[WifiPnoTest] Fix: Make Wi-Fi connection to the saved networks before PNO scan. am: 96381028c2 am: 897cfb6708 am: 9c334850e6
Original change: https://googleplex-android-review.googlesource.com/c/platform/tools/test/connectivity/+/17184490
Change-Id: I632f571cd56a3c565ab055e815ed8b309983a5eb
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7a4a3ea
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
\ No newline at end of file
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index a62e1f9..5260bc1 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,7 +1,7 @@
[Hook Scripts]
-yapf_hook = ./tools/yapf_checker.py
-proto_check = ./tools/proto_check.py
create_virtualenv = ./tools/create_virtualenv.sh
+yapf_hook = /tmp/acts_preupload_virtualenv/bin/python3 ./tools/yapf_checker.py
+proto_check = /tmp/acts_preupload_virtualenv/bin/python3 ./tools/proto_check.py
acts_unittests = /tmp/acts_preupload_virtualenv/bin/python3 ./acts_tests/tests/meta/ActsUnitTest.py
destroy_virtualenv = rm -rf /tmp/acts_preupload_virtualenv/
diff --git a/acts/framework/acts/config_parser.py b/acts/framework/acts/config_parser.py
index 549ebed..a639c38 100755
--- a/acts/framework/acts/config_parser.py
+++ b/acts/framework/acts/config_parser.py
@@ -207,7 +207,7 @@
tbs[name] = testbeds[name]
else:
raise ActsConfigError(
- 'Expected testbed named "%s", but none was found. Check'
+ 'Expected testbed named "%s", but none was found. Check '
'if you have the correct testbed names.' % name)
testbeds = tbs
diff --git a/acts/framework/acts/controllers/OWNERS b/acts/framework/acts/controllers/OWNERS
index 8155c96..ea76291 100644
--- a/acts/framework/acts/controllers/OWNERS
+++ b/acts/framework/acts/controllers/OWNERS
@@ -1,4 +1,5 @@
-per-file fuchsia_device.py = tturney@google.com, jmbrenna@google.com, haydennix@google.com
+per-file asus_axe11000_ap.py = martschneider@google.com
+per-file fuchsia_device.py = chcl@google.com, dhobsd@google.com, haydennix@google.com, jmbrenna@google.com, mnck@google.com, nickchee@google.com, sbalana@google.com, silberst@google.com, tturney@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
-per-file openwrt_ap.py = jerrypcchen@google.com, martschneider@google.com, gmoturu@google.com
+per-file openwrt_ap.py = jerrypcchen@google.com, martschneider@google.com, gmoturu@google.com, sishichen@google.com
diff --git a/acts/framework/acts/controllers/access_point.py b/acts/framework/acts/controllers/access_point.py
index 193a93d..abc31dd 100755
--- a/acts/framework/acts/controllers/access_point.py
+++ b/acts/framework/acts/controllers/access_point.py
@@ -128,6 +128,13 @@
additional_ap_parameters: Additional parameters to send the AP.
password: Password to connect to WLAN if necessary.
check_connectivity: Whether to check for internet connectivity.
+
+ Returns:
+ An identifier for each ssid being started. These identifiers can be
+ used later by this controller to control the ap.
+
+ Raises:
+ Error: When the ap can't be brought up.
"""
ap = hostapd_ap_preset.create_ap_preset(profile_name=profile_name,
iface_wlan_2g=access_point.wlan_2g,
@@ -148,9 +155,10 @@
n_capabilities=n_capabilities,
ac_capabilities=ac_capabilities,
vht_bandwidth=vht_bandwidth)
- access_point.start_ap(hostapd_config=ap,
- setup_bridge=setup_bridge,
- additional_parameters=additional_ap_parameters)
+ return access_point.start_ap(
+ hostapd_config=ap,
+ setup_bridge=setup_bridge,
+ additional_parameters=additional_ap_parameters)
class Error(Exception):
@@ -212,10 +220,14 @@
self._dhcp = None
self._dhcp_bss = dict()
self.bridge = bridge_interface.BridgeInterface(self)
- self.interfaces = ap_get_interface.ApInterfaces(self)
self.iwconfig = ap_iwconfig.ApIwconfig(self)
- # Get needed interface names and initialize the unneccessary ones.
+ # Check to see if wan_interface is specified in acts_config for tests
+ # isolated from the internet and set this override.
+ self.interfaces = ap_get_interface.ApInterfaces(
+ self, configs.get('wan_interface'))
+
+ # Get needed interface names and initialize the unnecessary ones.
self.wan = self.interfaces.get_wan_interface()
self.wlan = self.interfaces.get_wlan_interface()
self.wlan_2g = self.wlan[0]
@@ -323,6 +335,7 @@
# Clear all routes to prevent old routes from interfering.
self._route_cmd.clear_routes(net_interface=interface)
+ self._dhcp_bss = dict()
if hostapd_config.bss_lookup:
# The self._dhcp_bss dictionary is created to hold the key/value
# pair of the interface name and the ip scope that will be
@@ -332,7 +345,6 @@
# is requested. This part is designed to bring up the
# hostapd interfaces and not the DHCP servers for each
# interface.
- self._dhcp_bss = dict()
counter = 1
for bss in hostapd_config.bss_lookup:
if interface_mac_orig:
@@ -357,7 +369,7 @@
interface_ip = ipaddress.ip_interface(
'%s/%s' % (subnet.router, subnet.network.netmask))
if setup_bridge is True:
- bridge_interface_name = 'br_lan'
+ bridge_interface_name = 'eth_test'
self.create_bridge(bridge_interface_name, [interface, self.lan])
self._ip_cmd.set_ipv4_address(bridge_interface_name, interface_ip)
else:
@@ -374,12 +386,9 @@
self._ip_cmd.set_ipv4_address(str(k), bss_interface_ip)
# Restart the DHCP server with our updated list of subnets.
- configured_subnets = [x.subnet for x in self._aps.values()]
- if hostapd_config.bss_lookup:
- for k, v in self._dhcp_bss.items():
- configured_subnets.append(v)
-
- self.start_dhcp(subnets=configured_subnets)
+ configured_subnets = self.get_configured_subnets()
+ dhcp_conf = dhcp_config.DhcpConfig(subnets=configured_subnets)
+ self.start_dhcp(dhcp_conf=dhcp_conf)
self.start_nat()
bss_interfaces = [bss for bss in hostapd_config.bss_lookup]
@@ -387,22 +396,60 @@
return bss_interfaces
- def start_dhcp(self, subnets):
+ def get_configured_subnets(self):
+ """Get the list of configured subnets on the access point.
+
+ This allows consumers of the access point objects create custom DHCP
+ configs with the correct subnets.
+
+ Returns: a list of dhcp_config.Subnet objects
+ """
+ configured_subnets = [x.subnet for x in self._aps.values()]
+ for k, v in self._dhcp_bss.items():
+ configured_subnets.append(v)
+ return configured_subnets
+
+ def start_dhcp(self, dhcp_conf):
"""Start a DHCP server for the specified subnets.
This allows consumers of the access point objects to control DHCP.
Args:
- subnets: A list of Subnets.
+ dhcp_conf: A dhcp_config.DhcpConfig object.
+
+ Raises:
+ Error: Raised when a dhcp server error is found.
"""
- return self._dhcp.start(config=dhcp_config.DhcpConfig(subnets))
+ self._dhcp.start(config=dhcp_conf)
def stop_dhcp(self):
"""Stop DHCP for this AP object.
This allows consumers of the access point objects to control DHCP.
"""
- return self._dhcp.stop()
+ self._dhcp.stop()
+
+ def get_dhcp_logs(self):
+ """Get DHCP logs for this AP object.
+
+ This allows consumers of the access point objects to validate DHCP
+ behavior.
+ """
+ return self._dhcp.get_logs()
+
+ def get_hostapd_logs(self):
+ """Get hostapd logs for all interfaces on AP object.
+
+ This allows consumers of the access point objects to validate hostapd
+ behavior.
+
+ Returns: A dict with {interface: log} from hostapd instances.
+ """
+ hostapd_logs = dict()
+ for identifier in self._aps:
+ hostapd_logs[identifier] = self._aps.get(
+ identifier).hostapd.pull_logs()
+ return hostapd_logs
def start_nat(self):
"""Start NAT on the AP.
@@ -452,6 +499,9 @@
self.ssh.run('brctl addif {bridge_name} {interface}'.format(
bridge_name=bridge_name, interface=interface))
+ self.ssh.run(
+ 'ip link set {bridge_name} up'.format(bridge_name=bridge_name))
+
def remove_bridge(self, bridge_name):
"""Removes the specified bridge
@@ -793,3 +843,18 @@
self.start_ap(config,
setup_bridge=setup_bridge,
additional_parameters=additional_parameters)
+
+ def channel_switch(self, identifier, channel_num):
+ """Switch to a different channel on the given AP."""
+ if identifier not in list(self._aps.keys()):
+ raise ValueError('Invalid identifier %s given' % identifier)
+ instance = self._aps.get(identifier)
+ self.log.info('channel switch to channel {}'.format(channel_num))
+ instance.hostapd.channel_switch(channel_num)
+
+ def get_current_channel(self, identifier):
+ """Find the current channel on the given AP."""
+ if identifier not in list(self._aps.keys()):
+ raise ValueError('Invalid identifier %s given' % identifier)
+ instance = self._aps.get(identifier)
+ return instance.hostapd.get_current_channel()
diff --git a/acts/framework/acts/controllers/adb.py b/acts/framework/acts/controllers/adb.py
index 53e56af..854ed23 100644
--- a/acts/framework/acts/controllers/adb.py
+++ b/acts/framework/acts/controllers/adb.py
@@ -269,7 +269,7 @@
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:
+ if clean_name in ['pull', 'push', 'remount'] 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/amarisoft_lib/OWNERS b/acts/framework/acts/controllers/amarisoft_lib/OWNERS
new file mode 100644
index 0000000..edee4ef
--- /dev/null
+++ b/acts/framework/acts/controllers/amarisoft_lib/OWNERS
@@ -0,0 +1,4 @@
+markusliu@google.com
+mollychang@google.com
+angelayu@google.com
+zoeyliu@google.com
diff --git a/acts/framework/acts/controllers/amarisoft_lib/amarisoft_client.py b/acts/framework/acts/controllers/amarisoft_lib/amarisoft_client.py
new file mode 100644
index 0000000..bbfa174
--- /dev/null
+++ b/acts/framework/acts/controllers/amarisoft_lib/amarisoft_client.py
@@ -0,0 +1,221 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - Google
+#
+# 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 asyncio
+import json
+import logging
+from typing import Any, Mapping, Optional, Tuple
+
+from acts.controllers.amarisoft_lib import ssh_utils
+import immutabledict
+import websockets
+
+_CONFIG_DIR_MAPPING = immutabledict.immutabledict({
+ 'enb': '/config/enb.cfg',
+ 'mme': '/config/mme.cfg',
+ 'ims': '/config/ims.cfg',
+ 'mbms': '/config/mbmsgw.cfg',
+ 'ots': '/config/ots.cfg'
+})
+
+
+class MessageFailureError(Exception):
+ """Raises an error when the message execution fail."""
+
+
+class AmariSoftClient(ssh_utils.RemoteClient):
+ """The SSH client class interacts with Amarisoft.
+
+ A simulator used to simulate the base station can output different signals
+ according to the network configuration settings.
+ For example: T Mobile NSA LTE band 66 + NR band 71.
+ """
+
+ async def _send_message_to_callbox(self, uri: str,
+ msg: str) -> Tuple[str, str]:
+ """Implements async function for send message to the callbox.
+
+ Args:
+ uri: The uri of specific websocket interface.
+ msg: The message to be send to callbox.
+
+ Returns:
+ The response from callbox.
+ """
+ async with websockets.connect(
+ uri, extra_headers={'origin': 'Test'}) as websocket:
+ await websocket.send(msg)
+ head = await websocket.recv()
+ body = await websocket.recv()
+ return head, body
+
+ def send_message(self, port: str, msg: str) -> Tuple[str, str]:
+ """Sends a message to the callbox.
+
+ Args:
+ port: The port of specific websocket interface.
+ msg: The message to be send to callbox.
+
+ Returns:
+ The response from callbox.
+ """
+ return asyncio.get_event_loop().run_until_complete(
+ self._send_message_to_callbox(f'ws://{self.host}:{port}/', msg))
+
+ def verify_response(self, func: str, head: str,
+ body: str) -> Tuple[Mapping[str, Any], Mapping[str, Any]]:
+ """Makes sure there are no error messages in Amarisoft's response.
+
+ If a message produces an error, response will have an error string field
+ representing the error.
+ For example:
+ {
+ "message": "ready",
+ "message_id": <message id>,
+ "error": <error message>,
+ "type": "ENB",
+ "name: <name>,
+ }
+
+ Args:
+ func: The message send to Amarisoft.
+ head: Responsed message head.
+ body: Responsed message body.
+
+ Returns:
+ Standard output of the shell command.
+
+ Raises:
+ MessageFailureError: Raised when an error occurs in the response message.
+ """
+ loaded_head = json.loads(head)
+ loaded_body = json.loads(body)
+
+ if loaded_head.get('message') != 'ready':
+ raise MessageFailureError(
+ f'Fail to get response from callbox, message: {loaded_head["error"]}')
+ if 'error' in loaded_body:
+ raise MessageFailureError(
+ f'Fail to excute {func} with error message: {loaded_body["error"]}')
+ if loaded_body.get('message') != func:
+ raise MessageFailureError(
+ f'The message sent was {loaded_body["message"]} instead of {func}.')
+ return loaded_head, loaded_body
+
+ def lte_service_stop(self) -> None:
+ """Stops to output signal."""
+ self.run_cmd('systemctl stop lte')
+
+ def lte_service_start(self):
+ """Starts to output signal."""
+ self.run_cmd('systemctl start lte')
+
+ def lte_service_restart(self):
+ """Restarts to output signal."""
+ self.run_cmd('systemctl restart lte')
+
+ def lte_service_enable(self):
+ """lte service remains enable until next reboot."""
+ self.run_cmd('systemctl enable lte')
+
+ def lte_service_disable(self):
+ """lte service remains disable until next reboot."""
+ self.run_cmd('systemctl disable lte')
+
+ def lte_service_is_active(self) -> bool:
+ """Checks lte service is active or not.
+
+ Returns:
+ True if service active, False otherwise.
+ """
+ return not any('inactive' in line
+ for line in self.run_cmd('systemctl is-active lte'))
+
+ def set_config_dir(self, cfg_type: str, path: str) -> None:
+ """Sets the path of target configuration file.
+
+ Args:
+ cfg_type: The type of target configuration. (e.g. mme, enb ...etc.)
+ path: The path of target configuration. (e.g.
+ /root/lteenb-linux-2020-12-14)
+ """
+ path_old = self.get_config_dir(cfg_type)
+ if path != path_old:
+ logging.info('set new path %s (was %s)', path, path_old)
+ self.run_cmd(f'ln -sfn {path} /root/{cfg_type}')
+ else:
+ logging.info('path %s does not change.', path_old)
+
+ def get_config_dir(self, cfg_type: str) -> Optional[str]:
+ """Gets the path of target configuration.
+
+ Args:
+ cfg_type: Target configuration type. (e.g. mme, enb...etc.)
+
+ Returns:
+ The path of configuration.
+ """
+ result = self.run_cmd(f'readlink /root/{cfg_type}')
+ if result:
+ path = result[0].strip()
+ else:
+ logging.warning('%s path not found.', cfg_type)
+ return None
+ return path
+
+ def set_config_file(self, cfg_type: str, cfg_file: str) -> None:
+ """Sets the configuration to be executed.
+
+ Args:
+ cfg_type: The type of target configuration. (e.g. mme, enb...etc.)
+ cfg_file: The configuration to be executed. (e.g.
+ /root/lteenb-linux-2020-12-14/config/gnb.cfg )
+
+ Raises:
+ FileNotFoundError: Raised when a file or directory is requested but
+ doesn’t exist.
+ """
+ cfg_link = self.get_config_dir(cfg_type) + _CONFIG_DIR_MAPPING[cfg_type]
+ if not self.is_file_exist(cfg_file):
+ raise FileNotFoundError("The command file doesn't exist")
+ self.run_cmd(f'ln -sfn {cfg_file} {cfg_link}')
+
+ def get_config_file(self, cfg_type: str) -> Optional[str]:
+ """Gets the current configuration of specific configuration type.
+
+ Args:
+ cfg_type: The type of target configuration. (e.g. mme, enb...etc.)
+
+ Returns:
+ The current configuration with absolute path.
+ """
+ cfg_path = self.get_config_dir(cfg_type) + _CONFIG_DIR_MAPPING[cfg_type]
+ if cfg_path:
+ result = self.run_cmd(f'readlink {cfg_path}')
+ if result:
+ return result[0].strip()
+
+ def get_all_config_dir(self) -> Mapping[str, str]:
+ """Gets all configuration directions.
+
+ Returns:
+ All configuration directions.
+ """
+ config_dir = {}
+ for cfg_type in ('ots', 'enb', 'mme', 'mbms'):
+ config_dir[cfg_type] = self.get_config_dir(cfg_type)
+ logging.debug('get path of %s: %s', cfg_type, config_dir[cfg_type])
+ return config_dir
diff --git a/acts/framework/acts/controllers/amarisoft_lib/amarisoft_constants.py b/acts/framework/acts/controllers/amarisoft_lib/amarisoft_constants.py
new file mode 100644
index 0000000..c62bf2a
--- /dev/null
+++ b/acts/framework/acts/controllers/amarisoft_lib/amarisoft_constants.py
@@ -0,0 +1,14 @@
+"""Constants for test."""
+
+
+# ports of lte service websocket interface
+class PortNumber:
+ URI_MME = '9000'
+ URI_ENB = '9001'
+ URI_UE = '9002'
+ URI_IMS = '9003'
+ URI_MBMS = '9004'
+ URI_PROBE = '9005'
+ URI_LICENSE = '9006'
+ URI_MON = '9007'
+ URI_VIEW = '9008'
diff --git a/acts/framework/acts/controllers/amarisoft_lib/config_utils.py b/acts/framework/acts/controllers/amarisoft_lib/config_utils.py
new file mode 100644
index 0000000..3dad7a3
--- /dev/null
+++ b/acts/framework/acts/controllers/amarisoft_lib/config_utils.py
@@ -0,0 +1,201 @@
+!/usr/bin/env python3
+#
+# Copyright 2022 - Google
+#
+# 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 enum
+import os
+import immutabledict
+
+from acts.controllers.amarisoft_lib import amarisoft_client
+
+TEMPLATE_PATH = os.path.dirname(os.path.abspath(__file__)) + '/config_templates'
+TEMPLATE_PATH_ENB = f'{TEMPLATE_PATH}/enb/'
+TEMPLATE_PATH_MME = f'{TEMPLATE_PATH}/mme/'
+
+_CLIENT_CONFIG_DIR_MAPPING = immutabledict.immutabledict({
+ 'enb': '/config/mhtest_enb.cfg',
+ 'mme': '/config/mhtest_mme.cfg',
+})
+
+
+class EnbCfg():
+ """MME configuration templates."""
+ ENB_GENERIC = 'enb-single-generic.cfg'
+ GNB_NSA_GENERIC = 'gnb-nsa-lte-ho-generic.cfg'
+ GNB_SA_GENERIC = 'gnb-sa-lte-ho-generic.cfg'
+
+
+class MmeCfg():
+ """MME configuration templates."""
+ MME_GENERIC = 'mme-generic.cfg'
+
+
+class SpecTech(enum.Enum):
+ """Spectrum usage techniques."""
+ FDD = 0
+ TDD = 1
+
+
+class ConfigUtils():
+ """Utilities for set Amarisoft configs.
+
+ Attributes:
+ remote: An amarisoft client.
+ """
+
+ def __init__(self, remote: amarisoft_client.AmariSoftClient):
+ self.remote = remote
+
+ def upload_enb_template(self, cfg: str) -> bool:
+ """Loads ENB configuration.
+
+ Args:
+ cfg: The ENB configuration to be loaded.
+
+ Returns:
+ True if the ENB configuration was loaded successfully, False otherwise.
+ """
+ cfg_template = TEMPLATE_PATH_ENB + cfg
+ if not os.path.isfile(cfg_template):
+ return False
+ cfg_path = self.remote.get_config_dir(
+ 'enb') + _CLIENT_CONFIG_DIR_MAPPING['enb']
+ self.remote.run_cmd('rm -f ' + cfg_path)
+ self.remote.sftp_upload(cfg_template, cfg_path)
+ self.remote.set_config_file('enb', cfg_path)
+ if not self.remote.is_file_exist(cfg_path):
+ return False
+ return True
+
+ def upload_mme_template(self, cfg: str) -> bool:
+ """Loads MME configuration.
+
+ Args:
+ cfg: The MME configuration to be loaded.
+
+ Returns:
+ True if the ENB configuration was loaded successfully, False otherwise.
+ """
+ cfg_template = TEMPLATE_PATH_MME + cfg
+ if not os.path.isfile(cfg_template):
+ return False
+ cfg_path = self.remote.get_config_dir(
+ 'mme') + _CLIENT_CONFIG_DIR_MAPPING['mme']
+ self.remote.run_cmd('rm -f ' + cfg_path)
+ self.remote.sftp_upload(cfg_template, cfg_path)
+ self.remote.set_config_file('mme', cfg_path)
+ if not self.remote.is_file_exist(cfg_path):
+ return False
+ return True
+
+ def enb_set_plmn(self, plmn: str) -> bool:
+ """Sets the PLMN in ENB configuration.
+
+ Args:
+ plmn: The PLMN to be set. ex: 311480
+
+ Returns:
+ True if set PLMN successfully, False otherwise.
+ """
+ cfg_path = self.remote.get_config_dir(
+ 'enb') + _CLIENT_CONFIG_DIR_MAPPING['enb']
+ if not self.remote.is_file_exist(cfg_path):
+ return False
+ string_from = '#define PLMN \"00101\"'
+ string_to = f'#define PLMN \"{plmn}\"'
+ self.remote.run_cmd(f'sed -i \'s/\\r//g\' {cfg_path}')
+ self.remote.run_cmd(
+ f'sed -i \':a;N;$!ba;s/{string_from}/{string_to}/g\' {cfg_path}')
+ return True
+
+ def mme_set_plmn(self, plmn: str) -> bool:
+ """Sets the PLMN in MME configuration.
+
+ Args:
+ plmn: The PLMN to be set. ex:'311480'
+
+ Returns:
+ True if set PLMN successfully, False otherwise.
+ """
+ cfg_path = self.remote.get_config_dir(
+ 'mme') + _CLIENT_CONFIG_DIR_MAPPING['mme']
+ if not self.remote.is_file_exist(cfg_path):
+ return False
+ string_from = '#define PLMN \"00101\"'
+ string_to = f'#define PLMN \"{plmn}\"'
+ self.remote.run_cmd(f'sed -i \'s/\\r//g\' {cfg_path}')
+ self.remote.run_cmd(
+ f'sed -i \':a;N;$!ba;s/{string_from}/{string_to}/g\' {cfg_path}')
+ return True
+
+ def enb_set_fdd_arfcn(self, arfcn: int) -> bool:
+ """Sets the FDD ARFCN in ENB configuration.
+
+ Args:
+ arfcn: The arfcn to be set. ex: 1400
+
+ Returns:
+ True if set FDD ARFCN successfully, False otherwise.
+ """
+ cfg_path = self.remote.get_config_dir(
+ 'enb') + _CLIENT_CONFIG_DIR_MAPPING['enb']
+ if not self.remote.is_file_exist(cfg_path):
+ return False
+ string_from = '#define FDD_CELL_earfcn 1400'
+ string_to = f'#define FDD_CELL_earfcn {arfcn}'
+ self.remote.run_cmd(f'sed -i \'s/\\r//g\' {cfg_path}')
+ self.remote.run_cmd(
+ f'sed -i \':a;N;$!ba;s/{string_from}/{string_to}/g\' {cfg_path}')
+ return True
+
+ def enb_set_tdd_arfcn(self, arfcn: int) -> bool:
+ """Sets the TDD ARFCN in ENB configuration.
+
+ Args:
+ arfcn: The arfcn to be set. ex: 1400
+
+ Returns:
+ True if set FDD ARFCN successfully, False otherwise.
+ """
+ cfg_path = self.remote.get_config_dir(
+ 'enb') + _CLIENT_CONFIG_DIR_MAPPING['enb']
+ if not self.remote.is_file_exist(cfg_path):
+ return False
+ string_from = '#define TDD_CELL_earfcn 40620'
+ string_to = f'#define TDD_CELL_earfcn {arfcn}'
+ self.remote.run_cmd(f'sed -i \'s/\\r//g\' {cfg_path}')
+ self.remote.run_cmd(
+ f'sed -i \':a;N;$!ba;s/{string_from}/{string_to}/g\' {cfg_path}')
+ return True
+
+ def enb_set_spectrum_tech(self, tech: int) -> bool:
+ """Sets the spectrum usage techniques in ENB configuration.
+
+ Args:
+ tech: the spectrum usage techniques. ex: SpecTech.FDD.name
+
+ Returns:
+ True if set spectrum usage techniques successfully, False otherwise.
+ """
+ cfg_path = self.remote.get_config_dir(
+ 'enb') + _CLIENT_CONFIG_DIR_MAPPING['enb']
+ if not self.remote.is_file_exist(cfg_path):
+ return False
+ string_from = '#define TDD 0'
+ string_to = f'#define TDD {tech}'
+ self.remote.run_cmd(f'sed -i \'s/\\r//g\' {cfg_path}')
+ self.remote.run_cmd(
+ f'sed -i \':a;N;$!ba;s/{string_from}/{string_to}/g\' {cfg_path}')
+ return True
diff --git a/acts/framework/acts/controllers/amarisoft_lib/ims.py b/acts/framework/acts/controllers/amarisoft_lib/ims.py
new file mode 100644
index 0000000..9289ba0
--- /dev/null
+++ b/acts/framework/acts/controllers/amarisoft_lib/ims.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - Google
+#
+# 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 logging
+from typing import Any, Mapping, Optional, Union
+
+from acts.controllers.amarisoft_lib import amarisoft_client
+from acts.controllers.amarisoft_lib import amarisoft_constants as const
+
+
+class ImsFunctions():
+ """Utilities for Amarisoft's IMS Remote API.
+
+ Attributes:
+ remote: An amarisoft client.
+ """
+
+ def __init__(self, remote: amarisoft_client.AmariSoftClient):
+ self.remote = remote
+
+ def make_call(self,
+ impi: str,
+ impu: str,
+ contact: str,
+ sip_file: str = 'mt_call_qos.sdp',
+ caller: str = 'Amarisoft',
+ duration: int = 30) -> None:
+ """Performs MT call from callbox to test device.
+
+ Args:
+ impi: IMPI (IP Multimedia Private identity) of user to call.
+ impu: IMPU (IP Multimedia Public identity) of user to call.
+ contact: Contact SIP uri of user to call.
+ sip_file: Define file to use as sdp.
+ caller: The number/ID is displayed as the caller.
+ duration: If set, call duration in seconds (The server will close the
+ dialog).
+ """
+ msg = {}
+ msg['message'] = 'mt_call'
+ msg['impi'] = impi
+ msg['impu'] = impu
+ msg['contact'] = contact
+ msg['sip_file'] = sip_file
+ msg['caller'] = caller
+ msg['duration'] = duration
+ dump_msg = json.dumps(msg)
+ logging.debug('mt_call dump msg = %s', dump_msg)
+ head, body = self.remote.send_message(const.PortNumber.URI_IMS, dump_msg)
+ self.remote.verify_response('mt_call', head, body)
+
+ def send_sms(self,
+ text: str,
+ impi: str,
+ sender: Optional[str] = 'Amarisoft') -> None:
+ """Sends SMS to assigned device which connect to Amarisoft.
+
+ Args:
+ text: SMS text to send.
+ impi: IMPI (IP Multimedia Private identity) of user.
+ sender: Sets SMS sender.
+ """
+ msg = {}
+ msg['message'] = 'sms'
+ msg['text'] = text
+ msg['impi'] = impi
+ msg['sender'] = sender
+ dump_msg = json.dumps(msg)
+ logging.debug('send_sms dump msg = %s', dump_msg)
+ head, body = self.remote.send_message(const.PortNumber.URI_IMS, dump_msg)
+ self.remote.verify_response('sms', head, body)
+
+ def send_mms(self, filename: str, sender: str, receiver: str) -> None:
+ """Sends MMS to assigned device which connect to Amarisoft.
+
+ Args:
+ filename: File name with absolute path to send. Extensions jpg, jpeg, png,
+ gif and txt are supported.
+ sender: IMPI (IP Multimedia Private identity) of user.
+ receiver: IMPU (IP Multimedia Public identity) of user.
+ """
+ msg = {}
+ msg['message'] = 'mms'
+ msg['filename'] = filename
+ msg['sender'] = sender
+ msg['receiver'] = receiver
+ dump_msg = json.dumps(msg)
+ logging.debug('send_mms dump msg = %s', dump_msg)
+ head, body = self.remote.send_message(const.PortNumber.URI_IMS, dump_msg)
+ self.remote.verify_response('mms', head, body)
+
+ def users_get(self, registered_only: bool = True) -> Mapping[str, Any]:
+ """Gets users state.
+
+ Args:
+ registered_only: If set, only registered user will be dumped.
+
+ Returns:
+ The user information.
+ """
+ msg = {}
+ msg['message'] = 'users_get'
+ msg['registered_only'] = registered_only
+ dump_msg = json.dumps(msg)
+ logging.debug('users_get dump msg = %s', dump_msg)
+ head, body = self.remote.send_message(const.PortNumber.URI_IMS, dump_msg)
+ _, loaded_body = self.remote.verify_response('users_get', head, body)
+ return loaded_body
+
+ def get_impu(self, impi) -> Union[str, None]:
+ """Obtains the IMPU of the target user according to IMPI.
+
+ Args:
+ impi: IMPI (IP Multimedia Private identity) of user to call. ex:
+ "310260123456785@ims.mnc260.mcc310.3gppnetwork.org"
+
+ Returns:
+ The IMPU of target user.
+ """
+ body = self.users_get(True)
+ for index in range(len(body['users'])):
+ if impi in body['users'][index]['impi']:
+ impu = body['users'][index]['bindings'][0]['impu'][1]
+ return impu
+ return None
+
+ def get_uri(self, impi) -> Union[str, None]:
+ """Obtains the URI of the target user according to IMPI.
+
+ Args:
+ impi: IMPI (IP Multimedia Private identity) of user to call. ex:
+ "310260123456785@ims.mnc260.mcc310.3gppnetwork.org"
+
+ Returns:
+ The URI of target user.
+ """
+ body = self.users_get(True)
+ for index in range(len(body['users'])):
+ if impi in body['users'][index]['impi']:
+ uri = body['users'][index]['bindings'][0]['uri']
+ return uri
+ return None
diff --git a/acts/framework/acts/controllers/amarisoft_lib/mme.py b/acts/framework/acts/controllers/amarisoft_lib/mme.py
new file mode 100644
index 0000000..58a6d4f
--- /dev/null
+++ b/acts/framework/acts/controllers/amarisoft_lib/mme.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - Google
+#
+# 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 logging
+
+from acts.controllers.amarisoft_lib import amarisoft_constants as const
+from acts.controllers.amarisoft_lib import amarisoft_client
+
+
+class MmeFunctions():
+ """Utilities for Amarisoft's MME Remote API.
+
+ Attributes:
+ remote: An amarisoft client.
+ """
+
+ def __init__(self, remote: amarisoft_client.AmariSoftClient):
+ self.remote = remote
+
+ def pws_write(self, local_id: str, n50: bool = False):
+ """Broadcasts emergency alert message.
+
+ Args:
+ local_id: ID of the message as defined by local identifier in MME
+ configuration file.
+ n50: If True, N50 interface is used, otherwise SBC interface is used. (see TS 23.041)
+ """
+ msg = {}
+ msg['message'] = 'pws_write'
+ msg['local_id'] = local_id
+ msg['nf'] = n50
+ dump_msg = json.dumps(msg)
+ logging.debug('pws_write dump msg = %s', dump_msg)
+ head, body = self.remote.send_message(const.PortNumber.URI_MME, dump_msg)
+ self.remote.verify_response('pws_write', head, body)
+
+ def pws_kill(self, local_id: str, n50: bool = False):
+ """Stops broadcasts emergency alert message.
+
+ Args:
+ local_id: ID of the message as defined by local identifier in MME
+ configuration file.
+ n50: If True, N50 interface is used, otherwise SBC interface is used. (see TS 23.041)
+ """
+ msg = {}
+ msg['message'] = 'pws_kill'
+ msg['local_id'] = local_id
+ msg['nf'] = n50
+ dump_msg = json.dumps(msg)
+ logging.debug('pws_kill dump msg = %s', dump_msg)
+ head, body = self.remote.send_message(const.PortNumber.URI_MME, dump_msg)
+ self.remote.verify_response('pws_kill', head, body)
+
+ def ue_del(self, imsi: str):
+ """Remove UE from the UE database and force disconnect if necessary.
+
+ Args:
+ imsi: IMSI of the UE to delete.
+ """
+ msg = {}
+ msg['message'] = 'ue_del'
+ msg['imsi'] = imsi
+ dump_msg = json.dumps(msg)
+ logging.debug('ue_del dump msg = %s', dump_msg)
+ head, body = self.remote.send_message(const.PortNumber.URI_MME, dump_msg)
+ self.remote.verify_response('ue_del', head, body)
diff --git a/acts/framework/acts/controllers/amarisoft_lib/ssh_utils.py b/acts/framework/acts/controllers/amarisoft_lib/ssh_utils.py
new file mode 100644
index 0000000..a1673a5
--- /dev/null
+++ b/acts/framework/acts/controllers/amarisoft_lib/ssh_utils.py
@@ -0,0 +1,195 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - Google
+#
+# 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 typing import Sequence
+
+import paramiko
+
+COMMAND_RETRY_TIMES = 3
+
+
+class RunCommandError(Exception):
+ """Raises an error when run command fail."""
+
+
+class NotConnectedError(Exception):
+ """Raises an error when run command without SSH connect."""
+
+
+class RemoteClient:
+ """The SSH client class interacts with the test machine.
+
+ Attributes:
+ host: A string representing the IP address of amarisoft.
+ port: A string representing the default port of SSH.
+ username: A string representing the username of amarisoft.
+ password: A string representing the password of amarisoft.
+ ssh: A SSH client.
+ sftp: A SFTP client.
+ """
+
+ def __init__(self,
+ host: str,
+ username: str,
+ password: str,
+ port: str = '22') -> None:
+ self.host = host
+ self.port = port
+ self.username = username
+ self.password = password
+ self.ssh = paramiko.SSHClient()
+ self.sftp = None
+
+ def ssh_is_connected(self) -> bool:
+ """Checks SSH connect or not.
+
+ Returns:
+ True if SSH is connected, False otherwise.
+ """
+ return self.ssh and self.ssh.get_transport().is_active()
+
+ def ssh_close(self) -> bool:
+ """Closes the SSH connection.
+
+ Returns:
+ True if ssh session closed, False otherwise.
+ """
+ for _ in range(COMMAND_RETRY_TIMES):
+ if self.ssh_is_connected():
+ self.ssh.close()
+ else:
+ return True
+ return False
+
+ def connect(self) -> bool:
+ """Creats SSH connection.
+
+ Returns:
+ True if success, False otherwise.
+ """
+ for _ in range(COMMAND_RETRY_TIMES):
+ try:
+ self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+ self.ssh.connect(self.host, self.port, self.username, self.password)
+ self.ssh.get_transport().set_keepalive(1)
+ self.sftp = paramiko.SFTPClient.from_transport(self.ssh.get_transport())
+ return True
+ except Exception: # pylint: disable=broad-except
+ self.ssh_close()
+ return False
+
+ def run_cmd(self, cmd: str) -> Sequence[str]:
+ """Runs shell command.
+
+ Args:
+ cmd: Command to be executed.
+
+ Returns:
+ Standard output of the shell command.
+
+ Raises:
+ RunCommandError: Raise error when command failed.
+ NotConnectedError: Raised when run command without SSH connect.
+ """
+ if not self.ssh_is_connected():
+ raise NotConnectedError('ssh remote has not been established')
+
+ logging.debug('ssh remote -> %s', cmd)
+ _, stdout, stderr = self.ssh.exec_command(cmd)
+ err = stderr.readlines()
+ if err:
+ logging.error('command failed.')
+ raise RunCommandError(err)
+ return stdout.readlines()
+
+ def is_file_exist(self, file: str) -> bool:
+ """Checks target file exist.
+
+ Args:
+ file: Target file with absolute path.
+
+ Returns:
+ True if file exist, false otherwise.
+ """
+ return any('exist' in line for line in self.run_cmd(
+ f'if [ -f "{file}" ]; then echo -e "exist"; fi'))
+
+ def sftp_upload(self, src: str, dst: str) -> bool:
+ """Uploads a local file to remote side.
+
+ Args:
+ src: The target file with absolute path.
+ dst: The absolute path to put the file with file name.
+ For example:
+ upload('/usr/local/google/home/zoeyliu/Desktop/sample_config.yml',
+ '/root/sample_config.yml')
+
+ Returns:
+ True if file upload success, False otherwise.
+
+ Raises:
+ NotConnectedError: Raised when run command without SSH connect.
+ """
+ if not self.ssh_is_connected():
+ raise NotConnectedError('ssh remote has not been established')
+ if not self.sftp:
+ raise NotConnectedError('sftp remote has not been established')
+
+ logging.info('[local] %s -> [remote] %s', src, dst)
+ self.sftp.put(src, dst)
+ return self.is_file_exist(dst)
+
+ def sftp_download(self, src: str, dst: str) -> bool:
+ """Downloads a file to local.
+
+ Args:
+ src: The target file with absolute path.
+ dst: The absolute path to put the file.
+
+ Returns:
+ True if file download success, False otherwise.
+
+ Raises:
+ NotConnectedError: Raised when run command without SSH connect.
+ """
+ if not self.ssh_is_connected():
+ raise NotConnectedError('ssh remote has not been established')
+ if not self.sftp:
+ raise NotConnectedError('sftp remote has not been established')
+
+ logging.info('[remote] %s -> [local] %s', src, dst)
+ self.sftp.get(src, dst)
+ return self.is_file_exist(dst)
+
+ def sftp_list_dir(self, path: str) -> Sequence[str]:
+ """Lists the names of the entries in the given path.
+
+ Args:
+ path: The path of the list.
+
+ Returns:
+ The names of the entries in the given path.
+
+ Raises:
+ NotConnectedError: Raised when run command without SSH connect.
+ """
+ if not self.ssh_is_connected():
+ raise NotConnectedError('ssh remote has not been established')
+ if not self.sftp:
+ raise NotConnectedError('sftp remote has not been established')
+ return sorted(self.sftp.listdir(path))
+
diff --git a/acts/framework/acts/controllers/android_device.py b/acts/framework/acts/controllers/android_device.py
index 3a35bf3..793cb23 100755
--- a/acts/framework/acts/controllers/android_device.py
+++ b/acts/framework/acts/controllers/android_device.py
@@ -19,6 +19,7 @@
import math
import os
import re
+import shutil
import socket
import time
from builtins import open
@@ -60,8 +61,10 @@
"/data/vendor/ramdump/bluetooth", "/data/vendor/log/cbd")
CRASH_REPORT_SKIPS = ("RAMDUMP_RESERVED", "RAMDUMP_STATUS", "RAMDUMP_OUTPUT",
"bluetooth")
+ALWAYS_ON_LOG_PATH = "/data/vendor/radio/logs/always-on"
DEFAULT_QXDM_LOG_PATH = "/data/vendor/radio/diag_logs"
DEFAULT_SDM_LOG_PATH = "/data/vendor/slog/"
+DEFAULT_SCREENSHOT_PATH = "/sdcard/Pictures/screencap"
BUG_REPORT_TIMEOUT = 1800
PULL_TIMEOUT = 300
PORT_RETRY_COUNT = 3
@@ -428,7 +431,7 @@
self.skip_sl4a = False
self.crash_report = None
self.data_accounting = collections.defaultdict(int)
- self._sl4a_manager = sl4a_manager.Sl4aManager(self.adb)
+ self._sl4a_manager = sl4a_manager.create_sl4a_manager(self.adb)
self.last_logcat_timestamp = None
# Device info cache.
self._user_added_device_info = {}
@@ -445,6 +448,34 @@
if self._ssh_connection:
self._ssh_connection.close()
+ def recreate_services(self, serial):
+ """Clean up the AndroidDevice object and re-create adb/sl4a services.
+
+ Unregister the existing services and re-create adb and sl4a services,
+ call this method when the connection break after certain API call
+ (e.g., enable USB tethering by #startTethering)
+
+ Args:
+ serial: the serial number of the AndroidDevice
+ """
+ # Clean the old services
+ for service in self._services:
+ service.unregister()
+ self._services.clear()
+ if self._ssh_connection:
+ self._ssh_connection.close()
+ self._sl4a_manager.stop_service()
+
+ # Wait for old services to stop
+ time.sleep(5)
+
+ # Re-create the new adb and sl4a services
+ self.register_service(services.AdbLogcatService(self))
+ self.register_service(services.Sl4aService(self))
+ self.adb.wait_for_device()
+ self.terminate_all_sessions()
+ self.start_services()
+
def register_service(self, service):
"""Registers the service on the device. """
service.register()
@@ -734,11 +765,11 @@
except (IndexError, ValueError) as e:
# Possible ValueError from string to int cast.
# Possible IndexError from split.
- self.log.warn(
+ self.log.warning(
'Command \"%s\" returned output line: '
'\"%s\".\nError: %s', cmd, out, e)
except Exception as e:
- self.log.warn(
+ self.log.warning(
'Device fails to check if %s running with \"%s\"\n'
'Exception %s', package_name, cmd, e)
self.log.debug("apk %s is not running", package_name)
@@ -900,7 +931,7 @@
save the logcat in a file.
"""
if self.is_adb_logcat_on:
- self.log.warn(
+ self.log.warning(
'Android device %s already has a running adb logcat thread. ' %
self.serial)
return
@@ -921,7 +952,7 @@
"""Stops the adb logcat collection subprocess.
"""
if not self.is_adb_logcat_on:
- self.log.warn(
+ self.log.warning(
'Android device %s does not have an ongoing adb logcat ' %
self.serial)
return
@@ -948,6 +979,29 @@
else:
None
+ @record_api_usage
+ def get_apk_version(self, package_name):
+ """Get the version of the given apk.
+
+ Args:
+ package_name: Name of the package, e.g., com.android.phone.
+
+ Returns:
+ Version of the given apk.
+ """
+ try:
+ output = self.adb.shell("dumpsys package %s | grep versionName" %
+ package_name)
+ pattern = re.compile(r"versionName=(.+)", re.I)
+ result = pattern.findall(output)
+ if result:
+ return result[0]
+ except Exception as e:
+ self.log.warning("Fail to get the version of package %s: %s",
+ package_name, e)
+ self.log.debug("apk %s is not found", package_name)
+ return None
+
def is_apk_installed(self, package_name):
"""Check if the given apk is already installed.
@@ -990,7 +1044,7 @@
self.log.info("apk %s is running", package_name)
return True
except Exception as e:
- self.log.warn(
+ self.log.warning(
"Device fails to check is %s running by %s "
"Exception %s", package_name, cmd, e)
continue
@@ -1013,14 +1067,7 @@
self.adb.shell('am force-stop %s' % package_name,
ignore_status=True)
except Exception as e:
- self.log.warn("Fail to stop package %s: %s", package_name, e)
-
- def stop_sl4a(self):
- # TODO(markdr): Move this into sl4a_manager.
- return self.force_stop_apk(SL4A_APK_NAME)
-
- def start_sl4a(self):
- self._sl4a_manager.start_sl4a_service()
+ self.log.warning("Fail to stop package %s: %s", package_name, e)
def take_bug_report(self, test_name, begin_time):
"""Takes a bug report on the device and stores it in a file.
@@ -1172,11 +1219,16 @@
qxdm_log_path = os.path.join(self.device_log_path,
"QXDM_%s" % self.serial)
os.makedirs(qxdm_log_path, exist_ok=True)
+
self.log.info("Pull QXDM Log %s to %s", qxdm_logs, qxdm_log_path)
self.pull_files(qxdm_logs, qxdm_log_path)
+
self.adb.pull("/firmware/image/qdsp6m.qdb %s" % qxdm_log_path,
timeout=PULL_TIMEOUT,
ignore_status=True)
+ # Zip Folder
+ utils.zip_directory('%s.zip' % qxdm_log_path, qxdm_log_path)
+ shutil.rmtree(qxdm_log_path)
else:
self.log.error("Didn't find QXDM logs in %s." % log_path)
if "Verizon" in self.adb.getprop("gsm.sim.operator.alpha"):
@@ -1194,10 +1246,15 @@
"""Get sdm logs."""
# Sleep 10 seconds for the buffered log to be written in sdm log file
time.sleep(10)
- log_path = getattr(self, "sdm_log_path", DEFAULT_SDM_LOG_PATH)
- sdm_logs = self.get_file_names(log_path,
- begin_time=begin_time,
- match_string="*.sdm*")
+ log_paths = [
+ ALWAYS_ON_LOG_PATH,
+ getattr(self, "sdm_log_path", DEFAULT_SDM_LOG_PATH)
+ ]
+ sdm_logs = []
+ for path in log_paths:
+ sdm_logs += self.get_file_names(path,
+ begin_time=begin_time,
+ match_string="*.sdm*")
if sdm_logs:
sdm_log_path = os.path.join(self.device_log_path,
"SDM_%s" % self.serial)
@@ -1457,10 +1514,9 @@
def get_my_current_focus_window(self):
"""Get the current focus window on screen"""
output = self.adb.shell(
- 'dumpsys window displays | grep -E mCurrentFocus',
+ 'dumpsys window displays | grep -E mCurrentFocus | grep -v null',
ignore_status=True)
- if not output or "not found" in output or "Can't find" in output or (
- "mCurrentFocus=null" in output):
+ if not output or "not found" in output or "Can't find" in output:
result = ''
else:
result = output.split(' ')[-1].strip("}")
@@ -1534,16 +1590,9 @@
@record_api_usage
def is_screen_lock_enabled(self):
"""Check if screen lock is enabled"""
- cmd = ("sqlite3 /data/system/locksettings.db .dump"
- " | grep lockscreen.password_type | grep -v alternate")
+ cmd = ("dumpsys window policy | grep showing=")
out = self.adb.shell(cmd, ignore_status=True)
- if "unable to open" in out:
- self.root_adb()
- out = self.adb.shell(cmd, ignore_status=True)
- if ",0,'0'" not in out and out != "":
- self.log.info("Screen lock is enabled")
- return True
- return False
+ return "true" in out
@record_api_usage
def is_waiting_for_unlock_pin(self):
@@ -1609,6 +1658,23 @@
self.send_keycode("BACK")
@record_api_usage
+ def screenshot(self, name=""):
+ """Take a screenshot on the device.
+
+ Args:
+ name: additional information of screenshot on the file name.
+ """
+ if name:
+ file_name = "%s_%s" % (DEFAULT_SCREENSHOT_PATH, name)
+ file_name = "%s_%s.png" % (file_name, utils.get_current_epoch_time())
+ self.ensure_screen_on()
+ self.log.info("Log screenshot to %s", file_name)
+ try:
+ self.adb.shell("screencap -p %s" % file_name)
+ except:
+ self.log.error("Fail to log screenshot to %s", file_name)
+
+ @record_api_usage
def exit_setup_wizard(self):
# Handling Android TV's setupwizard is ignored for now.
if 'feature:android.hardware.type.television' in self.adb.shell(
diff --git a/acts/framework/acts/controllers/android_lib/services.py b/acts/framework/acts/controllers/android_lib/services.py
index f4ff20b..42998f7 100644
--- a/acts/framework/acts/controllers/android_lib/services.py
+++ b/acts/framework/acts/controllers/android_lib/services.py
@@ -108,4 +108,3 @@
def _stop(self, _):
self.ad.terminate_all_sessions()
self.ad._sl4a_manager.stop_service()
- self.ad.stop_sl4a()
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 eea1c8a..a1b15db 100644
--- a/acts/framework/acts/controllers/anritsu_lib/md8475_cellular_simulator.py
+++ b/acts/framework/acts/controllers/anritsu_lib/md8475_cellular_simulator.py
@@ -86,41 +86,15 @@
self.anritsu.load_simulation_paramfile(sim_file_path)
self.anritsu.load_cell_paramfile(cell_file_path)
- self.anritsu.start_simulation()
- self.bts = [self.anritsu.get_BTS(md8475a.BtsNumber.BTS1)]
-
- self.num_carriers = 1
-
- def setup_lte_ca_scenario(self):
- """ Configures the equipment for an LTE with CA simulation. """
- cell_file_name = self.LTE_CA_BASIC_CELL_FILE
- sim_file_name = self.LTE_CA_BASIC_SIM_FILE
-
- cell_file_path = ntpath.join(self.CALLBOX_CONFIG_PATH, cell_file_name)
- sim_file_path = ntpath.join(self.CALLBOX_CONFIG_PATH, sim_file_name)
-
- # Load the simulation config file
- self.anritsu.load_simulation_paramfile(sim_file_path)
-
- # Enable all LTE base stations. This is needed so that base settings
- # can be applied.
- self.anritsu.set_simulation_model(
- *[md8475a.BtsTechnology.LTE for _ in range(self.LTE_MAX_CARRIERS)],
- reset=False)
-
- # Load cell settings
- self.anritsu.load_cell_paramfile(cell_file_path)
-
- self.anritsu.start_simulation()
-
+ # MD4875A supports only 2 carriers. The MD4875B class adds other cells.
self.bts = [
self.anritsu.get_BTS(md8475a.BtsNumber.BTS1),
self.anritsu.get_BTS(md8475a.BtsNumber.BTS2)
]
- def set_ca_combination(self, combination):
- """ Prepares the test equipment for the indicated CA combination.
+ def set_band_combination(self, bands):
+ """ Prepares the test equipment for the indicated band combination.
The reason why this is implemented in a separate method and not calling
LteSimulation.BtsConfig for each separate band is that configuring each
@@ -129,40 +103,8 @@
be shared in the test equipment.
Args:
- combination: carrier aggregation configurations are indicated
- with a list of strings consisting of the band number followed
- by the CA class. For example, for 5 CA using 3C 7C and 28A
- the parameter value should be [3c, 7c, 28a].
+ bands: a list of bands represented as ints or strings
"""
-
- # Obtain the list of bands from the carrier combination list
- bands = []
-
- for ca in combination:
- ca_class = ca[-1]
- band = ca[:-1]
-
- # If the band appears twice in the combo it means that carriers
- # must be in the same band but non contiguous.
- if band in bands:
- raise cc.CellularSimulatorError(
- 'Intra-band non-contiguous carrier aggregation is not '
- 'supported.')
-
- if ca_class.upper() == 'B':
- raise cc.CellularSimulatorError(
- 'Class B carrier aggregation is not supported')
- elif ca_class.upper() == 'A':
- bands.append(band)
- elif ca_class.upper() == 'C':
- # Class C means two contiguous carriers in the same band, so
- # add the band twice to the list.
- bands.append(band)
- bands.append(band)
- else:
- raise cc.CellularSimulatorError('Invalid carrier aggregation '
- 'configuration: ' + ca)
-
self.num_carriers = len(bands)
# Validate the number of carriers.
@@ -170,10 +112,6 @@
raise cc.CellularSimulatorError('The test equipment supports up '
'to {} carriers.'.format(
self.LTE_MAX_CARRIERS))
- elif self.num_carriers < 2:
- raise cc.CellularSimulatorError('At least two carriers need to be '
- 'indicated for the carrier '
- 'aggregation simulation.')
# Initialize the base stations in the test equipment
self.anritsu.set_simulation_model(
@@ -187,7 +125,7 @@
# both base stations.
self.bts[0].mimo_support = md8475a.LteMimoMode.MIMO_4X4
self.bts[1].mimo_support = md8475a.LteMimoMode.MIMO_4X4
- if self.num_carriers == 3:
+ elif self.num_carriers == 3:
# 4X4 can only be done in the second base station if it is shared
# with the primary. If the RF cards cannot be shared, then at most
# 2X2 can be done.
@@ -197,17 +135,17 @@
else:
self.bts[1].mimo_support = md8475a.LteMimoMode.MIMO_2X2
self.bts[2].mimo_support = md8475a.LteMimoMode.MIMO_2X2
+ elif self.num_carriers > 3:
+ raise NotImplementedError('The controller doesn\'t implement more '
+ 'than 3 carriers for MD8475B yet.')
- # Enable carrier aggregation
- self.anritsu.set_carrier_aggregation_enabled()
+ # Enable carrier aggregation if there is more than one carrier
+ if self.num_carriers > 1:
+ self.anritsu.set_carrier_aggregation_enabled()
# Restart the simulation as changing the simulation model will stop it.
self.anritsu.start_simulation()
- # Set the bands in each base station
- for bts_index in range(len(bands)):
- self.set_band(bts_index, bands[bts_index])
-
def set_input_power(self, bts_index, input_power):
""" Sets the input power for the indicated base station.
@@ -245,36 +183,40 @@
# Temporarily adding this line to workaround a bug in the
# Anritsu callbox in which the channel number needs to be set
# to a different value before setting it to the final one.
- self.bts[bts_index].dl_channel = str(channel_number + 1)
+ self.bts[bts_index].dl_channel = str(int(channel_number + 1))
time.sleep(8)
- self.bts[bts_index].dl_channel = str(channel_number)
+ self.bts[bts_index].dl_channel = str(int(channel_number))
- def set_dl_modulation(self, bts_index, modulation):
- """ Sets the DL modulation for the indicated base station.
+ def set_dl_256_qam_enabled(self, bts_index, enabled):
+ """ Determines what MCS table should be used for the downlink.
Args:
bts_index: the base station number
- modulation: the new DL modulation
+ enabled: whether 256 QAM should be used
"""
- self.bts[bts_index].lte_dl_modulation_order = modulation.value
+ if enabled and not self.LTE_SUPPORTS_DL_256QAM:
+ raise RuntimeError('256 QAM is not supported')
+ self.bts[bts_index].lte_dl_modulation_order = \
+ md8475a.ModulationType.Q256 if enabled else md8475a.ModulationType.Q64
- def set_ul_modulation(self, bts_index, modulation):
- """ Sets the UL modulation for the indicated base station.
+ def set_ul_64_qam_enabled(self, bts_index, enabled):
+ """ Determines what MCS table should be used for the uplink.
Args:
bts_index: the base station number
- modulation: the new UL modulation
+ enabled: whether 64 QAM should be used
"""
- self.bts[bts_index].lte_ul_modulation_order = modulation.value
+ self.bts[bts_index].lte_ul_modulation_order = \
+ md8475a.ModulationType.Q64 if enabled else md8475a.ModulationType.Q16
- def set_tbs_pattern_on(self, bts_index, tbs_pattern_on):
- """ Enables or disables TBS pattern in the indicated base station.
+ def set_mac_padding(self, bts_index, mac_padding):
+ """ Enables or disables MAC padding in the indicated base station.
Args:
bts_index: the base station number
- tbs_pattern_on: the new TBS pattern setting
+ mac_padding: the new MAC padding setting
"""
- if tbs_pattern_on:
+ if mac_padding:
self.bts[bts_index].tbs_pattern = 'FULLALLOCATION'
else:
self.bts[bts_index].tbs_pattern = 'OFF'
@@ -515,7 +457,8 @@
"number of DL antennas will override this "
"setting.")
bts.dl_antenna = 2
- elif mimo == LteSimulation.MimoMode.MIMO_4x4:
+ elif mimo == LteSimulation.MimoMode.MIMO_4x4 and \
+ self.LTE_SUPPORTS_4X4_MIMO:
if bts.transmode not in [
LteSimulation.TransmissionMode.TM2,
LteSimulation.TransmissionMode.TM3,
@@ -689,6 +632,11 @@
def detach(self):
""" Turns off all the base stations so the DUT loose connection."""
+ if self.anritsu.get_smartstudio_status() == \
+ md8475a.ProcessingStatus.PROCESS_STATUS_NOTRUN.value:
+ self.log.info('Device cannot be detached because simulation is '
+ 'not running.')
+ return
self.anritsu.set_simulation_state_to_poweroff()
def stop(self):
@@ -772,10 +720,10 @@
# formatted to replace {} with either A or B depending on the model.
CALLBOX_CONFIG_PATH = 'C:\\Users\\MD8475B\\Documents\\DAN_configs\\'
- def setup_lte_ca_scenario(self):
+ def setup_lte_scenario(self):
""" The B model can support up to five carriers. """
- super().setup_lte_ca_scenario()
+ super().setup_lte_scenario()
self.bts.extend([
self.anritsu.get_BTS(md8475a.BtsNumber.BTS3),
diff --git a/acts/framework/acts/controllers/anritsu_lib/md8475a.py b/acts/framework/acts/controllers/anritsu_lib/md8475a.py
index ffaade4..2f2865f 100644
--- a/acts/framework/acts/controllers/anritsu_lib/md8475a.py
+++ b/acts/framework/acts/controllers/anritsu_lib/md8475a.py
@@ -449,6 +449,13 @@
DISABLE = "DISABLE"
+class ModulationType(Enum):
+ """Supported Modulation Types."""
+ Q16 = '16QAM'
+ Q64 = '64QAM'
+ Q256 = '256QAM'
+
+
class MD8475A(object):
"""Class to communicate with Anritsu MD8475A Signalling Tester.
This uses GPIB command to interface with Anritsu MD8475A """
@@ -3350,6 +3357,8 @@
Returns:
None
"""
+ if isinstance(order, ModulationType):
+ order = order.value
cmd = "DLRMC_MOD {},{}".format(order, self._bts_number)
self._anritsu.send_command(cmd)
@@ -3376,6 +3385,8 @@
Returns:
None
"""
+ if isinstance(order, ModulationType):
+ order = order.value
cmd = "ULRMC_MOD {},{}".format(order, self._bts_number)
self._anritsu.send_command(cmd)
diff --git a/acts/framework/acts/controllers/ap_lib/ap_get_interface.py b/acts/framework/acts/controllers/ap_lib/ap_get_interface.py
index 2a801ec..2a206b5 100644
--- a/acts/framework/acts/controllers/ap_lib/ap_get_interface.py
+++ b/acts/framework/acts/controllers/ap_lib/ap_get_interface.py
@@ -30,13 +30,15 @@
"""Class to get network interface information for the device.
"""
- def __init__(self, ap):
+ def __init__(self, ap, wan_interface_override=None):
"""Initialize the ApInterface class.
Args:
ap: the ap object within ACTS
+ wan_interface_override: wan interface to use if specified by config
"""
self.ssh = ap.ssh
+ self.wan_interface_override = wan_interface_override
def get_all_interface(self):
"""Get all network interfaces on the device.
@@ -120,13 +122,17 @@
raise ApInterfacesError('Missing at least one WLAN interface')
def get_wan_interface(self):
- """Get the WAN interface which has internet connectivity.
+ """Get the WAN interface which has internet connectivity. If a wan
+ interface is already specified return that instead.
Returns:
wan: the only one WAN interface
Raises:
ApInterfacesError: no running WAN can be found
"""
+ if self.wan_interface_override:
+ return self.wan_interface_override
+
wan = None
interfaces_phy = self.get_physical_interface()
interfaces_wlan = self.get_wlan_interface()
diff --git a/acts/framework/acts/controllers/ap_lib/dhcp_config.py b/acts/framework/acts/controllers/ap_lib/dhcp_config.py
index ddf6ac1..ffc9db1 100644
--- a/acts/framework/acts/controllers/ap_lib/dhcp_config.py
+++ b/acts/framework/acts/controllers/ap_lib/dhcp_config.py
@@ -16,6 +16,8 @@
import copy
import ipaddress
+_ROUTER_DNS = '8.8.8.8, 4.4.4.4'
+
class Subnet(object):
"""Configs for a subnet on the dhcp server.
@@ -25,7 +27,9 @@
start: ipaddress.IPv4Address, the start ip address.
end: ipaddress.IPv4Address, the end ip address.
router: The router to give to all hosts in this subnet.
- lease: The lease time of all hosts in this subnet.
+ lease_time: The lease time of all hosts in this subnet.
+ additional_parameters: A dictionary corresponding to DHCP parameters.
+ additional_options: A dictionary corresponding to DHCP options.
"""
def __init__(self,
@@ -33,20 +37,26 @@
start=None,
end=None,
router=None,
- lease_time=None):
+ lease_time=None,
+ additional_parameters={},
+ additional_options={}):
"""
Args:
- subnet_address: ipaddress.IPv4Network, The network that this
- subnet is.
+ subnet: ipaddress.IPv4Network, The address space of the subnetwork
+ served by the DHCP server.
start: ipaddress.IPv4Address, The start of the address range to
- give hosts in this subnet. If not given then the first ip in
- the network is used.
+ give hosts in this subnet. If not given, the second ip in
+ the network is used, under the assumption that the first
+ address is the router.
end: ipaddress.IPv4Address, The end of the address range to give
- hosts. If not given then the last ip in the network is used.
+ hosts. If not given then the address prior to the broadcast
+ address (i.e. the second to last ip in the network) is used.
router: ipaddress.IPv4Address, The router hosts should use in this
subnet. If not given the first ip in the network is used.
lease_time: int, The amount of lease time in seconds
hosts in this subnet have.
+ additional_parameters: A dictionary corresponding to DHCP parameters.
+ additional_options: A dictionary corresponding to DHCP options.
"""
self.network = subnet
@@ -83,6 +93,10 @@
else:
# TODO: Use some more clever logic so that we don't have to search
# every host potentially.
+ # This is especially important if we support IPv6 networks in this
+ # configuration. The improved logic that we can use is:
+ # a) erroring out if start and end encompass the whole network, and
+ # b) picking any address before self.start or after self.end.
self.router = None
for host in self.network.hosts():
if host < self.start or host > self.end:
@@ -93,6 +107,10 @@
raise ValueError('No useable host found.')
self.lease_time = lease_time
+ self.additional_parameters = additional_parameters
+ self.additional_options = additional_options
+ if 'domain-name-servers' not in self.additional_options:
+ self.additional_options['domain-name-servers'] = _ROUTER_DNS
class StaticMapping(object):
@@ -131,3 +149,57 @@
if static_mappings else [])
self.default_lease_time = default_lease_time
self.max_lease_time = max_lease_time
+
+ def render_config_file(self):
+ """Renders the config parameters into a format compatible with
+ the ISC DHCP server (dhcpd).
+ """
+ lines = []
+
+ if self.default_lease_time:
+ lines.append('default-lease-time %d;' % self.default_lease_time)
+ if self.max_lease_time:
+ lines.append('max-lease-time %s;' % self.max_lease_time)
+
+ for subnet in self.subnets:
+ address = subnet.network.network_address
+ mask = subnet.network.netmask
+ router = subnet.router
+ start = subnet.start
+ end = subnet.end
+ lease_time = subnet.lease_time
+ additional_parameters = subnet.additional_parameters
+ additional_options = subnet.additional_options
+
+ lines.append('subnet %s netmask %s {' % (address, mask))
+ lines.append('\tpool {')
+ lines.append('\t\toption subnet-mask %s;' % mask)
+ lines.append('\t\toption routers %s;' % router)
+ lines.append('\t\trange %s %s;' % (start, end))
+ if lease_time:
+ lines.append('\t\tdefault-lease-time %d;' % lease_time)
+ lines.append('\t\tmax-lease-time %d;' % lease_time)
+ for param, value in additional_parameters.items():
+ lines.append('\t\t%s %s;' % (param, value))
+ for option, value in additional_options.items():
+ lines.append('\t\toption %s %s;' % (option, value))
+ lines.append('\t}')
+ lines.append('}')
+
+ for mapping in self.static_mappings:
+ identifier = mapping.identifier
+ fixed_address = mapping.ipv4_address
+ host_fake_name = 'host%s' % identifier.replace(':', '')
+ lease_time = mapping.lease_time
+
+ lines.append('host %s {' % host_fake_name)
+ lines.append('\thardware ethernet %s;' % identifier)
+ lines.append('\tfixed-address %s;' % fixed_address)
+ if lease_time:
+ lines.append('\tdefault-lease-time %d;' % lease_time)
+ lines.append('\tmax-lease-time %d;' % lease_time)
+ lines.append('}')
+
+ config_str = '\n'.join(lines)
+
+ return config_str
diff --git a/acts/framework/acts/controllers/ap_lib/dhcp_server.py b/acts/framework/acts/controllers/ap_lib/dhcp_server.py
index a94ecf8..b243e6f 100644
--- a/acts/framework/acts/controllers/ap_lib/dhcp_server.py
+++ b/acts/framework/acts/controllers/ap_lib/dhcp_server.py
@@ -16,8 +16,7 @@
from retry import retry
from acts.controllers.utils_lib.commands import shell
-
-_ROUTER_DNS = '8.8.8.8, 4.4.4.4'
+from acts import logger
class Error(Exception):
@@ -47,10 +46,12 @@
interface: string, The name of the interface to use.
working_dir: The directory to work out of.
"""
+ self._log = logger.create_logger(lambda msg: '[DHCP Server|%s] %s' % (
+ interface, msg))
self._runner = runner
self._working_dir = working_dir
self._shell = shell.ShellCommand(runner, working_dir)
- self._log_file = 'dhcpd_%s.log' % interface
+ self._stdio_log_file = 'dhcpd_%s.log' % interface
self._config_file = 'dhcpd_%s.conf' % interface
self._lease_file = 'dhcpd_%s.leases' % interface
self._pid_file = 'dhcpd_%s.pid' % interface
@@ -71,31 +72,32 @@
config: dhcp_config.DhcpConfig, Configs to start the dhcp server
with.
- Returns:
- True if the daemon could be started. Note that the daemon can still
- start and not work. Invalid configurations can take a long amount
- of time to be produced, and because the daemon runs indefinitely
- it's infeasible to wait on. If you need to check if configs are ok
- then periodic checks to is_running and logs should be used.
+ Raises:
+ Error: Raised when a dhcp server error is found.
"""
if self.is_alive():
self.stop()
self._write_configs(config)
- self._shell.delete_file(self._log_file)
+ self._shell.delete_file(self._stdio_log_file)
+ self._shell.delete_file(self._pid_file)
self._shell.touch_file(self._lease_file)
dhcpd_command = '%s -cf "%s" -lf %s -f -pf "%s"' % (
self.PROGRAM_FILE, self._config_file, self._lease_file,
self._pid_file)
base_command = 'cd "%s"; %s' % (self._working_dir, dhcpd_command)
- job_str = '%s > "%s" 2>&1' % (base_command, self._log_file)
+ job_str = '%s > "%s" 2>&1' % (base_command, self._stdio_log_file)
self._runner.run_async(job_str)
try:
self._wait_for_process(timeout=timeout)
self._wait_for_server(timeout=timeout)
except:
+ self._log.warn("Failed to start DHCP server.")
+ self._log.info("DHCP configuration:\n" +
+ config.render_config_file() + "\n")
+ self._log.info("DHCP logs:\n" + self.get_logs() + "\n")
self.stop()
raise
@@ -117,7 +119,24 @@
Returns:
A string of the dhcp server logs.
"""
- return self._shell.read_file(self._log_file)
+ try:
+ # Try reading the PID file. This will fail if the server failed to
+ # start.
+ pid = self._shell.read_file(self._pid_file)
+ # `dhcpd` logs to the syslog, where its messages are interspersed
+ # with all other programs that use the syslog. Log lines contain
+ # `dhcpd[<pid>]`, which we can search for to extract all the logs
+ # from this particular dhcpd instance.
+ # The logs are preferable to the stdio output, since they contain
+ # a superset of the information from stdio, including leases
+ # that the server provides.
+ return self._shell.run(
+ f"grep dhcpd.{pid} /var/log/messages").stdout
+ except Exception:
+ self._log.info(
+ "Failed to read logs from syslog (likely because the server " +
+ "failed to start). Falling back to stdio output.")
+ return self._shell.read_file(self._stdio_log_file)
def _wait_for_process(self, timeout=60):
"""Waits for the process to come up.
@@ -146,7 +165,7 @@
start_time = time.time()
while time.time() - start_time < timeout:
success = self._shell.search_file(
- 'Wrote [0-9]* leases to leases file', self._log_file)
+ 'Wrote [0-9]* leases to leases file', self._stdio_log_file)
if success:
return
@@ -172,7 +191,7 @@
is_dead = not self.is_alive()
no_interface = self._shell.search_file(
- 'Not configured to listen on any interfaces', self._log_file)
+ 'Not configured to listen on any interfaces', self._stdio_log_file)
if no_interface:
raise NoInterfaceError(
'Dhcp does not contain a subnet for any of the networks the'
@@ -183,48 +202,6 @@
def _write_configs(self, config):
"""Writes the configs to the dhcp server config file."""
-
self._shell.delete_file(self._config_file)
-
- lines = []
-
- if config.default_lease_time:
- lines.append('default-lease-time %d;' % config.default_lease_time)
- if config.max_lease_time:
- lines.append('max-lease-time %s;' % config.max_lease_time)
-
- for subnet in config.subnets:
- address = subnet.network.network_address
- mask = subnet.network.netmask
- router = subnet.router
- start = subnet.start
- end = subnet.end
- lease_time = subnet.lease_time
-
- lines.append('subnet %s netmask %s {' % (address, mask))
- lines.append('\toption subnet-mask %s;' % mask)
- lines.append('\toption routers %s;' % router)
- lines.append('\toption domain-name-servers %s;' % _ROUTER_DNS)
- lines.append('\trange %s %s;' % (start, end))
- if lease_time:
- lines.append('\tdefault-lease-time %d;' % lease_time)
- lines.append('\tmax-lease-time %d;' % lease_time)
- lines.append('}')
-
- for mapping in config.static_mappings:
- identifier = mapping.identifier
- fixed_address = mapping.ipv4_address
- host_fake_name = 'host%s' % identifier.replace(':', '')
- lease_time = mapping.lease_time
-
- lines.append('host %s {' % host_fake_name)
- lines.append('\thardware ethernet %s;' % identifier)
- lines.append('\tfixed-address %s;' % fixed_address)
- if lease_time:
- lines.append('\tdefault-lease-time %d;' % lease_time)
- lines.append('\tmax-lease-time %d;' % lease_time)
- lines.append('}')
-
- config_str = '\n'.join(lines)
-
+ config_str = config.render_config_file()
self._shell.write_file(self._config_file, config_str)
diff --git a/acts/framework/acts/controllers/ap_lib/hostapd.py b/acts/framework/acts/controllers/ap_lib/hostapd.py
index 92b5ca3..d08caf2 100644
--- a/acts/framework/acts/controllers/ap_lib/hostapd.py
+++ b/acts/framework/acts/controllers/ap_lib/hostapd.py
@@ -16,9 +16,11 @@
import itertools
import logging
import os
+import re
import time
from acts.controllers.ap_lib import hostapd_config
+from acts.controllers.ap_lib import hostapd_constants
from acts.controllers.utils_lib.commands import shell
@@ -34,6 +36,7 @@
"""
PROGRAM_FILE = '/usr/sbin/hostapd'
+ CLI_PROGRAM_FILE = '/usr/bin/hostapd_cli'
def __init__(self, runner, interface, working_dir='/tmp'):
"""
@@ -102,6 +105,38 @@
if self.is_alive():
self._shell.kill(self._identifier)
+ def channel_switch(self, channel_num):
+ """Switches to the given channel.
+
+ Returns:
+ acts.libs.proc.job.Result containing the results of the command.
+ Raises: See _run_hostapd_cli_cmd
+ """
+ try:
+ channel_freq = hostapd_constants.FREQUENCY_MAP[channel_num]
+ except KeyError:
+ raise ValueError('Invalid channel number {}'.format(channel_num))
+ csa_beacon_count = 10
+ channel_switch_cmd = 'chan_switch {} {}'.format(
+ csa_beacon_count, channel_freq)
+ result = self._run_hostapd_cli_cmd(channel_switch_cmd)
+
+ def get_current_channel(self):
+ """Returns the current channel number.
+
+ Raises: See _run_hostapd_cli_cmd
+ """
+ status_cmd = 'status'
+ result = self._run_hostapd_cli_cmd(status_cmd)
+ match = re.search(r'^channel=(\d+)$', result.stdout, re.MULTILINE)
+ if not match:
+ raise Error('Current channel could not be determined')
+ try:
+ channel = int(match.group(1))
+ except ValueError:
+ raise Error('Internal error: current channel could not be parsed')
+ return channel
+
def is_alive(self):
"""
Returns:
@@ -118,6 +153,28 @@
# TODO: Auto pulling of logs when stop is called.
return self._shell.read_file(self._log_file)
+ def _run_hostapd_cli_cmd(self, cmd):
+ """Run the given hostapd_cli command.
+
+ Runs the command, waits for the output (up to default timeout), and
+ returns the result.
+
+ Returns:
+ acts.libs.proc.job.Result containing the results of the ssh command.
+
+ Raises:
+ acts.lib.proc.job.TimeoutError: When the remote command took too
+ long to execute.
+ acts.controllers.utils_lib.ssh.connection.Error: When the ssh
+ connection failed to be created.
+ acts.controllers.utils_lib.ssh.connection.CommandError: Ssh worked,
+ but the command had an error executing.
+ """
+ hostapd_cli_job = 'cd {}; {} -p {} {}'.format(self._working_dir,
+ self.CLI_PROGRAM_FILE,
+ self._ctrl_file, cmd)
+ return self._runner.run(hostapd_cli_job)
+
def _wait_for_process(self, timeout=60):
"""Waits for the process to come up.
@@ -142,12 +199,14 @@
"""
start_time = time.time()
while time.time() - start_time < timeout:
+ time.sleep(0.1)
success = self._shell.search_file('Setup of interface done',
self._log_file)
if success:
return
+ self._scan_for_errors(False)
- self._scan_for_errors(True)
+ self._scan_for_errors(True)
def _scan_for_errors(self, should_be_up):
"""Scans the hostapd log for any errors.
diff --git a/acts/framework/acts/controllers/ap_lib/radvd.py b/acts/framework/acts/controllers/ap_lib/radvd.py
index 187f9e7..e88701e 100644
--- a/acts/framework/acts/controllers/ap_lib/radvd.py
+++ b/acts/framework/acts/controllers/ap_lib/radvd.py
@@ -134,8 +134,9 @@
"""
start_time = time.time()
while time.time() - start_time < timeout and not self.is_alive():
- self._scan_for_errors(True)
time.sleep(0.1)
+ self._scan_for_errors(False)
+ self._scan_for_errors(True)
def _scan_for_errors(self, should_be_up):
"""Scans the radvd log for any errors.
diff --git a/acts/framework/acts/controllers/attenuator.py b/acts/framework/acts/controllers/attenuator.py
index ad5ad81..b7f4a6d 100644
--- a/acts/framework/acts/controllers/attenuator.py
+++ b/acts/framework/acts/controllers/attenuator.py
@@ -228,7 +228,7 @@
self.max_atten = AttenuatorInstrument.INVALID_MAX_ATTEN
self.properties = None
- def set_atten(self, idx, value, strict=True):
+ def set_atten(self, idx, value, strict=True, retry=False):
"""Sets the attenuation given its index in the instrument.
Args:
@@ -238,15 +238,17 @@
strict: if True, function raises an error when given out of
bounds attenuation values, if false, the function sets out of
bounds values to 0 or max_atten.
+ retry: if True, command will be retried if possible
"""
raise NotImplementedError('Base class should not be called directly!')
- def get_atten(self, idx):
+ def get_atten(self, idx, retry=False):
"""Returns the current attenuation of the attenuator at index idx.
Args:
idx: A zero based index used to identify a particular attenuator in
an instrument.
+ retry: if True, command will be retried if possible
Returns:
The current attenuation value as a floating point value
@@ -262,6 +264,7 @@
the physical implementation and allows the user to think only of attenuators
regardless of their location.
"""
+
def __init__(self, instrument, idx=0, offset=0):
"""This is the constructor for Attenuator
@@ -290,7 +293,7 @@
raise IndexError(
'Attenuator index out of range for attenuator instrument')
- def set_atten(self, value, strict=True):
+ def set_atten(self, value, strict=True, retry=False):
"""Sets the attenuation.
Args:
@@ -298,6 +301,7 @@
strict: if True, function raises an error when given out of
bounds attenuation values, if false, the function sets out of
bounds values to 0 or max_atten.
+ retry: if True, command will be retried if possible
Raises:
ValueError if value + offset is greater than the maximum value.
@@ -306,11 +310,14 @@
raise ValueError(
'Attenuator Value+Offset greater than Max Attenuation!')
- self.instrument.set_atten(self.idx, value + self.offset, strict)
+ self.instrument.set_atten(self.idx,
+ value + self.offset,
+ strict=strict,
+ retry=retry)
- def get_atten(self):
+ def get_atten(self, retry=False):
"""Returns the attenuation as a float, normalized by the offset."""
- return self.instrument.get_atten(self.idx) - self.offset
+ return self.instrument.get_atten(self.idx, retry) - self.offset
def get_max_atten(self):
"""Returns the max attenuation as a float, normalized by the offset."""
@@ -330,6 +337,7 @@
convenience to the user and avoid re-implementation of helper functions and
small loops scattered throughout user code.
"""
+
def __init__(self, name=''):
"""This constructor for AttenuatorGroup
diff --git a/acts/framework/acts/controllers/attenuator_lib/_tnhelper.py b/acts/framework/acts/controllers/attenuator_lib/_tnhelper.py
index 028814e..348cab1 100644
--- a/acts/framework/acts/controllers/attenuator_lib/_tnhelper.py
+++ b/acts/framework/acts/controllers/attenuator_lib/_tnhelper.py
@@ -35,8 +35,9 @@
It should only be used by those implementation control libraries and not by
any user code directly.
"""
-
- def __init__(self, tx_cmd_separator='\n', rx_cmd_separator='\n',
+ def __init__(self,
+ tx_cmd_separator='\n',
+ rx_cmd_separator='\n',
prompt=''):
self._tn = None
self._ip_address = None
@@ -78,7 +79,8 @@
"""
logging.debug('Diagnosing telnet connection')
try:
- job_result = job.run('ping {} -c 5'.format(self._ip_address))
+ job_result = job.run('ping {} -c 5 -i 0.1'.format(
+ self._ip_address))
except:
logging.error("Unable to ping telnet server.")
return False
@@ -99,7 +101,7 @@
logging.debug('Telnet connection likely recovered')
return True
- def cmd(self, cmd_str, wait_ret=True):
+ def cmd(self, cmd_str, wait_ret=True, retry=False):
if not isinstance(cmd_str, str):
raise TypeError('Invalid command string', cmd_str)
@@ -117,16 +119,21 @@
match_idx, match_val, ret_text = self._tn.expect(
[_ascii_string('\S+' + self.rx_cmd_separator)], 1)
+ logging.debug('Telnet Command: {}'.format(cmd_str))
+ logging.debug('Telnet Reply: ({},{},{})'.format(
+ match_idx, match_val, ret_text))
+
if match_idx == -1:
- logging.debug('Telnet Command: {}'.format(cmd_str))
- logging.debug('Telnet Reply: ({},{},{})'.format(
- match_idx, match_val, ret_text))
- self.diagnose_telnet()
- raise attenuator.InvalidDataError(
- 'Telnet command failed to return valid data')
+ telnet_recovered = self.diagnose_telnet()
+ if telnet_recovered and retry:
+ logging.debug('Retrying telnet command once.')
+ return self.cmd(cmd_str, wait_ret, retry=False)
+ else:
+ raise attenuator.InvalidDataError(
+ 'Telnet command failed to return valid data')
ret_text = ret_text.decode()
- ret_text = ret_text.strip(
- self.tx_cmd_separator + self.rx_cmd_separator + self.prompt)
+ ret_text = ret_text.strip(self.tx_cmd_separator +
+ self.rx_cmd_separator + self.prompt)
- return ret_text
\ No newline at end of file
+ return ret_text
diff --git a/acts/framework/acts/controllers/attenuator_lib/aeroflex/telnet.py b/acts/framework/acts/controllers/attenuator_lib/aeroflex/telnet.py
index 8a7a2cd..2e46ebf 100644
--- a/acts/framework/acts/controllers/attenuator_lib/aeroflex/telnet.py
+++ b/acts/framework/acts/controllers/attenuator_lib/aeroflex/telnet.py
@@ -78,7 +78,7 @@
"""
self._tnhelper.close()
- def set_atten(self, idx, value):
+ def set_atten(self, idx, value, **_):
"""This function sets the attenuation of an attenuator given its index
in the instrument.
@@ -107,7 +107,7 @@
self._tnhelper.cmd('ATTN ' + str(idx + 1) + ' ' + str(value), False)
- def get_atten(self, idx):
+ def get_atten(self, idx, **_):
"""Returns the current attenuation of the attenuator at the given index.
Args:
diff --git a/acts/framework/acts/controllers/attenuator_lib/minicircuits/http.py b/acts/framework/acts/controllers/attenuator_lib/minicircuits/http.py
index f6d61e9..21ca646 100644
--- a/acts/framework/acts/controllers/attenuator_lib/minicircuits/http.py
+++ b/acts/framework/acts/controllers/attenuator_lib/minicircuits/http.py
@@ -59,7 +59,7 @@
att_req = urllib.request.urlopen('http://{}:{}/MN?'.format(
self._ip_address, self._port))
- config_str = att_req.read().decode('utf-8')
+ config_str = att_req.read().decode('utf-8').strip()
if not config_str.startswith('MN='):
raise attenuator.InvalidDataError(
'Attenuator returned invalid data. Attenuator returned: {}'.
@@ -86,7 +86,7 @@
"""
pass
- def set_atten(self, idx, value, strict_flag=True):
+ def set_atten(self, idx, value, strict=True, **_):
"""This function sets the attenuation of an attenuator given its index
in the instrument.
@@ -95,7 +95,7 @@
an instrument. For instruments that only have one channel, this
is ignored by the device.
value: A floating point value for nominal attenuation to be set.
- strict_flag: if True, function raises an error when given out of
+ strict: if True, function raises an error when given out of
bounds attenuation values, if false, the function sets out of
bounds values to 0 or max_atten.
@@ -107,21 +107,23 @@
raise IndexError('Attenuator index out of range!', self.num_atten,
idx)
- if value > self.max_atten and strict_flag:
+ if value > self.max_atten and strict:
raise ValueError('Attenuator value out of range!', self.max_atten,
value)
# The actual device uses one-based index for channel numbers.
+ adjusted_value = min(max(0, value), self.max_atten)
att_req = urllib.request.urlopen(
- 'http://{}:{}/CHAN:{}:SETATT:{}'.format(
- self._ip_address, self._port, idx + 1, value),
+ 'http://{}:{}/CHAN:{}:SETATT:{}'.format(self._ip_address,
+ self._port, idx + 1,
+ adjusted_value),
timeout=self._timeout)
- att_resp = att_req.read().decode('utf-8')
+ att_resp = att_req.read().decode('utf-8').strip()
if att_resp != '1':
raise attenuator.InvalidDataError(
- 'Attenuator returned invalid data. Attenuator returned: {}'.
- format(att_resp))
+ f"Attenuator returned invalid data. Attenuator returned: {att_resp}"
+ )
- def get_atten(self, idx):
+ def get_atten(self, idx, **_):
"""Returns the current attenuation of the attenuator at the given index.
Args:
@@ -141,7 +143,7 @@
'http://{}:{}/CHAN:{}:ATT?'.format(self._ip_address, self.port,
idx + 1),
timeout=self._timeout)
- att_resp = att_req.read().decode('utf-8')
+ att_resp = att_req.read().decode('utf-8').strip()
try:
atten_val = float(att_resp)
except:
diff --git a/acts/framework/acts/controllers/attenuator_lib/minicircuits/telnet.py b/acts/framework/acts/controllers/attenuator_lib/minicircuits/telnet.py
index 87d1d98..ddda6ab 100644
--- a/acts/framework/acts/controllers/attenuator_lib/minicircuits/telnet.py
+++ b/acts/framework/acts/controllers/attenuator_lib/minicircuits/telnet.py
@@ -37,6 +37,7 @@
the functionality of AttenuatorInstrument is contingent upon a telnet
connection being established.
"""
+
def __init__(self, num_atten=0):
super(AttenuatorInstrument, self).__init__(num_atten)
self._tnhelper = _tnhelper._TNHelper(tx_cmd_separator='\r\n',
@@ -84,7 +85,7 @@
"""
self._tnhelper.close()
- def set_atten(self, idx, value, strict_flag=True):
+ def set_atten(self, idx, value, strict=True, retry=False):
"""This function sets the attenuation of an attenuator given its index
in the instrument.
@@ -93,9 +94,10 @@
an instrument. For instruments that only have one channel, this
is ignored by the device.
value: A floating point value for nominal attenuation to be set.
- strict_flag: if True, function raises an error when given out of
+ strict: if True, function raises an error when given out of
bounds attenuation values, if false, the function sets out of
bounds values to 0 or max_atten.
+ retry: if True, command will be retried if possible
Raises:
InvalidOperationError if the telnet connection is not open.
@@ -111,17 +113,20 @@
raise IndexError('Attenuator index out of range!', self.num_atten,
idx)
- if value > self.max_atten and strict_flag:
+ if value > self.max_atten and strict:
raise ValueError('Attenuator value out of range!', self.max_atten,
value)
# The actual device uses one-based index for channel numbers.
- self._tnhelper.cmd('CHAN:%s:SETATT:%s' % (idx + 1, value))
+ adjusted_value = min(max(0, value), self.max_atten)
+ self._tnhelper.cmd('CHAN:%s:SETATT:%s' % (idx + 1, adjusted_value),
+ retry=retry)
- def get_atten(self, idx):
+ def get_atten(self, idx, retry=False):
"""Returns the current attenuation of the attenuator at the given index.
Args:
idx: The index of the attenuator.
+ retry: if True, command will be retried if possible
Raises:
InvalidOperationError if the telnet connection is not open.
@@ -137,8 +142,9 @@
idx)
if self.num_atten == 1:
- atten_val_str = self._tnhelper.cmd(':ATT?')
+ atten_val_str = self._tnhelper.cmd(':ATT?', retry=retry)
else:
- atten_val_str = self._tnhelper.cmd('CHAN:%s:ATT?' % (idx + 1))
+ atten_val_str = self._tnhelper.cmd('CHAN:%s:ATT?' % (idx + 1),
+ retry=retry)
atten_val = float(atten_val_str)
return atten_val
diff --git a/acts/framework/acts/controllers/cellular_lib/BaseCellConfig.py b/acts/framework/acts/controllers/cellular_lib/BaseCellConfig.py
new file mode 100644
index 0000000..14540de
--- /dev/null
+++ b/acts/framework/acts/controllers/cellular_lib/BaseCellConfig.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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.
+
+
+class BaseCellConfig:
+ """ Base cell configuration class.
+
+ Attributes:
+ output_power: a float indicating the required signal level at the
+ instrument's output.
+ input_power: a float indicating the required signal level at the
+ instrument's input.
+ """
+ # Configuration dictionary keys
+ PARAM_UL_PW = 'pul'
+ PARAM_DL_PW = 'pdl'
+
+ def __init__(self, log):
+ """ Initialize the base station config by setting all its
+ parameters to None.
+ Args:
+ log: logger object.
+ """
+ self.log = log
+ self.output_power = None
+ self.input_power = None
+ self.band = None
+
+ def incorporate(self, new_config):
+ """ Incorporates a different configuration by replacing the current
+ values with the new ones for all the parameters different to None.
+ Args:
+ new_config: 5G cell configuration object.
+ """
+ for attr, value in vars(new_config).items():
+ if value and not hasattr(self, attr):
+ setattr(self, attr, value)
diff --git a/acts/framework/acts/controllers/cellular_lib/BaseSimulation.py b/acts/framework/acts/controllers/cellular_lib/BaseSimulation.py
index f956f72..7427628 100644
--- a/acts/framework/acts/controllers/cellular_lib/BaseSimulation.py
+++ b/acts/framework/acts/controllers/cellular_lib/BaseSimulation.py
@@ -19,6 +19,7 @@
import numpy as np
from acts.controllers import cellular_simulator
+from acts.controllers.cellular_lib.BaseCellConfig import BaseCellConfig
class BaseSimulation(object):
@@ -59,40 +60,14 @@
DEFAULT_ATTACH_RETRIES = 3
# These two dictionaries allow to map from a string to a signal level and
- # have to be overriden by the simulations inheriting from this class.
+ # have to be overridden by the simulations inheriting from this class.
UPLINK_SIGNAL_LEVEL_DICTIONARY = {}
DOWNLINK_SIGNAL_LEVEL_DICTIONARY = {}
- # Units for downlink signal level. This variable has to be overriden by
+ # Units for downlink signal level. This variable has to be overridden by
# the simulations inheriting from this class.
DOWNLINK_SIGNAL_LEVEL_UNITS = None
- class BtsConfig:
- """ Base station configuration class. This class is only a container for
- base station parameters and should not interact with the instrument
- controller.
-
- Atributes:
- output_power: a float indicating the required signal level at the
- instrument's output.
- input_level: a float indicating the required signal level at the
- instrument's input.
- """
- def __init__(self):
- """ Initialize the base station config by setting all its
- parameters to None. """
- self.output_power = None
- self.input_power = None
- self.band = None
-
- def incorporate(self, new_config):
- """ Incorporates a different configuration by replacing the current
- values with the new ones for all the parameters different to None.
- """
- for attr, value in vars(new_config).items():
- if value:
- setattr(self, attr, value)
-
def __init__(self, simulator, log, dut, test_config, calibration_table):
""" Initializes the Simulation object.
@@ -145,8 +120,8 @@
self.attach_timeout = test_config.get(self.KEY_ATTACH_TIMEOUT,
self.DEFAULT_ATTACH_TIMEOUT)
- # Configuration object for the primary base station
- self.primary_config = self.BtsConfig()
+ # Create an empty list for cell configs.
+ self.cell_configs = []
# Store the current calibrated band
self.current_calibrated_band = None
@@ -199,11 +174,11 @@
time.sleep(2)
# Provide a good signal power for the phone to attach easily
- new_config = self.BtsConfig()
+ new_config = BaseCellConfig(self.log)
new_config.input_power = -10
new_config.output_power = -30
self.simulator.configure_bts(new_config)
- self.primary_config.incorporate(new_config)
+ self.cell_configs[0].incorporate(new_config)
# Try to attach the phone.
for i in range(self.attach_retries):
@@ -294,13 +269,13 @@
# Wait until it goes to communication state
self.simulator.wait_until_communication_state()
- # Set uplink power to a minimum before going to the actual desired
+ # Set uplink power to a low value before going to the actual desired
# value. This avoid inconsistencies produced by the hysteresis in the
# PA switching points.
- self.log.info('Setting UL power to -30 dBm before going to the '
+ self.log.info('Setting UL power to -5 dBm before going to the '
'requested value to avoid incosistencies caused by '
'hysteresis.')
- self.set_uplink_tx_power(-30)
+ self.set_uplink_tx_power(-5)
# Set signal levels obtained from the test parameters
self.set_downlink_rx_power(self.sim_dl_power)
@@ -325,51 +300,28 @@
# Stop IP traffic after setting the UL power level
self.stop_traffic_for_calibration()
- def parse_parameters(self, parameters):
- """ Configures simulation using a list of parameters.
+ def configure(self, parameters):
+ """ Configures simulation using a dictionary of parameters.
- Consumes parameters from a list.
Children classes need to call this method first.
Args:
- parameters: list of parameters
+ parameters: a configuration dictionary
"""
+ # Setup uplink power
+ ul_power = self.get_uplink_power_from_parameters(parameters)
- raise NotImplementedError()
+ # Power is not set on the callbox until after the simulation is
+ # started. Saving this value in a variable for later
+ self.sim_ul_power = ul_power
- def consume_parameter(self, parameters, parameter_name, num_values=0):
- """ Parses a parameter from a list.
+ # Setup downlink power
- Allows to parse the parameter list. Will delete parameters from the
- list after consuming them to ensure that they are not used twice.
+ dl_power = self.get_downlink_power_from_parameters(parameters)
- Args:
- parameters: list of parameters
- parameter_name: keyword to look up in the list
- num_values: number of arguments following the
- parameter name in the list
- Returns:
- A list containing the parameter name and the following num_values
- arguments
- """
-
- try:
- i = parameters.index(parameter_name)
- except ValueError:
- # parameter_name is not set
- return []
-
- return_list = []
-
- try:
- for j in range(num_values + 1):
- return_list.append(parameters.pop(i))
- except IndexError:
- raise ValueError(
- "Parameter {} has to be followed by {} values.".format(
- parameter_name, num_values))
-
- return return_list
+ # Power is not set on the callbox until after the simulation is
+ # started. Saving this value in a variable for later
+ self.sim_dl_power = dl_power
def set_uplink_tx_power(self, signal_level):
""" Configure the uplink tx power level
@@ -377,11 +329,11 @@
Args:
signal_level: calibrated tx power in dBm
"""
- new_config = self.BtsConfig()
+ new_config = BaseCellConfig(self.log)
new_config.input_power = self.calibrated_uplink_tx_power(
- self.primary_config, signal_level)
+ self.cell_configs[0], signal_level)
self.simulator.configure_bts(new_config)
- self.primary_config.incorporate(new_config)
+ self.cell_configs[0].incorporate(new_config)
def set_downlink_rx_power(self, signal_level):
""" Configure the downlink rx power level
@@ -389,51 +341,49 @@
Args:
signal_level: calibrated rx power in dBm
"""
- new_config = self.BtsConfig()
+ new_config = BaseCellConfig(self.log)
new_config.output_power = self.calibrated_downlink_rx_power(
- self.primary_config, signal_level)
+ self.cell_configs[0], signal_level)
self.simulator.configure_bts(new_config)
- self.primary_config.incorporate(new_config)
+ self.cell_configs[0].incorporate(new_config)
def get_uplink_power_from_parameters(self, parameters):
- """ Reads uplink power from a list of parameters. """
+ """ Reads uplink power from the parameter dictionary. """
- values = self.consume_parameter(parameters, self.PARAM_UL_PW, 1)
-
- if values:
- if values[1] in self.UPLINK_SIGNAL_LEVEL_DICTIONARY:
- return self.UPLINK_SIGNAL_LEVEL_DICTIONARY[values[1]]
+ if BaseCellConfig.PARAM_UL_PW in parameters:
+ value = parameters[BaseCellConfig.PARAM_UL_PW]
+ if value in self.UPLINK_SIGNAL_LEVEL_DICTIONARY:
+ return self.UPLINK_SIGNAL_LEVEL_DICTIONARY[value]
else:
try:
- if values[1][0] == 'n':
+ if isinstance(value[0], str) and value[0] == 'n':
# Treat the 'n' character as a negative sign
- return -int(values[1][1:])
+ return -int(value[1:])
else:
- return int(values[1])
+ return int(value)
except ValueError:
pass
# If the method got to this point it is because PARAM_UL_PW was not
# included in the test parameters or the provided value was invalid.
raise ValueError(
- "The test name needs to include parameter {} followed by the "
- "desired uplink power expressed by an integer number in dBm "
- "or by one the following values: {}. To indicate negative "
+ "The config dictionary must include a key {} with the desired "
+ "uplink power expressed by an integer number in dBm or with one of "
+ "the following values: {}. To indicate negative "
"values, use the letter n instead of - sign.".format(
- self.PARAM_UL_PW,
+ BaseCellConfig.PARAM_UL_PW,
list(self.UPLINK_SIGNAL_LEVEL_DICTIONARY.keys())))
def get_downlink_power_from_parameters(self, parameters):
- """ Reads downlink power from a list of parameters. """
+ """ Reads downlink power from a the parameter dictionary. """
- values = self.consume_parameter(parameters, self.PARAM_DL_PW, 1)
-
- if values:
- if values[1] not in self.DOWNLINK_SIGNAL_LEVEL_DICTIONARY:
- raise ValueError("Invalid signal level value {}.".format(
- values[1]))
+ if BaseCellConfig.PARAM_DL_PW in parameters:
+ value = parameters[BaseCellConfig.PARAM_DL_PW]
+ if value not in self.DOWNLINK_SIGNAL_LEVEL_DICTIONARY:
+ raise ValueError(
+ "Invalid signal level value {}.".format(value))
else:
- return self.DOWNLINK_SIGNAL_LEVEL_DICTIONARY[values[1]]
+ return self.DOWNLINK_SIGNAL_LEVEL_DICTIONARY[value]
else:
# Use default value
power = self.DOWNLINK_SIGNAL_LEVEL_DICTIONARY['excellent']
@@ -598,7 +548,7 @@
reported signal level and bts. use None if no conversion is
needed.
Returns:
- Dowlink calibration value and measured DL power.
+ Downlink calibration value and measured DL power.
"""
# Check if this parameter was set. Child classes may need to override
@@ -609,11 +559,11 @@
"reported by the phone.")
# Save initial output level to restore it after calibration
- restoration_config = self.BtsConfig()
- restoration_config.output_power = self.primary_config.output_power
+ restoration_config = BaseCellConfig(self.log)
+ restoration_config.output_power = self.cell_configs[0].output_power
# Set BTS to a good output level to minimize measurement error
- new_config = self.BtsConfig()
+ new_config = BaseCellConfig(self.log)
new_config.output_power = self.simulator.MAX_DL_POWER - 5
self.simulator.configure_bts(new_config)
@@ -640,7 +590,7 @@
# Convert from RSRP to signal power
if power_units_conversion_func:
avg_down_power = power_units_conversion_func(
- reported_asu_power, self.primary_config)
+ reported_asu_power, self.cell_configs[0])
else:
avg_down_power = reported_asu_power
@@ -670,13 +620,13 @@
"""
# Save initial input level to restore it after calibration
- restoration_config = self.BtsConfig()
- restoration_config.input_power = self.primary_config.input_power
+ restoration_config = BaseCellConfig(self.log)
+ restoration_config.input_power = self.cell_configs[0].input_power
# Set BTS1 to maximum input allowed in order to perform
# uplink calibration
target_power = self.MAX_PHONE_OUTPUT_POWER
- new_config = self.BtsConfig()
+ new_config = BaseCellConfig(self.log)
new_config.input_power = self.MAX_BTS_INPUT_POWER
self.simulator.configure_bts(new_config)
@@ -742,7 +692,7 @@
# Load the new ones
if self.calibration_required:
- band = self.primary_config.band
+ band = self.cell_configs[0].band
# Try loading the path loss values from the calibration table. If
# they are not available, use the automated calibration procedure.
diff --git a/acts/framework/acts/controllers/cellular_lib/GsmSimulation.py b/acts/framework/acts/controllers/cellular_lib/GsmSimulation.py
index b7237f3..f907567 100644
--- a/acts/framework/acts/controllers/cellular_lib/GsmSimulation.py
+++ b/acts/framework/acts/controllers/cellular_lib/GsmSimulation.py
@@ -26,6 +26,7 @@
from acts.controllers.anritsu_lib import md8475_cellular_simulator as anritsusim
from acts.controllers.cellular_lib import BaseCellularDut
from acts.controllers.cellular_lib.BaseSimulation import BaseSimulation
+from acts.controllers.cellular_lib.BaseCellConfig import BaseCellConfig
class GsmSimulation(BaseSimulation):
@@ -39,8 +40,7 @@
GSM_CELL_FILE = 'CELL_GSM_config.wnscp'
- # Test name parameters
-
+ # Configuration dictionary keys
PARAM_BAND = "band"
PARAM_GPRS = "gprs"
PARAM_EGPRS = "edge"
@@ -57,7 +57,7 @@
def __init__(self, simulator, log, dut, test_config, calibration_table):
""" Initializes the simulator for a single-carrier GSM simulation.
- Loads a simple LTE simulation enviroment with 1 basestation. It also
+ Loads a simple LTE simulation environment with 1 basestation. It also
creates the BTS handle so we can change the parameters as desired.
Args:
@@ -100,52 +100,48 @@
# Start simulation if it wasn't started
self.anritsu.start_simulation()
- def parse_parameters(self, parameters):
- """ Configs a GSM simulation using a list of parameters.
+ def configure(self, parameters):
+ """ Configures simulation using a dictionary of parameters.
- Calls the parent method first, then consumes parameters specific to GSM.
+ Processes GSM configuration parameters.
Args:
- parameters: list of parameters
+ parameters: a configuration dictionary
"""
+ # Don't call super() because Gsm doesn't control Tx power.
# Setup band
-
- values = self.consume_parameter(parameters, self.PARAM_BAND, 1)
-
- if not values:
+ if self.PARAM_BAND not in parameters:
raise ValueError(
- "The test name needs to include parameter '{}' followed by "
- "the required band number.".format(self.PARAM_BAND))
+ "The configuration dictionary must include key '{}' with the "
+ "required band number.".format(self.PARAM_BAND))
- self.set_band(self.bts1, values[1])
+ self.set_band(self.bts1, parameters[self.PARAM_BAND])
self.load_pathloss_if_required()
# Setup GPRS mode
- if self.consume_parameter(parameters, self.PARAM_GPRS):
+ if self.PARAM_GPRS in parameters:
self.bts1.gsm_gprs_mode = BtsGprsMode.GPRS
- elif self.consume_parameter(parameters, self.PARAM_EGPRS):
+ elif self.PARAM_EGPRS in parameters:
self.bts1.gsm_gprs_mode = BtsGprsMode.EGPRS
- elif self.consume_parameter(parameters, self.PARAM_NO_GPRS):
+ elif self.PARAM_NO_GPRS in parameters:
self.bts1.gsm_gprs_mode = BtsGprsMode.NO_GPRS
else:
raise ValueError(
- "GPRS mode needs to be indicated in the test name with either "
- "{}, {} or {}.".format(self.PARAM_GPRS, self.PARAM_EGPRS,
- self.PARAM_NO_GPRS))
+ "GPRS mode needs to be indicated in the config dictionary by "
+ "including either {}, {} or {} as a key.".format(
+ self.PARAM_GPRS, self.PARAM_EGPRS, self.PARAM_NO_GPRS))
# Setup slot allocation
-
- values = self.consume_parameter(parameters, self.PARAM_SLOTS, 2)
-
- if not values:
+ if self.PARAM_SLOTS not in parameters or len(
+ parameters[self.PARAM_SLOTS]) != 2:
raise ValueError(
- "The test name needs to include parameter {} followed by two "
+ "The config dictionary must include key {} with a list of two "
"int values indicating DL and UL slots.".format(
self.PARAM_SLOTS))
-
- self.bts1.gsm_slots = (int(values[1]), int(values[2]))
+ values = parameters[self.PARAM_SLOTS]
+ self.bts1.gsm_slots = (int(values[0]), int(values[1]))
def set_band(self, bts, band):
""" Sets the band used for communication.
diff --git a/acts/framework/acts/controllers/cellular_lib/LteCaSimulation.py b/acts/framework/acts/controllers/cellular_lib/LteCaSimulation.py
deleted file mode 100644
index 3f98a34..0000000
--- a/acts/framework/acts/controllers/cellular_lib/LteCaSimulation.py
+++ /dev/null
@@ -1,427 +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 re
-from acts.controllers.cellular_lib import LteSimulation
-
-
-class LteCaSimulation(LteSimulation.LteSimulation):
- """ Carrier aggregation LTE simulation. """
-
- # Dictionary of lower DL channel number bound for each band.
- LOWEST_DL_CN_DICTIONARY = {
- 1: 0,
- 2: 600,
- 3: 1200,
- 4: 1950,
- 5: 2400,
- 6: 2650,
- 7: 2750,
- 8: 3450,
- 9: 3800,
- 10: 4150,
- 11: 4750,
- 12: 5010,
- 13: 5180,
- 14: 5280,
- 17: 5730,
- 18: 5850,
- 19: 6000,
- 20: 6150,
- 21: 6450,
- 22: 6600,
- 23: 7500,
- 24: 7700,
- 25: 8040,
- 26: 8690,
- 27: 9040,
- 28: 9210,
- 29: 9660,
- 30: 9770,
- 31: 9870,
- 32: 36000,
- 33: 36200,
- 34: 36350,
- 35: 36950,
- 36: 37550,
- 37: 37750,
- 38: 38250,
- 39: 38650,
- 40: 39650,
- 41: 41590,
- 42: 45590,
- 66: 66436
- }
-
- # Simulation config keywords contained in the test name
- PARAM_CA = 'ca'
-
- # Test config keywords
- KEY_FREQ_BANDS = "freq_bands"
-
- def __init__(self, simulator, log, dut, test_config, calibration_table):
- """ Initializes the simulator for LTE simulation with carrier
- aggregation.
-
- Loads a simple LTE simulation enviroment with 5 basestations.
-
- Args:
- simulator: the cellular instrument controller
- log: a logger handle
- 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.
-
- """
-
- super().__init__(simulator, log, dut, test_config, calibration_table)
-
- # Create a configuration object for each base station and copy initial
- # settings from the PCC base station.
- self.bts_configs = [self.primary_config]
-
- for bts_index in range(1, self.simulator.LTE_MAX_CARRIERS):
- new_config = self.BtsConfig()
- new_config.incorporate(self.primary_config)
- self.simulator.configure_bts(new_config, bts_index)
- self.bts_configs.append(new_config)
-
- # Get LTE CA frequency bands setting from the test configuration
- if self.KEY_FREQ_BANDS not in test_config:
- self.log.warning("The key '{}' is not set in the config file. "
- "Setting to null by default.".format(
- self.KEY_FREQ_BANDS))
-
- self.freq_bands = test_config.get(self.KEY_FREQ_BANDS, True)
-
- def setup_simulator(self):
- """ Do initial configuration in the simulator. """
- self.simulator.setup_lte_ca_scenario()
-
- def parse_parameters(self, parameters):
- """ Configs an LTE simulation with CA using a list of parameters.
-
- Args:
- parameters: list of parameters
- """
-
- # Get the CA band configuration
-
- values = self.consume_parameter(parameters, self.PARAM_CA, 1)
-
- if not values:
- raise ValueError(
- "The test name needs to include parameter '{}' followed by "
- "the CA configuration. For example: ca_3c7c28a".format(
- self.PARAM_CA))
-
- # Carrier aggregation configurations are indicated with the band numbers
- # followed by the CA classes in a single string. For example, for 5 CA
- # using 3C 7C and 28A the parameter value should be 3c7c28a.
- ca_configs = re.findall(r'(\d+[abcABC])', values[1])
-
- if not ca_configs:
- raise ValueError(
- "The CA configuration has to be indicated with one string as "
- "in the following example: ca_3c7c28a".format(self.PARAM_CA))
-
- # Apply the carrier aggregation combination
- self.simulator.set_ca_combination(ca_configs)
-
- # Save the bands to the bts config objects
- bts_index = 0
- for ca in ca_configs:
- ca_class = ca[-1]
- band = ca[:-1]
-
- self.bts_configs[bts_index].band = band
- bts_index += 1
-
- if ca_class.upper() == 'B' or ca_class.upper() == 'C':
- # Class B and C means two carriers with the same band
- self.bts_configs[bts_index].band = band
- bts_index += 1
-
- # Count the number of carriers in the CA combination
- self.num_carriers = 0
- for ca in ca_configs:
- ca_class = ca[-1]
- # Class C means that there are two contiguous carriers, while other
- # classes are a single one.
- if ca_class.upper() == 'C':
- self.num_carriers += 2
- else:
- self.num_carriers += 1
-
- # Create an array of configuration objects to set up the base stations.
- new_configs = [self.BtsConfig() for _ in range(self.num_carriers)]
-
- # Get the bw for each carrier
- # This is an optional parameter, by default the maximum bandwidth for
- # each band will be selected.
-
- values = self.consume_parameter(parameters, self.PARAM_BW,
- self.num_carriers)
-
- bts_index = 0
-
- for ca in ca_configs:
-
- band = int(ca[:-1])
- ca_class = ca[-1]
-
- if values:
- bw = int(values[1 + bts_index])
- else:
- bw = max(self.allowed_bandwidth_dictionary[band])
-
- new_configs[bts_index].bandwidth = bw
- bts_index += 1
-
- if ca_class.upper() == 'C':
-
- new_configs[bts_index].bandwidth = bw
-
- # Calculate the channel number for the second carrier to be
- # contiguous to the first one
- new_configs[bts_index].dl_channel = int(
- self.LOWEST_DL_CN_DICTIONARY[int(band)] + bw * 10 - 2)
-
- bts_index += 1
-
- # Get the TM for each carrier
- # This is an optional parameter, by the default value depends on the
- # MIMO mode for each carrier
-
- tm_values = self.consume_parameter(parameters, self.PARAM_TM,
- self.num_carriers)
-
- # Get the MIMO mode for each carrier
-
- mimo_values = self.consume_parameter(parameters, self.PARAM_MIMO,
- self.num_carriers)
-
- if not mimo_values:
- raise ValueError(
- "The test parameter '{}' has to be included in the "
- "test name followed by the MIMO mode for each "
- "carrier separated by underscores.".format(self.PARAM_MIMO))
-
- if len(mimo_values) != self.num_carriers + 1:
- raise ValueError(
- "The test parameter '{}' has to be followed by "
- "a number of MIMO mode values equal to the number "
- "of carriers being used.".format(self.PARAM_MIMO))
-
- for bts_index in range(self.num_carriers):
-
- # Parse and set the requested MIMO mode
-
- for mimo_mode in LteSimulation.MimoMode:
- if mimo_values[bts_index + 1] == mimo_mode.value:
- requested_mimo = mimo_mode
- break
- else:
- raise ValueError(
- "The mimo mode must be one of %s." %
- {elem.value
- for elem in LteSimulation.MimoMode})
-
- if (requested_mimo == LteSimulation.MimoMode.MIMO_4x4
- and not self.simulator.LTE_SUPPORTS_4X4_MIMO):
- raise ValueError("The test requires 4x4 MIMO, but that is not "
- "supported by the MD8475A callbox.")
-
- new_configs[bts_index].mimo_mode = requested_mimo
-
- # Parse and set the requested TM
-
- if tm_values:
- for tm in LteSimulation.TransmissionMode:
- if tm_values[bts_index + 1] == tm.value[2:]:
- requested_tm = tm
- break
- else:
- raise ValueError(
- "The TM must be one of %s." %
- {elem.value
- for elem in LteSimulation.MimoMode})
- else:
- # Provide default values if the TM parameter is not set
- if requested_mimo == LteSimulation.MimoMode.MIMO_1x1:
- requested_tm = LteSimulation.TransmissionMode.TM1
- else:
- requested_tm = LteSimulation.TransmissionMode.TM3
-
- new_configs[bts_index].transmission_mode = requested_tm
-
- self.log.info("Cell {} will be set to {} and {} MIMO.".format(
- bts_index + 1, requested_tm.value, requested_mimo.value))
-
- # Get uplink power
-
- ul_power = self.get_uplink_power_from_parameters(parameters)
-
- # Power is not set on the callbox until after the simulation is
- # started. Saving this value in a variable for later
- self.sim_ul_power = ul_power
-
- # Get downlink power
-
- dl_power = self.get_downlink_power_from_parameters(parameters)
-
- # Power is not set on the callbox until after the simulation is
- # started. Saving this value in a variable for later
- self.sim_dl_power = dl_power
-
- # Setup scheduling mode
-
- values = self.consume_parameter(parameters, self.PARAM_SCHEDULING, 1)
-
- if not values:
- scheduling = LteSimulation.SchedulingMode.STATIC
- self.log.warning(
- "The test name does not include the '{}' parameter. Setting to "
- "{} by default.".format(scheduling.value,
- self.PARAM_SCHEDULING))
- else:
- for scheduling_mode in LteSimulation.SchedulingMode:
- if values[1].upper() == scheduling_mode.value:
- scheduling = scheduling_mode
- break
- else:
- raise ValueError(
- "The test name parameter '{}' has to be followed by one of "
- "{}.".format(
- self.PARAM_SCHEDULING,
- {elem.value
- for elem in LteSimulation.SchedulingMode}))
-
- for bts_index in range(self.num_carriers):
- new_configs[bts_index].scheduling_mode = scheduling
-
- if scheduling == LteSimulation.SchedulingMode.STATIC:
-
- values = self.consume_parameter(parameters, self.PARAM_PATTERN, 2)
-
- if not values:
- self.log.warning(
- "The '{}' parameter was not set, using 100% RBs for both "
- "DL and UL. To set the percentages of total RBs include "
- "the '{}' parameter followed by two ints separated by an "
- "underscore indicating downlink and uplink percentages.".
- format(self.PARAM_PATTERN, self.PARAM_PATTERN))
- dl_pattern = 100
- ul_pattern = 100
- else:
- dl_pattern = int(values[1])
- ul_pattern = int(values[2])
-
- if (dl_pattern, ul_pattern) not in [(0, 100), (100, 0),
- (100, 100)]:
- raise ValueError(
- "Only full RB allocation for DL or UL is supported in CA "
- "sims. The allowed combinations are 100/0, 0/100 and "
- "100/100.")
-
- for bts_index in range(self.num_carriers):
-
- # Look for a DL MCS configuration in the test parameters. If it
- # is not present, use a default value.
- dlmcs = self.consume_parameter(parameters, self.PARAM_DL_MCS,
- 1)
- if dlmcs:
- mcs_dl = int(dlmcs[1])
- else:
- self.log.warning(
- 'The test name does not include the {} parameter. '
- 'Setting to the max value by default'.format(
- self.PARAM_DL_MCS))
-
- if self.dl_256_qam and new_configs[
- bts_index].bandwidth == 1.4:
- mcs_dl = 26
- elif (not self.dl_256_qam
- and self.primary_config.tbs_pattern_on
- and new_configs[bts_index].bandwidth != 1.4):
- mcs_dl = 28
- else:
- mcs_dl = 27
-
- # Look for an UL MCS configuration in the test parameters. If it
- # is not present, use a default value.
- ulmcs = self.consume_parameter(parameters, self.PARAM_UL_MCS,
- 1)
- if ulmcs:
- mcs_ul = int(ulmcs[1])
- else:
- self.log.warning(
- 'The test name does not include the {} parameter. '
- 'Setting to the max value by default'.format(
- self.PARAM_UL_MCS))
-
- if self.ul_64_qam:
- mcs_ul = 28
- else:
- mcs_ul = 23
-
- dl_rbs, ul_rbs = self.allocation_percentages_to_rbs(
- new_configs[bts_index].bandwidth,
- new_configs[bts_index].transmission_mode, dl_pattern,
- ul_pattern)
-
- new_configs[bts_index].dl_rbs = dl_rbs
- new_configs[bts_index].ul_rbs = ul_rbs
- new_configs[bts_index].dl_mcs = mcs_dl
- new_configs[bts_index].ul_mcs = mcs_ul
-
- # Setup the base stations with the obtained configurations and then save
- # these parameters in the current configuration objects
- for bts_index in range(len(new_configs)):
- self.simulator.configure_bts(new_configs[bts_index], bts_index)
- self.bts_configs[bts_index].incorporate(new_configs[bts_index])
-
- # Now that the band is set, calibrate the link for the PCC if necessary
- self.load_pathloss_if_required()
-
- def maximum_downlink_throughput(self):
- """ Calculates maximum downlink throughput as the sum of all the active
- carriers.
- """
- return sum(
- self.bts_maximum_downlink_throughtput(self.bts_configs[bts_index])
- for bts_index in range(self.num_carriers))
-
- def start(self):
- """ Set the signal level for the secondary carriers, as the base class
- implementation of this method will only set up downlink power for the
- primary carrier component.
-
- After that, attaches the secondary carriers."""
-
- super().start()
-
- if self.sim_dl_power:
- self.log.info('Setting DL power for secondary carriers.')
-
- for bts_index in range(1, self.num_carriers):
- new_config = self.BtsConfig()
- new_config.output_power = self.calibrated_downlink_rx_power(
- self.bts_configs[bts_index], self.sim_dl_power)
- self.simulator.configure_bts(new_config, bts_index)
- self.bts_configs[bts_index].incorporate(new_config)
-
- self.simulator.lte_attach_secondary_carriers(self.freq_bands)
diff --git a/acts/framework/acts/controllers/cellular_lib/LteCellConfig.py b/acts/framework/acts/controllers/cellular_lib/LteCellConfig.py
new file mode 100644
index 0000000..34b982d
--- /dev/null
+++ b/acts/framework/acts/controllers/cellular_lib/LteCellConfig.py
@@ -0,0 +1,485 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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.controllers.cellular_lib.BaseCellConfig as base_cell
+import acts.controllers.cellular_lib.LteSimulation as lte_sim
+import math
+
+
+class LteCellConfig(base_cell.BaseCellConfig):
+ """ Extension of the BaseBtsConfig to implement parameters that are
+ exclusive to LTE.
+
+ Attributes:
+ band: an integer indicating the required band number.
+ dlul_config: an integer indicating the TDD config number.
+ ssf_config: an integer indicating the Special Sub-Frame config.
+ bandwidth: a float indicating the required channel bandwidth.
+ mimo_mode: an instance of LteSimulation.MimoMode indicating the
+ required MIMO mode for the downlink signal.
+ transmission_mode: an instance of LteSimulation.TransmissionMode
+ indicating the required TM.
+ scheduling_mode: an instance of LteSimulation.SchedulingMode
+ indicating whether to use Static or Dynamic scheduling.
+ dl_rbs: an integer indicating the number of downlink RBs
+ ul_rbs: an integer indicating the number of uplink RBs
+ dl_mcs: an integer indicating the MCS for the downlink signal
+ ul_mcs: an integer indicating the MCS for the uplink signal
+ dl_256_qam_enabled: a boolean indicating if 256 QAM is enabled
+ ul_64_qam_enabled: a boolean indicating if 256 QAM is enabled
+ mac_padding: a boolean indicating whether RBs should be allocated
+ when there is no user data in static scheduling
+ dl_channel: an integer indicating the downlink channel number
+ cfi: an integer indicating the Control Format Indicator
+ paging_cycle: an integer indicating the paging cycle duration in
+ milliseconds
+ phich: a string indicating the PHICH group size parameter
+ drx_connected_mode: a boolean indicating whether cDRX mode is
+ on or off
+ drx_on_duration_timer: number of PDCCH subframes representing
+ DRX on duration
+ drx_inactivity_timer: number of PDCCH subframes to wait before
+ entering DRX mode
+ drx_retransmission_timer: number of consecutive PDCCH subframes
+ to wait for retransmission
+ drx_long_cycle: number of subframes representing one long DRX cycle.
+ One cycle consists of DRX sleep + DRX on duration
+ drx_long_cycle_offset: number representing offset in range
+ 0 to drx_long_cycle - 1
+ """
+ PARAM_FRAME_CONFIG = "tddconfig"
+ PARAM_BW = "bw"
+ PARAM_SCHEDULING = "scheduling"
+ PARAM_SCHEDULING_STATIC = "static"
+ PARAM_SCHEDULING_DYNAMIC = "dynamic"
+ PARAM_PATTERN = "pattern"
+ PARAM_TM = "tm"
+ PARAM_BAND = "band"
+ PARAM_MIMO = "mimo"
+ PARAM_DL_MCS = 'dlmcs'
+ PARAM_UL_MCS = 'ulmcs'
+ PARAM_SSF = 'ssf'
+ PARAM_CFI = 'cfi'
+ PARAM_PAGING = 'paging'
+ PARAM_PHICH = 'phich'
+ PARAM_DRX = 'drx'
+ PARAM_PADDING = 'mac_padding'
+ PARAM_DL_256_QAM_ENABLED = "256_qam_dl_enabled"
+ PARAM_UL_64_QAM_ENABLED = "64_qam_ul_enabled"
+ PARAM_DL_EARFCN = 'dl_earfcn'
+
+ def __init__(self, log):
+ """ Initialize the base station config by setting all its
+ parameters to None.
+ Args:
+ log: logger object.
+ """
+ super().__init__(log)
+ self.band = None
+ self.dlul_config = None
+ self.ssf_config = None
+ self.bandwidth = None
+ self.mimo_mode = None
+ self.transmission_mode = None
+ self.scheduling_mode = None
+ self.dl_rbs = None
+ self.ul_rbs = None
+ self.dl_mcs = None
+ self.ul_mcs = None
+ self.dl_256_qam_enabled = None
+ self.ul_64_qam_enabled = None
+ self.mac_padding = None
+ self.dl_channel = None
+ self.cfi = None
+ self.paging_cycle = None
+ self.phich = None
+ self.drx_connected_mode = None
+ self.drx_on_duration_timer = None
+ self.drx_inactivity_timer = None
+ self.drx_retransmission_timer = None
+ self.drx_long_cycle = None
+ self.drx_long_cycle_offset = None
+
+ def configure(self, parameters):
+ """ Configures an LTE cell using a dictionary of parameters.
+
+ Args:
+ parameters: a configuration dictionary
+ """
+ # Setup band
+ if self.PARAM_BAND not in parameters:
+ raise ValueError(
+ "The configuration dictionary must include a key '{}' with "
+ "the required band number.".format(self.PARAM_BAND))
+
+ self.band = parameters[self.PARAM_BAND]
+
+ if self.PARAM_DL_EARFCN not in parameters:
+ band = int(self.band)
+ channel = int(lte_sim.LteSimulation.LOWEST_DL_CN_DICTIONARY[band] +
+ lte_sim.LteSimulation.LOWEST_DL_CN_DICTIONARY[band +
+ 1]) / 2
+ self.log.warning(
+ "Key '{}' was not set. Using center band channel {} by default."
+ .format(self.PARAM_DL_EARFCN, channel))
+ self.dl_channel = channel
+ else:
+ self.dl_channel = parameters[self.PARAM_DL_EARFCN]
+
+ # Set TDD-only configs
+ if self.get_duplex_mode() == lte_sim.DuplexMode.TDD:
+
+ # Sub-frame DL/UL config
+ if self.PARAM_FRAME_CONFIG not in parameters:
+ raise ValueError("When a TDD band is selected the frame "
+ "structure has to be indicated with the '{}' "
+ "key with a value from 0 to 6.".format(
+ self.PARAM_FRAME_CONFIG))
+
+ self.dlul_config = int(parameters[self.PARAM_FRAME_CONFIG])
+
+ # Special Sub-Frame configuration
+ if self.PARAM_SSF not in parameters:
+ self.log.warning(
+ 'The {} parameter was not provided. Setting '
+ 'Special Sub-Frame config to 6 by default.'.format(
+ self.PARAM_SSF))
+ self.ssf_config = 6
+ else:
+ self.ssf_config = int(parameters[self.PARAM_SSF])
+
+ # Setup bandwidth
+ if self.PARAM_BW not in parameters:
+ raise ValueError(
+ "The config dictionary must include parameter {} with an "
+ "int value (to indicate 1.4 MHz use 14).".format(
+ self.PARAM_BW))
+
+ bw = float(parameters[self.PARAM_BW])
+
+ if abs(bw - 14) < 0.00000000001:
+ bw = 1.4
+
+ self.bandwidth = bw
+
+ # Setup mimo mode
+ if self.PARAM_MIMO not in parameters:
+ raise ValueError(
+ "The config dictionary must include parameter '{}' with the "
+ "mimo mode.".format(self.PARAM_MIMO))
+
+ for mimo_mode in lte_sim.MimoMode:
+ if parameters[self.PARAM_MIMO] == mimo_mode.value:
+ self.mimo_mode = mimo_mode
+ break
+ else:
+ raise ValueError("The value of {} must be one of the following:"
+ "1x1, 2x2 or 4x4.".format(self.PARAM_MIMO))
+
+ # Setup transmission mode
+ if self.PARAM_TM not in parameters:
+ raise ValueError(
+ "The config dictionary must include key {} with an "
+ "int value from 1 to 4 indicating transmission mode.".format(
+ self.PARAM_TM))
+
+ for tm in lte_sim.TransmissionMode:
+ if parameters[self.PARAM_TM] == tm.value[2:]:
+ self.transmission_mode = tm
+ break
+ else:
+ raise ValueError(
+ "The {} key must have one of the following values:"
+ "1, 2, 3, 4, 7, 8 or 9.".format(self.PARAM_TM))
+
+ # Setup scheduling mode
+ if self.PARAM_SCHEDULING not in parameters:
+ self.scheduling_mode = lte_sim.SchedulingMode.STATIC
+ self.log.warning(
+ "The test config does not include the '{}' key. Setting to "
+ "static by default.".format(self.PARAM_SCHEDULING))
+ elif parameters[
+ self.PARAM_SCHEDULING] == self.PARAM_SCHEDULING_DYNAMIC:
+ self.scheduling_mode = lte_sim.SchedulingMode.DYNAMIC
+ elif parameters[self.PARAM_SCHEDULING] == self.PARAM_SCHEDULING_STATIC:
+ self.scheduling_mode = lte_sim.SchedulingMode.STATIC
+ else:
+ raise ValueError("Key '{}' must have a value of "
+ "'dynamic' or 'static'.".format(
+ self.PARAM_SCHEDULING))
+
+ if self.scheduling_mode == lte_sim.SchedulingMode.STATIC:
+
+ if self.PARAM_PADDING not in parameters:
+ self.log.warning(
+ "The '{}' parameter was not set. Enabling MAC padding by "
+ "default.".format(self.PARAM_PADDING))
+ self.mac_padding = True
+ else:
+ self.mac_padding = parameters[self.PARAM_PADDING]
+
+ if self.PARAM_PATTERN not in parameters:
+ self.log.warning(
+ "The '{}' parameter was not set, using 100% RBs for both "
+ "DL and UL. To set the percentages of total RBs include "
+ "the '{}' key with a list of two ints indicating downlink "
+ "and uplink percentages.".format(self.PARAM_PATTERN,
+ self.PARAM_PATTERN))
+ dl_pattern = 100
+ ul_pattern = 100
+ else:
+ dl_pattern = int(parameters[self.PARAM_PATTERN][0])
+ ul_pattern = int(parameters[self.PARAM_PATTERN][1])
+
+ if not (0 <= dl_pattern <= 100 and 0 <= ul_pattern <= 100):
+ raise ValueError(
+ "The scheduling pattern parameters need to be two "
+ "positive numbers between 0 and 100.")
+
+ self.dl_rbs, self.ul_rbs = (self.allocation_percentages_to_rbs(
+ dl_pattern, ul_pattern))
+
+ # Check if 256 QAM is enabled for DL MCS
+ if self.PARAM_DL_256_QAM_ENABLED not in parameters:
+ self.log.warning("The key '{}' is not set in the test config. "
+ "Setting to false by default.".format(
+ self.PARAM_DL_256_QAM_ENABLED))
+
+ self.dl_256_qam_enabled = parameters.get(
+ self.PARAM_DL_256_QAM_ENABLED, False)
+
+ # Look for a DL MCS configuration in the test parameters. If it is
+ # not present, use a default value.
+ if self.PARAM_DL_MCS in parameters:
+ self.dl_mcs = int(parameters[self.PARAM_DL_MCS])
+ else:
+ self.log.warning(
+ 'The test config does not include the {} key. Setting '
+ 'to the max value by default'.format(self.PARAM_DL_MCS))
+ if self.dl_256_qam_enabled and self.bandwidth == 1.4:
+ self.dl_mcs = 26
+ elif (not self.dl_256_qam_enabled and self.mac_padding
+ and self.bandwidth != 1.4):
+ self.dl_mcs = 28
+ else:
+ self.dl_mcs = 27
+
+ # Check if 64 QAM is enabled for UL MCS
+ if self.PARAM_UL_64_QAM_ENABLED not in parameters:
+ self.log.warning("The key '{}' is not set in the config file. "
+ "Setting to false by default.".format(
+ self.PARAM_UL_64_QAM_ENABLED))
+
+ self.ul_64_qam_enabled = parameters.get(
+ self.PARAM_UL_64_QAM_ENABLED, False)
+
+ # Look for an UL MCS configuration in the test parameters. If it is
+ # not present, use a default value.
+ if self.PARAM_UL_MCS in parameters:
+ self.ul_mcs = int(parameters[self.PARAM_UL_MCS])
+ else:
+ self.log.warning(
+ 'The test config does not include the {} key. Setting '
+ 'to the max value by default'.format(self.PARAM_UL_MCS))
+ if self.ul_64_qam_enabled:
+ self.ul_mcs = 28
+ else:
+ self.ul_mcs = 23
+
+ # Configure the simulation for DRX mode
+ if self.PARAM_DRX in parameters and len(
+ parameters[self.PARAM_DRX]) == 5:
+ self.drx_connected_mode = True
+ self.drx_on_duration_timer = parameters[self.PARAM_DRX][0]
+ self.drx_inactivity_timer = parameters[self.PARAM_DRX][1]
+ self.drx_retransmission_timer = parameters[self.PARAM_DRX][2]
+ self.drx_long_cycle = parameters[self.PARAM_DRX][3]
+ try:
+ long_cycle = int(parameters[self.PARAM_DRX][3])
+ long_cycle_offset = int(parameters[self.PARAM_DRX][4])
+ if long_cycle_offset in range(0, long_cycle):
+ self.drx_long_cycle_offset = long_cycle_offset
+ else:
+ self.log.error(
+ ("The cDRX long cycle offset must be in the "
+ "range 0 to (long cycle - 1). Setting "
+ "long cycle offset to 0"))
+ self.drx_long_cycle_offset = 0
+
+ except ValueError:
+ self.log.error(("cDRX long cycle and long cycle offset "
+ "must be integers. Disabling cDRX mode."))
+ self.drx_connected_mode = False
+ else:
+ self.log.warning(
+ ("DRX mode was not configured properly. "
+ "Please provide a list with the following values: "
+ "1) DRX on duration timer "
+ "2) Inactivity timer "
+ "3) Retransmission timer "
+ "4) Long DRX cycle duration "
+ "5) Long DRX cycle offset "
+ "Example: [2, 6, 16, 20, 0]."))
+
+ # Channel Control Indicator
+ if self.PARAM_CFI not in parameters:
+ self.log.warning('The {} parameter was not provided. Setting '
+ 'CFI to BESTEFFORT.'.format(self.PARAM_CFI))
+ self.cfi = 'BESTEFFORT'
+ else:
+ self.cfi = parameters[self.PARAM_CFI]
+
+ # PHICH group size
+ if self.PARAM_PHICH not in parameters:
+ self.log.warning('The {} parameter was not provided. Setting '
+ 'PHICH group size to 1 by default.'.format(
+ self.PARAM_PHICH))
+ self.phich = '1'
+ else:
+ if parameters[self.PARAM_PHICH] == '16':
+ self.phich = '1/6'
+ elif parameters[self.PARAM_PHICH] == '12':
+ self.phich = '1/2'
+ elif parameters[self.PARAM_PHICH] in ['1/6', '1/2', '1', '2']:
+ self.phich = parameters[self.PARAM_PHICH]
+ else:
+ raise ValueError('The {} parameter can only be followed by 1,'
+ '2, 1/2 (or 12) and 1/6 (or 16).'.format(
+ self.PARAM_PHICH))
+
+ # Paging cycle duration
+ if self.PARAM_PAGING not in parameters:
+ self.log.warning('The {} parameter was not provided. Setting '
+ 'paging cycle duration to 1280 ms by '
+ 'default.'.format(self.PARAM_PAGING))
+ self.paging_cycle = 1280
+ else:
+ try:
+ self.paging_cycle = int(parameters[self.PARAM_PAGING])
+ except ValueError:
+ raise ValueError(
+ 'The {} key has to be followed by the paging cycle '
+ 'duration in milliseconds.'.format(self.PARAM_PAGING))
+
+ def get_duplex_mode(self):
+ """ Determines if the cell uses FDD or TDD duplex mode
+
+ Returns:
+ an variable of class DuplexMode indicating if band is FDD or TDD
+ """
+ if 33 <= int(self.band) <= 46:
+ return lte_sim.DuplexMode.TDD
+ else:
+ return lte_sim.DuplexMode.FDD
+
+ def allocation_percentages_to_rbs(self, dl, ul):
+ """ Converts usage percentages to number of DL/UL RBs
+
+ Because not any number of DL/UL RBs can be obtained for a certain
+ bandwidth, this function calculates the number of RBs that most
+ closely matches the desired DL/UL percentages.
+
+ Args:
+ dl: desired percentage of downlink RBs
+ ul: desired percentage of uplink RBs
+ Returns:
+ a tuple indicating the number of downlink and uplink RBs
+ """
+
+ # Validate the arguments
+ if (not 0 <= dl <= 100) or (not 0 <= ul <= 100):
+ raise ValueError("The percentage of DL and UL RBs have to be two "
+ "positive between 0 and 100.")
+
+ # Get min and max values from tables
+ max_rbs = lte_sim.TOTAL_RBS_DICTIONARY[self.bandwidth]
+ min_dl_rbs = lte_sim.MIN_DL_RBS_DICTIONARY[self.bandwidth]
+ min_ul_rbs = lte_sim.MIN_UL_RBS_DICTIONARY[self.bandwidth]
+
+ def percentage_to_amount(min_val, max_val, percentage):
+ """ Returns the integer between min_val and max_val that is closest
+ to percentage/100*max_val
+ """
+
+ # Calculate the value that corresponds to the required percentage.
+ closest_int = round(max_val * percentage / 100)
+ # Cannot be less than min_val
+ closest_int = max(closest_int, min_val)
+ # RBs cannot be more than max_rbs
+ closest_int = min(closest_int, max_val)
+
+ return closest_int
+
+ # Calculate the number of DL RBs
+
+ # Get the number of DL RBs that corresponds to
+ # the required percentage.
+ desired_dl_rbs = percentage_to_amount(min_val=min_dl_rbs,
+ max_val=max_rbs,
+ percentage=dl)
+
+ if self.transmission_mode == lte_sim.TransmissionMode.TM3 or \
+ self.transmission_mode == lte_sim.TransmissionMode.TM4:
+
+ # For TM3 and TM4 the number of DL RBs needs to be max_rbs or a
+ # multiple of the RBG size
+
+ if desired_dl_rbs == max_rbs:
+ dl_rbs = max_rbs
+ else:
+ dl_rbs = (math.ceil(
+ desired_dl_rbs / lte_sim.RBG_DICTIONARY[self.bandwidth]) *
+ lte_sim.RBG_DICTIONARY[self.bandwidth])
+
+ else:
+ # The other TMs allow any number of RBs between 1 and max_rbs
+ dl_rbs = desired_dl_rbs
+
+ # Calculate the number of UL RBs
+
+ # Get the number of UL RBs that corresponds
+ # to the required percentage
+ desired_ul_rbs = percentage_to_amount(min_val=min_ul_rbs,
+ max_val=max_rbs,
+ percentage=ul)
+
+ # Create a list of all possible UL RBs assignment
+ # The standard allows any number that can be written as
+ # 2**a * 3**b * 5**c for any combination of a, b and c.
+
+ def pow_range(max_value, base):
+ """ Returns a range of all possible powers of base under
+ the given max_value.
+ """
+ return range(int(math.ceil(math.log(max_value, base))))
+
+ possible_ul_rbs = [
+ 2 ** a * 3 ** b * 5 ** c for a in pow_range(max_rbs, 2)
+ for b in pow_range(max_rbs, 3)
+ for c in pow_range(max_rbs, 5)
+ if 2 ** a * 3 ** b * 5 ** c <= max_rbs] # yapf: disable
+
+ # Find the value in the list that is closest to desired_ul_rbs
+ differences = [abs(rbs - desired_ul_rbs) for rbs in possible_ul_rbs]
+ ul_rbs = possible_ul_rbs[differences.index(min(differences))]
+
+ # Report what are the obtained RB percentages
+ self.log.info("Requested a {}% / {}% RB allocation. Closest possible "
+ "percentages are {}% / {}%.".format(
+ dl, ul, round(100 * dl_rbs / max_rbs),
+ round(100 * ul_rbs / max_rbs)))
+
+ return dl_rbs, ul_rbs
diff --git a/acts/framework/acts/controllers/cellular_lib/LteSimulation.py b/acts/framework/acts/controllers/cellular_lib/LteSimulation.py
index 9627e9f..846c9e4 100644
--- a/acts/framework/acts/controllers/cellular_lib/LteSimulation.py
+++ b/acts/framework/acts/controllers/cellular_lib/LteSimulation.py
@@ -13,11 +13,12 @@
# 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 time
from enum import Enum
from acts.controllers.cellular_lib.BaseSimulation import BaseSimulation
+from acts.controllers.cellular_lib.LteCellConfig import LteCellConfig
+from acts.controllers.cellular_lib.NrCellConfig import NrCellConfig
from acts.controllers.cellular_lib import BaseCellularDut
@@ -50,6 +51,7 @@
FDD = "FDD"
TDD = "TDD"
+
class ModulationType(Enum):
"""DL/UL Modulation order."""
QPSK = 'QPSK'
@@ -58,34 +60,26 @@
Q256 = '256QAM'
+# Bandwidth [MHz] to RB group size
+RBG_DICTIONARY = {20: 4, 15: 4, 10: 3, 5: 2, 3: 2, 1.4: 1}
+
+# Bandwidth [MHz] to total RBs mapping
+TOTAL_RBS_DICTIONARY = {20: 100, 15: 75, 10: 50, 5: 25, 3: 15, 1.4: 6}
+
+# Bandwidth [MHz] to minimum number of DL RBs that can be assigned to a UE
+MIN_DL_RBS_DICTIONARY = {20: 16, 15: 12, 10: 9, 5: 4, 3: 4, 1.4: 2}
+
+# Bandwidth [MHz] to minimum number of UL RBs that can be assigned to a UE
+MIN_UL_RBS_DICTIONARY = {20: 8, 15: 6, 10: 4, 5: 2, 3: 2, 1.4: 1}
+
+
class LteSimulation(BaseSimulation):
""" Single-carrier LTE simulation. """
-
- # Simulation config keywords contained in the test name
- PARAM_FRAME_CONFIG = "tddconfig"
- PARAM_BW = "bw"
- PARAM_SCHEDULING = "scheduling"
- PARAM_SCHEDULING_STATIC = "static"
- PARAM_SCHEDULING_DYNAMIC = "dynamic"
- PARAM_PATTERN = "pattern"
- PARAM_TM = "tm"
- PARAM_UL_PW = 'pul'
- PARAM_DL_PW = 'pdl'
- PARAM_BAND = "band"
- PARAM_MIMO = "mimo"
- PARAM_DL_MCS = 'dlmcs'
- PARAM_UL_MCS = 'ulmcs'
- PARAM_SSF = 'ssf'
- PARAM_CFI = 'cfi'
- PARAM_PAGING = 'paging'
- PARAM_PHICH = 'phich'
- PARAM_RRC_STATUS_CHANGE_TIMER = "rrcstatuschangetimer"
- PARAM_DRX = 'drx'
-
# Test config keywords
- KEY_TBS_PATTERN = "tbs_pattern_on"
- KEY_DL_256_QAM = "256_qam_dl"
- KEY_UL_64_QAM = "64_qam_ul"
+ KEY_FREQ_BANDS = "freq_bands"
+
+ # Cell param keywords
+ PARAM_RRC_STATUS_CHANGE_TIMER = "rrcstatuschangetimer"
# Units in which signal level is defined in DOWNLINK_SIGNAL_LEVEL_DICTIONARY
DOWNLINK_SIGNAL_LEVEL_UNITS = "RSRP"
@@ -96,7 +90,8 @@
'excellent': -75,
'high': -110,
'medium': -115,
- 'weak': -120
+ 'weak': -120,
+ 'disconnected': -170
}
# Transmitted output power for the phone (dBm)
@@ -107,18 +102,6 @@
'low': -20
}
- # Bandwidth [MHz] to total RBs mapping
- total_rbs_dictionary = {20: 100, 15: 75, 10: 50, 5: 25, 3: 15, 1.4: 6}
-
- # Bandwidth [MHz] to RB group size
- rbg_dictionary = {20: 4, 15: 4, 10: 3, 5: 2, 3: 2, 1.4: 1}
-
- # Bandwidth [MHz] to minimum number of DL RBs that can be assigned to a UE
- min_dl_rbs_dictionary = {20: 16, 15: 12, 10: 9, 5: 4, 3: 4, 1.4: 2}
-
- # Bandwidth [MHz] to minimum number of UL RBs that can be assigned to a UE
- min_ul_rbs_dictionary = {20: 8, 15: 6, 10: 4, 5: 2, 3: 2, 1.4: 1}
-
# Allowed bandwidth for each band.
allowed_bandwidth_dictionary = {
1: [5, 10, 15, 20],
@@ -185,6 +168,52 @@
255: [20]
}
+ # Dictionary of lower DL channel number bound for each band.
+ LOWEST_DL_CN_DICTIONARY = {
+ 1: 0,
+ 2: 600,
+ 3: 1200,
+ 4: 1950,
+ 5: 2400,
+ 6: 2650,
+ 7: 2750,
+ 8: 3450,
+ 9: 3800,
+ 10: 4150,
+ 11: 4750,
+ 12: 5010,
+ 13: 5180,
+ 14: 5280,
+ 17: 5730,
+ 18: 5850,
+ 19: 6000,
+ 20: 6150,
+ 21: 6450,
+ 22: 6600,
+ 23: 7500,
+ 24: 7700,
+ 25: 8040,
+ 26: 8690,
+ 27: 9040,
+ 28: 9210,
+ 29: 9660,
+ 30: 9770,
+ 31: 9870,
+ 32: 9920,
+ 33: 36000,
+ 34: 36200,
+ 35: 36350,
+ 36: 36950,
+ 37: 37550,
+ 38: 37750,
+ 39: 38250,
+ 40: 38650,
+ 41: 39650,
+ 42: 41590,
+ 43: 45590,
+ 66: 66436
+ }
+
# Peak throughput lookup tables for each TDD subframe
# configuration and bandwidth
# yapf: disable
@@ -372,90 +401,18 @@
# Peak throughput lookup table dictionary
tdd_config_tput_lut_dict = {
'TDD_CONFIG1':
- tdd_config1_tput_lut, # DL 256QAM, UL 64QAM & TBS turned OFF
+ tdd_config1_tput_lut, # DL 256QAM, UL 64QAM & MAC padding turned OFF
'TDD_CONFIG2':
- tdd_config2_tput_lut, # DL 256QAM, UL 64 QAM turned ON & TBS OFF
+ tdd_config2_tput_lut, # DL 256QAM, UL 64 QAM ON & MAC padding OFF
'TDD_CONFIG3':
- tdd_config3_tput_lut, # DL 256QAM, UL 64QAM & TBS turned ON
+ tdd_config3_tput_lut, # DL 256QAM, UL 64QAM & MAC padding ON
'TDD_CONFIG4':
- tdd_config4_tput_lut # DL 256QAM, UL 64 QAM turned OFF & TBS ON
+ tdd_config4_tput_lut # DL 256QAM, UL 64 QAM OFF & MAC padding ON
}
- class BtsConfig(BaseSimulation.BtsConfig):
- """ Extension of the BaseBtsConfig to implement parameters that are
- exclusive to LTE.
-
- Attributes:
- band: an integer indicating the required band number.
- dlul_config: an integer indicating the TDD config number.
- ssf_config: an integer indicating the Special Sub-Frame config.
- bandwidth: a float indicating the required channel bandwidth.
- mimo_mode: an instance of LteSimulation.MimoMode indicating the
- required MIMO mode for the downlink signal.
- transmission_mode: an instance of LteSimulation.TransmissionMode
- indicating the required TM.
- scheduling_mode: an instance of LteSimulation.SchedulingMode
- indicating wether to use Static or Dynamic scheduling.
- dl_rbs: an integer indicating the number of downlink RBs
- ul_rbs: an integer indicating the number of uplink RBs
- dl_mcs: an integer indicating the MCS for the downlink signal
- ul_mcs: an integer indicating the MCS for the uplink signal
- dl_modulation_order: a string indicating a DL modulation scheme
- ul_modulation_order: a string indicating an UL modulation scheme
- tbs_pattern_on: a boolean indicating whether full allocation mode
- should be used or not
- dl_channel: an integer indicating the downlink channel number
- cfi: an integer indicating the Control Format Indicator
- paging_cycle: an integer indicating the paging cycle duration in
- milliseconds
- phich: a string indicating the PHICH group size parameter
- drx_connected_mode: a boolean indicating whether cDRX mode is
- on or off
- drx_on_duration_timer: number of PDCCH subframes representing
- DRX on duration
- drx_inactivity_timer: number of PDCCH subframes to wait before
- entering DRX mode
- drx_retransmission_timer: number of consecutive PDCCH subframes
- to wait for retransmission
- drx_long_cycle: number of subframes representing one long DRX cycle.
- One cycle consists of DRX sleep + DRX on duration
- drx_long_cycle_offset: number representing offset in range
- 0 to drx_long_cycle - 1
- """
- def __init__(self):
- """ Initialize the base station config by setting all its
- parameters to None. """
- super().__init__()
- self.band = None
- self.dlul_config = None
- self.ssf_config = None
- self.bandwidth = None
- self.mimo_mode = None
- self.transmission_mode = None
- self.scheduling_mode = None
- self.dl_rbs = None
- self.ul_rbs = None
- self.dl_mcs = None
- self.ul_mcs = None
- self.dl_modulation_order = None
- self.ul_modulation_order = None
- self.tbs_pattern_on = None
- self.dl_channel = None
- self.cfi = None
- self.paging_cycle = None
- self.phich = None
- self.drx_connected_mode = None
- self.drx_on_duration_timer = None
- self.drx_inactivity_timer = None
- self.drx_retransmission_timer = None
- self.drx_long_cycle = None
- self.drx_long_cycle_offset = None
-
def __init__(self, simulator, log, dut, test_config, calibration_table):
""" Initializes the simulator for a single-carrier LTE simulation.
- Loads a simple LTE simulation enviroment with 1 basestation.
-
Args:
simulator: a cellular simulator controller
log: a logger handle
@@ -468,370 +425,111 @@
super().__init__(simulator, log, dut, test_config, calibration_table)
+ self.num_carriers = None
+
+ # Force device to LTE only so that it connects faster
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:
+ # Get LTE CA frequency bands setting from the test configuration
+ if self.KEY_FREQ_BANDS not in test_config:
self.log.warning("The key '{}' is not set in the config file. "
- "Setting to true by default.".format(
- self.KEY_TBS_PATTERN))
- self.primary_config.tbs_pattern_on = test_config.get(
- self.KEY_TBS_PATTERN, True)
+ "Setting to null by default.".format(
+ self.KEY_FREQ_BANDS))
- # Get the 256-QAM setting from the test configuration
- if self.KEY_DL_256_QAM not in test_config:
- self.log.warning("The key '{}' is not set in the config file. "
- "Setting to false by default.".format(
- self.KEY_DL_256_QAM))
-
- self.dl_256_qam = test_config.get(self.KEY_DL_256_QAM, False)
-
- if self.dl_256_qam:
- if not self.simulator.LTE_SUPPORTS_DL_256QAM:
- self.log.warning("The key '{}' is set to true but the "
- "simulator doesn't support that modulation "
- "order.".format(self.KEY_DL_256_QAM))
- self.dl_256_qam = False
- else:
- self.primary_config.dl_modulation_order = ModulationType.Q256
-
- else:
- self.log.warning('dl modulation 256QAM is not specified in config, '
- 'setting to default value 64QAM')
- self.primary_config.dl_modulation_order = ModulationType.Q64
- # Get the 64-QAM setting from the test configuration
- if self.KEY_UL_64_QAM not in test_config:
- self.log.warning("The key '{}' is not set in the config file. "
- "Setting to false by default.".format(
- self.KEY_UL_64_QAM))
-
- self.ul_64_qam = test_config.get(self.KEY_UL_64_QAM, False)
-
- if self.ul_64_qam:
- if not self.simulator.LTE_SUPPORTS_UL_64QAM:
- self.log.warning("The key '{}' is set to true but the "
- "simulator doesn't support that modulation "
- "order.".format(self.KEY_UL_64_QAM))
- self.ul_64_qam = False
- else:
- self.primary_config.ul_modulation_order = ModulationType.Q64
- else:
- self.log.warning('ul modulation 64QAM is not specified in config, '
- 'setting to default value 16QAM')
- self.primary_config.ul_modulation_order = ModulationType.Q16
-
- self.simulator.configure_bts(self.primary_config)
+ self.freq_bands = test_config.get(self.KEY_FREQ_BANDS, True)
def setup_simulator(self):
""" Do initial configuration in the simulator. """
self.simulator.setup_lte_scenario()
- def parse_parameters(self, parameters):
- """ Configs an LTE simulation using a list of parameters.
+ def configure(self, parameters):
+ """ Configures simulation using a dictionary of parameters.
- Calls the parent method first, then consumes parameters specific to LTE.
+ Processes LTE configuration parameters.
Args:
- parameters: list of parameters
+ parameters: a configuration dictionary if there is only one carrier,
+ a list if there are multiple cells.
"""
+ # If there is a single item, put in a list
+ if not isinstance(parameters, list):
+ parameters = [parameters]
- # Instantiate a new configuration object
- new_config = self.BtsConfig()
+ # Pass only PCC configs to BaseSimulation
+ super().configure(parameters[0])
- # Setup band
-
- values = self.consume_parameter(parameters, self.PARAM_BAND, 1)
-
- if not values:
- raise ValueError(
- "The test name needs to include parameter '{}' followed by "
- "the required band number.".format(self.PARAM_BAND))
-
- new_config.band = values[1]
-
- # Set TDD-only configs
- if self.get_duplex_mode(new_config.band) == DuplexMode.TDD:
-
- # Sub-frame DL/UL config
- values = self.consume_parameter(parameters,
- self.PARAM_FRAME_CONFIG, 1)
- if not values:
+ new_cell_list = []
+ for cell in parameters:
+ if LteCellConfig.PARAM_BAND not in cell:
raise ValueError(
- "When a TDD band is selected the frame "
- "structure has to be indicated with the '{}' "
- "parameter followed by a number from 0 to 6.".format(
- self.PARAM_FRAME_CONFIG))
+ "The configuration dictionary must include a key '{}' with "
+ "the required band number.".format(
+ LteCellConfig.PARAM_BAND))
- new_config.dlul_config = int(values[1])
+ band = cell[LteCellConfig.PARAM_BAND]
- # Special Sub-Frame configuration
- values = self.consume_parameter(parameters, self.PARAM_SSF, 1)
+ if isinstance(band, str) and not band.isdigit():
+ # If band starts with n then it is an NR band
+ if band[0] == 'n' and band[1:].isdigit():
+ # If the remaining string is only the band number, add
+ # the cell and continue
+ new_cell_list.append(cell)
- if not values:
- self.log.warning(
- 'The {} parameter was not provided. Setting '
- 'Special Sub-Frame config to 6 by default.'.format(
- self.PARAM_SSF))
- new_config.ssf_config = 6
- else:
- new_config.ssf_config = int(values[1])
+ ca_class = band[-1].upper()
+ band_num = band[:-1]
- # Setup bandwidth
-
- values = self.consume_parameter(parameters, self.PARAM_BW, 1)
-
- if not values:
- raise ValueError(
- "The test name needs to include parameter {} followed by an "
- "int value (to indicate 1.4 MHz use 14).".format(
- self.PARAM_BW))
-
- bw = float(values[1])
-
- if bw == 14:
- bw = 1.4
-
- new_config.bandwidth = bw
-
- # Setup mimo mode
-
- values = self.consume_parameter(parameters, self.PARAM_MIMO, 1)
-
- if not values:
- raise ValueError(
- "The test name needs to include parameter '{}' followed by the "
- "mimo mode.".format(self.PARAM_MIMO))
-
- for mimo_mode in MimoMode:
- if values[1] == mimo_mode.value:
- new_config.mimo_mode = mimo_mode
- break
- else:
- raise ValueError("The {} parameter needs to be followed by either "
- "1x1, 2x2 or 4x4.".format(self.PARAM_MIMO))
-
- if (new_config.mimo_mode == MimoMode.MIMO_4x4
- and not self.simulator.LTE_SUPPORTS_4X4_MIMO):
- raise ValueError("The test requires 4x4 MIMO, but that is not "
- "supported by the cellular simulator.")
-
- # Setup transmission mode
-
- values = self.consume_parameter(parameters, self.PARAM_TM, 1)
-
- if not values:
- raise ValueError(
- "The test name needs to include parameter {} followed by an "
- "int value from 1 to 4 indicating transmission mode.".format(
- self.PARAM_TM))
-
- for tm in TransmissionMode:
- if values[1] == tm.value[2:]:
- new_config.transmission_mode = tm
- break
- else:
- raise ValueError("The {} parameter needs to be followed by either "
- "TM1, TM2, TM3, TM4, TM7, TM8 or TM9.".format(
- self.PARAM_MIMO))
-
- # Setup scheduling mode
-
- values = self.consume_parameter(parameters, self.PARAM_SCHEDULING, 1)
-
- if not values:
- new_config.scheduling_mode = SchedulingMode.STATIC
- self.log.warning(
- "The test name does not include the '{}' parameter. Setting to "
- "static by default.".format(self.PARAM_SCHEDULING))
- elif values[1] == self.PARAM_SCHEDULING_DYNAMIC:
- new_config.scheduling_mode = SchedulingMode.DYNAMIC
- elif values[1] == self.PARAM_SCHEDULING_STATIC:
- new_config.scheduling_mode = SchedulingMode.STATIC
- else:
- raise ValueError(
- "The test name parameter '{}' has to be followed by either "
- "'dynamic' or 'static'.".format(self.PARAM_SCHEDULING))
-
- if new_config.scheduling_mode == SchedulingMode.STATIC:
-
- values = self.consume_parameter(parameters, self.PARAM_PATTERN, 2)
-
- if not values:
- self.log.warning(
- "The '{}' parameter was not set, using 100% RBs for both "
- "DL and UL. To set the percentages of total RBs include "
- "the '{}' parameter followed by two ints separated by an "
- "underscore indicating downlink and uplink percentages.".
- format(self.PARAM_PATTERN, self.PARAM_PATTERN))
- dl_pattern = 100
- ul_pattern = 100
- else:
- dl_pattern = int(values[1])
- ul_pattern = int(values[2])
-
- if not (0 <= dl_pattern <= 100 and 0 <= ul_pattern <= 100):
- raise ValueError(
- "The scheduling pattern parameters need to be two "
- "positive numbers between 0 and 100.")
-
- new_config.dl_rbs, new_config.ul_rbs = (
- self.allocation_percentages_to_rbs(
- new_config.bandwidth, new_config.transmission_mode,
- dl_pattern, ul_pattern))
-
- # Look for a DL MCS configuration in the test parameters. If it is
- # not present, use a default value.
- dlmcs = self.consume_parameter(parameters, self.PARAM_DL_MCS, 1)
-
- if dlmcs:
- new_config.dl_mcs = int(dlmcs[1])
- else:
- self.log.warning(
- 'The test name does not include the {} parameter. Setting '
- 'to the max value by default'.format(self.PARAM_DL_MCS))
- if self.dl_256_qam and new_config.bandwidth == 1.4:
- new_config.dl_mcs = 26
- elif (not self.dl_256_qam
- and self.primary_config.tbs_pattern_on
- and new_config.bandwidth != 1.4):
- new_config.dl_mcs = 28
+ if ca_class in ['A', 'C']:
+ # Remove the CA class label and add the cell
+ cell[LteCellConfig.PARAM_BAND] = band_num
+ new_cell_list.append(cell)
+ elif ca_class == 'B':
+ raise RuntimeError('Class B LTE CA not supported.')
else:
- new_config.dl_mcs = 27
+ raise ValueError('Invalid band value: ' + band)
- # Look for an UL MCS configuration in the test parameters. If it is
- # not present, use a default value.
- ulmcs = self.consume_parameter(parameters, self.PARAM_UL_MCS, 1)
-
- if ulmcs:
- new_config.ul_mcs = int(ulmcs[1])
+ # Class C means that there are two contiguous carriers
+ if ca_class == 'C':
+ new_cell_list.append(cell)
+ bw = int(cell[LteCellConfig.PARAM_BW])
+ dl_earfcn = LteCellConfig.PARAM_DL_EARFCN
+ new_cell_list[-1][dl_earfcn] = self.LOWEST_DL_CN_DICTIONARY[
+ int(band_num)] + bw * 10 - 2
else:
- self.log.warning(
- 'The test name does not include the {} parameter. Setting '
- 'to the max value by default'.format(self.PARAM_UL_MCS))
- if self.ul_64_qam:
- new_config.ul_mcs = 28
- else:
- new_config.ul_mcs = 23
+ # The band is just a number, so just add it to the list
+ new_cell_list.append(cell)
- # Configure the simulation for DRX mode
+ self.simulator.set_band_combination(
+ [c[LteCellConfig.PARAM_BAND] for c in new_cell_list])
- drx = self.consume_parameter(parameters, self.PARAM_DRX, 5)
+ self.num_carriers = len(new_cell_list)
- if drx and len(drx) == 6:
- new_config.drx_connected_mode = True
- new_config.drx_on_duration_timer = drx[1]
- new_config.drx_inactivity_timer = drx[2]
- new_config.drx_retransmission_timer = drx[3]
- new_config.drx_long_cycle = drx[4]
- try:
- long_cycle = int(drx[4])
- long_cycle_offset = int(drx[5])
- if long_cycle_offset in range(0, long_cycle):
- new_config.drx_long_cycle_offset = long_cycle_offset
- else:
- self.log.error(("The cDRX long cycle offset must be in the "
- "range 0 to (long cycle - 1). Setting "
- "long cycle offset to 0"))
- new_config.drx_long_cycle_offset = 0
-
- except ValueError:
- self.log.error(("cDRX long cycle and long cycle offset "
- "must be integers. Disabling cDRX mode."))
- new_config.drx_connected_mode = False
- else:
- self.log.warning(("DRX mode was not configured properly. "
- "Please provide the following 5 values: "
- "1) DRX on duration timer "
- "2) Inactivity timer "
- "3) Retransmission timer "
- "4) Long DRX cycle duration "
- "5) Long DRX cycle offset "
- "Example: drx_2_6_16_20_0"))
-
- # Setup LTE RRC status change function and timer for LTE idle test case
- values = self.consume_parameter(parameters,
- self.PARAM_RRC_STATUS_CHANGE_TIMER, 1)
- if not values:
- self.log.info(
- "The test name does not include the '{}' parameter. Disabled "
- "by default.".format(self.PARAM_RRC_STATUS_CHANGE_TIMER))
- self.simulator.set_lte_rrc_state_change_timer(False)
- else:
- timer = int(values[1])
- self.simulator.set_lte_rrc_state_change_timer(True, timer)
- self.rrc_sc_timer = timer
-
- # Channel Control Indicator
- values = self.consume_parameter(parameters, self.PARAM_CFI, 1)
-
- if not values:
- self.log.warning('The {} parameter was not provided. Setting '
- 'CFI to BESTEFFORT.'.format(self.PARAM_CFI))
- new_config.cfi = 'BESTEFFORT'
- else:
- new_config.cfi = values[1]
-
- # PHICH group size
- values = self.consume_parameter(parameters, self.PARAM_PHICH, 1)
-
- if not values:
- self.log.warning('The {} parameter was not provided. Setting '
- 'PHICH group size to 1 by default.'.format(
- self.PARAM_PHICH))
- new_config.phich = '1'
- else:
- if values[1] == '16':
- new_config.phich = '1/6'
- elif values[1] == '12':
- new_config.phich = '1/2'
- elif values[1] in ['1/6', '1/2', '1', '2']:
- new_config.phich = values[1]
+ # Setup the base stations with the obtain configuration
+ self.cell_configs = []
+ for i in range(self.num_carriers):
+ band = new_cell_list[i][LteCellConfig.PARAM_BAND]
+ if isinstance(band, str) and band[0] == 'n':
+ self.cell_configs.append(NrCellConfig(self.log))
else:
- raise ValueError('The {} parameter can only be followed by 1,'
- '2, 1/2 (or 12) and 1/6 (or 16).'.format(
- self.PARAM_PHICH))
-
- # Paging cycle duration
- values = self.consume_parameter(parameters, self.PARAM_PAGING, 1)
-
- if not values:
- self.log.warning('The {} parameter was not provided. Setting '
- 'paging cycle duration to 1280 ms by '
- 'default.'.format(self.PARAM_PAGING))
- new_config.paging_cycle = 1280
- else:
- try:
- new_config.paging_cycle = int(values[1])
- except ValueError:
- raise ValueError(
- 'The {} parameter has to be followed by the paging cycle '
- 'duration in milliseconds.'.format(self.PARAM_PAGING))
-
- # Get uplink power
-
- ul_power = self.get_uplink_power_from_parameters(parameters)
-
- # Power is not set on the callbox until after the simulation is
- # started. Saving this value in a variable for later
- self.sim_ul_power = ul_power
-
- # Get downlink power
-
- dl_power = self.get_downlink_power_from_parameters(parameters)
-
- # Power is not set on the callbox until after the simulation is
- # started. Saving this value in a variable for later
- self.sim_dl_power = dl_power
-
- # Setup the base station with the obtained configuration and then save
- # these parameters in the current configuration object
- self.simulator.configure_bts(new_config)
- self.primary_config.incorporate(new_config)
+ self.cell_configs.append(LteCellConfig(self.log))
+ self.cell_configs[i].configure(new_cell_list[i])
+ self.simulator.configure_bts(self.cell_configs[i], i)
# Now that the band is set, calibrate the link if necessary
self.load_pathloss_if_required()
+ # This shouldn't be a cell parameter but instead a simulation config
+ # Setup LTE RRC status change function and timer for LTE idle test case
+ if self.PARAM_RRC_STATUS_CHANGE_TIMER not in parameters[0]:
+ self.log.info(
+ "The test config does not include the '{}' key. Disabled "
+ "by default.".format(self.PARAM_RRC_STATUS_CHANGE_TIMER))
+ self.simulator.set_lte_rrc_state_change_timer(False)
+ else:
+ timer = int(parameters[0][self.PARAM_RRC_STATUS_CHANGE_TIMER])
+ self.simulator.set_lte_rrc_state_change_timer(True, timer)
+ self.rrc_sc_timer = timer
+
def calibrated_downlink_rx_power(self, bts_config, rsrp):
""" LTE simulation overrides this method so that it can convert from
RSRP to total signal power transmitted from the basestation.
@@ -861,7 +559,7 @@
self.rsrp_to_signal_power
Returns:
- Dowlink calibration value and measured DL power. Note that the
+ Downlink calibration value and measured DL power. Note that the
phone only reports RSRP of the primary chain
"""
@@ -909,8 +607,9 @@
Maximum throughput in mbps.
"""
-
- return self.bts_maximum_downlink_throughtput(self.primary_config)
+ return sum(
+ self.bts_maximum_downlink_throughtput(self.cell_configs[bts_index])
+ for bts_index in range(self.num_carriers))
def bts_maximum_downlink_throughtput(self, bts_config):
""" Calculates maximum achievable downlink throughput for a single
@@ -934,18 +633,18 @@
'because the MIMO mode has not been set.')
bandwidth = bts_config.bandwidth
- rb_ratio = bts_config.dl_rbs / self.total_rbs_dictionary[bandwidth]
+ rb_ratio = bts_config.dl_rbs / TOTAL_RBS_DICTIONARY[bandwidth]
mcs = bts_config.dl_mcs
max_rate_per_stream = None
tdd_subframe_config = bts_config.dlul_config
- duplex_mode = self.get_duplex_mode(bts_config.band)
+ duplex_mode = bts_config.get_duplex_mode()
if duplex_mode == DuplexMode.TDD:
- if self.dl_256_qam:
+ if bts_config.dl_256_qam_enabled:
if mcs == 27:
- if bts_config.tbs_pattern_on:
+ if bts_config.mac_padding:
max_rate_per_stream = self.tdd_config_tput_lut_dict[
'TDD_CONFIG3'][tdd_subframe_config][bandwidth][
'DL']
@@ -955,7 +654,7 @@
'DL']
else:
if mcs == 28:
- if bts_config.tbs_pattern_on:
+ if bts_config.mac_padding:
max_rate_per_stream = self.tdd_config_tput_lut_dict[
'TDD_CONFIG4'][tdd_subframe_config][bandwidth][
'DL']
@@ -965,7 +664,7 @@
'DL']
elif duplex_mode == DuplexMode.FDD:
- if (not self.dl_256_qam and bts_config.tbs_pattern_on
+ if (not bts_config.dl_256_qam_enabled and bts_config.mac_padding
and mcs == 28):
max_rate_per_stream = {
3: 9.96,
@@ -974,13 +673,13 @@
15: 52.7,
20: 72.2
}.get(bandwidth, None)
- if (not self.dl_256_qam and bts_config.tbs_pattern_on
+ if (not bts_config.dl_256_qam_enabled and bts_config.mac_padding
and mcs == 27):
max_rate_per_stream = {
1.4: 2.94,
}.get(bandwidth, None)
- elif (not self.dl_256_qam and not bts_config.tbs_pattern_on
- and mcs == 27):
+ elif (not bts_config.dl_256_qam_enabled
+ and not bts_config.mac_padding and mcs == 27):
max_rate_per_stream = {
1.4: 2.87,
3: 7.7,
@@ -989,7 +688,7 @@
15: 42.3,
20: 57.7
}.get(bandwidth, None)
- elif self.dl_256_qam and bts_config.tbs_pattern_on and mcs == 27:
+ elif bts_config.dl_256_qam_enabled and bts_config.mac_padding and mcs == 27:
max_rate_per_stream = {
3: 13.2,
5: 22.9,
@@ -997,11 +696,11 @@
15: 72.2,
20: 93.9
}.get(bandwidth, None)
- elif self.dl_256_qam and bts_config.tbs_pattern_on and mcs == 26:
+ elif bts_config.dl_256_qam_enabled and bts_config.mac_padding and mcs == 26:
max_rate_per_stream = {
1.4: 3.96,
}.get(bandwidth, None)
- elif (self.dl_256_qam and not bts_config.tbs_pattern_on
+ elif (bts_config.dl_256_qam_enabled and not bts_config.mac_padding
and mcs == 27):
max_rate_per_stream = {
3: 11.3,
@@ -1010,7 +709,7 @@
15: 68.1,
20: 88.4
}.get(bandwidth, None)
- elif (self.dl_256_qam and not bts_config.tbs_pattern_on
+ elif (bts_config.dl_256_qam_enabled and not bts_config.mac_padding
and mcs == 26):
max_rate_per_stream = {
1.4: 3.96,
@@ -1018,9 +717,9 @@
if not max_rate_per_stream:
raise NotImplementedError(
- "The calculation for tbs pattern = {} "
+ "The calculation for MAC padding = {} "
"and mcs = {} is not implemented.".format(
- "FULLALLOCATION" if bts_config.tbs_pattern_on else "OFF",
+ "FULLALLOCATION" if bts_config.mac_padding else "OFF",
mcs))
return max_rate_per_stream * streams * rb_ratio
@@ -1034,7 +733,7 @@
"""
- return self.bts_maximum_uplink_throughtput(self.primary_config)
+ return self.bts_maximum_uplink_throughtput(self.cell_configs[0])
def bts_maximum_uplink_throughtput(self, bts_config):
""" Calculates maximum achievable uplink throughput for the selected
@@ -1049,18 +748,18 @@
"""
bandwidth = bts_config.bandwidth
- rb_ratio = bts_config.ul_rbs / self.total_rbs_dictionary[bandwidth]
+ rb_ratio = bts_config.ul_rbs / TOTAL_RBS_DICTIONARY[bandwidth]
mcs = bts_config.ul_mcs
max_rate_per_stream = None
tdd_subframe_config = bts_config.dlul_config
- duplex_mode = self.get_duplex_mode(bts_config.band)
+ duplex_mode = bts_config.get_duplex_mode()
if duplex_mode == DuplexMode.TDD:
- if self.ul_64_qam:
+ if bts_config.ul_64_qam_enabled:
if mcs == 28:
- if bts_config.tbs_pattern_on:
+ if bts_config.mac_padding:
max_rate_per_stream = self.tdd_config_tput_lut_dict[
'TDD_CONFIG3'][tdd_subframe_config][bandwidth][
'UL']
@@ -1070,7 +769,7 @@
'UL']
else:
if mcs == 23:
- if bts_config.tbs_pattern_on:
+ if bts_config.mac_padding:
max_rate_per_stream = self.tdd_config_tput_lut_dict[
'TDD_CONFIG4'][tdd_subframe_config][bandwidth][
'UL']
@@ -1080,7 +779,7 @@
'UL']
elif duplex_mode == DuplexMode.FDD:
- if mcs == 23 and not self.ul_64_qam:
+ if mcs == 23 and not bts_config.ul_64_qam_enabled:
max_rate_per_stream = {
1.4: 2.85,
3: 7.18,
@@ -1089,7 +788,7 @@
15: 36.5,
20: 49.1
}.get(bandwidth, None)
- elif mcs == 28 and self.ul_64_qam:
+ elif mcs == 28 and bts_config.ul_64_qam_enabled:
max_rate_per_stream = {
1.4: 4.2,
3: 10.5,
@@ -1102,110 +801,11 @@
if not max_rate_per_stream:
raise NotImplementedError(
"The calculation fir mcs = {} is not implemented.".format(
- "FULLALLOCATION" if bts_config.tbs_pattern_on else "OFF",
+ "FULLALLOCATION" if bts_config.mac_padding else "OFF",
mcs))
return max_rate_per_stream * rb_ratio
- def allocation_percentages_to_rbs(self, bw, tm, dl, ul):
- """ Converts usage percentages to number of DL/UL RBs
-
- Because not any number of DL/UL RBs can be obtained for a certain
- bandwidth, this function calculates the number of RBs that most
- closely matches the desired DL/UL percentages.
-
- Args:
- bw: the bandwidth for the which the RB configuration is requested
- tm: the transmission in which the base station will be operating
- dl: desired percentage of downlink RBs
- ul: desired percentage of uplink RBs
- Returns:
- a tuple indicating the number of downlink and uplink RBs
- """
-
- # Validate the arguments
- if (not 0 <= dl <= 100) or (not 0 <= ul <= 100):
- raise ValueError("The percentage of DL and UL RBs have to be two "
- "positive between 0 and 100.")
-
- # Get min and max values from tables
- max_rbs = self.total_rbs_dictionary[bw]
- min_dl_rbs = self.min_dl_rbs_dictionary[bw]
- min_ul_rbs = self.min_ul_rbs_dictionary[bw]
-
- def percentage_to_amount(min_val, max_val, percentage):
- """ Returns the integer between min_val and max_val that is closest
- to percentage/100*max_val
- """
-
- # Calculate the value that corresponds to the required percentage.
- closest_int = round(max_val * percentage / 100)
- # Cannot be less than min_val
- closest_int = max(closest_int, min_val)
- # RBs cannot be more than max_rbs
- closest_int = min(closest_int, max_val)
-
- return closest_int
-
- # Calculate the number of DL RBs
-
- # Get the number of DL RBs that corresponds to
- # the required percentage.
- desired_dl_rbs = percentage_to_amount(min_val=min_dl_rbs,
- max_val=max_rbs,
- percentage=dl)
-
- if tm == TransmissionMode.TM3 or tm == TransmissionMode.TM4:
-
- # For TM3 and TM4 the number of DL RBs needs to be max_rbs or a
- # multiple of the RBG size
-
- if desired_dl_rbs == max_rbs:
- dl_rbs = max_rbs
- else:
- dl_rbs = (math.ceil(desired_dl_rbs / self.rbg_dictionary[bw]) *
- self.rbg_dictionary[bw])
-
- else:
- # The other TMs allow any number of RBs between 1 and max_rbs
- dl_rbs = desired_dl_rbs
-
- # Calculate the number of UL RBs
-
- # Get the number of UL RBs that corresponds
- # to the required percentage
- desired_ul_rbs = percentage_to_amount(min_val=min_ul_rbs,
- max_val=max_rbs,
- percentage=ul)
-
- # Create a list of all possible UL RBs assignment
- # The standard allows any number that can be written as
- # 2**a * 3**b * 5**c for any combination of a, b and c.
-
- def pow_range(max_value, base):
- """ Returns a range of all possible powers of base under
- the given max_value.
- """
- return range(int(math.ceil(math.log(max_value, base))))
-
- possible_ul_rbs = [
- 2**a * 3**b * 5**c for a in pow_range(max_rbs, 2)
- for b in pow_range(max_rbs, 3)
- for c in pow_range(max_rbs, 5)
- if 2**a * 3**b * 5**c <= max_rbs] # yapf: disable
-
- # Find the value in the list that is closest to desired_ul_rbs
- differences = [abs(rbs - desired_ul_rbs) for rbs in possible_ul_rbs]
- ul_rbs = possible_ul_rbs[differences.index(min(differences))]
-
- # Report what are the obtained RB percentages
- self.log.info("Requested a {}% / {}% RB allocation. Closest possible "
- "percentages are {}% / {}%.".format(
- dl, ul, round(100 * dl_rbs / max_rbs),
- round(100 * ul_rbs / max_rbs)))
-
- return dl_rbs, ul_rbs
-
def calibrate(self, band):
""" Calculates UL and DL path loss if it wasn't done before
@@ -1217,55 +817,37 @@
"""
# Save initial values in a configuration object so they can be restored
- restore_config = self.BtsConfig()
- restore_config.mimo_mode = self.primary_config.mimo_mode
- restore_config.transmission_mode = self.primary_config.transmission_mode
- restore_config.bandwidth = self.primary_config.bandwidth
+ restore_config = LteCellConfig(self.log)
+ restore_config.mimo_mode = self.cell_configs[0].mimo_mode
+ restore_config.transmission_mode = \
+ self.cell_configs[0].transmission_mode
+ restore_config.bandwidth = self.cell_configs[0].bandwidth
# Set up a temporary calibration configuration.
- temporary_config = self.BtsConfig()
+ temporary_config = LteCellConfig(self.log)
temporary_config.mimo_mode = MimoMode.MIMO_1x1
temporary_config.transmission_mode = TransmissionMode.TM1
temporary_config.bandwidth = max(
self.allowed_bandwidth_dictionary[int(band)])
self.simulator.configure_bts(temporary_config)
- self.primary_config.incorporate(temporary_config)
+ self.cell_configs[0].incorporate(temporary_config)
super().calibrate(band)
# Restore values as they were before changing them for calibration.
self.simulator.configure_bts(restore_config)
- self.primary_config.incorporate(restore_config)
+ self.cell_configs[0].incorporate(restore_config)
def start_traffic_for_calibration(self):
- """
- If TBS pattern is set to full allocation, there is no need to start
- IP traffic.
- """
- if not self.primary_config.tbs_pattern_on:
+ """ If MAC padding is enabled, there is no need to start IP traffic. """
+ if not self.cell_configs[0].mac_padding:
super().start_traffic_for_calibration()
def stop_traffic_for_calibration(self):
- """
- If TBS pattern is set to full allocation, IP traffic wasn't started
- """
- if not self.primary_config.tbs_pattern_on:
+ """ If MAC padding is enabled, IP traffic wasn't started. """
+ if not self.cell_configs[0].mac_padding:
super().stop_traffic_for_calibration()
- def get_duplex_mode(self, band):
- """ Determines if the band uses FDD or TDD duplex mode
-
- Args:
- band: a band number
- Returns:
- an variable of class DuplexMode indicating if band is FDD or TDD
- """
-
- if 33 <= int(band) <= 46:
- return DuplexMode.TDD
- else:
- return DuplexMode.FDD
-
def get_measured_ul_power(self, samples=5, wait_after_sample=3):
""" Calculates UL power using measurements from the callbox and the
calibration data.
@@ -1293,3 +875,25 @@
'uncalibrated values as measured by the '
'callbox.')
return ul_power_sum / samples
+
+ def start(self):
+ """ Set the signal level for the secondary carriers, as the base class
+ implementation of this method will only set up downlink power for the
+ primary carrier component.
+
+ After that, attaches the secondary carriers."""
+
+ super().start()
+
+ if self.num_carriers > 1:
+ if self.sim_dl_power:
+ self.log.info('Setting DL power for secondary carriers.')
+
+ for bts_index in range(1, self.num_carriers):
+ new_config = LteCellConfig(self.log)
+ new_config.output_power = self.calibrated_downlink_rx_power(
+ self.cell_configs[bts_index], self.sim_dl_power)
+ self.simulator.configure_bts(new_config, bts_index)
+ self.cell_configs[bts_index].incorporate(new_config)
+
+ self.simulator.lte_attach_secondary_carriers(self.freq_bands)
diff --git a/acts/framework/acts/controllers/cellular_lib/NrCellConfig.py b/acts/framework/acts/controllers/cellular_lib/NrCellConfig.py
new file mode 100644
index 0000000..5a18025
--- /dev/null
+++ b/acts/framework/acts/controllers/cellular_lib/NrCellConfig.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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.controllers.cellular_lib.BaseCellConfig as base_cell
+
+
+class NrCellConfig(base_cell.BaseCellConfig):
+ """ NR cell configuration class.
+
+ Attributes:
+ band: an integer indicating the required band number.
+ bandwidth: a integer indicating the required channel bandwidth
+ """
+
+ PARAM_BAND = "band"
+ PARAM_BW = "bw"
+
+ def __init__(self, log):
+ """ Initialize the base station config by setting all its
+ parameters to None.
+ Args:
+ log: logger object.
+ """
+ super().__init__(log)
+ self.band = None
+ self.bandwidth = None
+
+ def configure(self, parameters):
+ """ Configures an NR cell using a dictionary of parameters.
+
+ Args:
+ parameters: a configuration dictionary
+ """
+ if self.PARAM_BAND not in parameters:
+ raise ValueError(
+ "The configuration dictionary must include a key '{}' with "
+ "the required band number.".format(self.PARAM_BAND))
+
+ self.band = parameters[self.PARAM_BAND]
+
+ if self.PARAM_BW not in parameters:
+ raise ValueError(
+ "The config dictionary must include parameter {} with an "
+ "int value (to indicate 1.4 MHz use 14).".format(
+ self.PARAM_BW))
+
+ self.bandwidth = parameters[self.PARAM_BW]
diff --git a/acts/framework/acts/controllers/cellular_lib/UmtsSimulation.py b/acts/framework/acts/controllers/cellular_lib/UmtsSimulation.py
index b301a6b..1e60813 100644
--- a/acts/framework/acts/controllers/cellular_lib/UmtsSimulation.py
+++ b/acts/framework/acts/controllers/cellular_lib/UmtsSimulation.py
@@ -39,13 +39,11 @@
UMTS_R8_CELL_FILE = 'CELL_WCDMA_R8_config.wnscp'
- # Test name parameters
+ # Configuration dictionary keys
PARAM_RELEASE_VERSION = "r"
PARAM_RELEASE_VERSION_99 = "99"
PARAM_RELEASE_VERSION_8 = "8"
PARAM_RELEASE_VERSION_7 = "7"
- PARAM_UL_PW = 'pul'
- PARAM_DL_PW = 'pdl'
PARAM_BAND = "band"
PARAM_RRC_STATUS_CHANGE_TIMER = "rrcstatuschangetimer"
@@ -92,7 +90,7 @@
def __init__(self, simulator, log, dut, test_config, calibration_table):
""" Initializes the cellular simulator for a UMTS simulation.
- Loads a simple UMTS simulation enviroment with 1 basestation. It also
+ Loads a simple UMTS simulation environment with 1 basestation. It also
creates the BTS handle so we can change the parameters as desired.
Args:
@@ -136,72 +134,50 @@
# Start simulation if it wasn't started
self.anritsu.start_simulation()
- def parse_parameters(self, parameters):
- """ Configs an UMTS simulation using a list of parameters.
+ def configure(self, parameters):
+ """ Configures simulation using a dictionary of parameters.
- Calls the parent method and consumes parameters specific to UMTS.
+ Processes UMTS configuration parameters.
Args:
- parameters: list of parameters
+ parameters: a configuration dictionary
"""
+ super().configure(parameters)
# Setup band
-
- values = self.consume_parameter(parameters, self.PARAM_BAND, 1)
-
- if not values:
+ if self.PARAM_BAND not in parameters:
raise ValueError(
- "The test name needs to include parameter '{}' followed by "
+ "The configuration dictionary must include a key '{}' with "
"the required band number.".format(self.PARAM_BAND))
- self.set_band(self.bts1, values[1])
+ self.set_band(self.bts1, parameters[self.PARAM_BAND])
self.load_pathloss_if_required()
# Setup release version
-
- values = self.consume_parameter(parameters, self.PARAM_RELEASE_VERSION,
- 1)
-
- if not values or values[1] not in [
- self.PARAM_RELEASE_VERSION_7, self.PARAM_RELEASE_VERSION_8,
- self.PARAM_RELEASE_VERSION_99
- ]:
+ if (self.PARAM_RELEASE_VERSION not in parameters
+ or parameters[self.PARAM_RELEASE_VERSION] not in [
+ self.PARAM_RELEASE_VERSION_7, self.PARAM_RELEASE_VERSION_8,
+ self.PARAM_RELEASE_VERSION_99
+ ]):
raise ValueError(
- "The test name needs to include the parameter {} followed by a "
+ "The configuration dictionary must include a key '{}' with a "
"valid release version.".format(self.PARAM_RELEASE_VERSION))
- self.set_release_version(self.bts1, values[1])
+ self.set_release_version(self.bts1,
+ parameters[self.PARAM_RELEASE_VERSION])
# Setup W-CDMA RRC status change and CELL_DCH timer for idle test case
-
- values = self.consume_parameter(parameters,
- self.PARAM_RRC_STATUS_CHANGE_TIMER, 1)
- if not values:
+ if self.PARAM_RRC_STATUS_CHANGE_TIMER not in parameters:
self.log.info(
- "The test name does not include the '{}' parameter. Disabled "
+ "The config dictionary does not include a '{}' key. Disabled "
"by default.".format(self.PARAM_RRC_STATUS_CHANGE_TIMER))
self.anritsu.set_umts_rrc_status_change(False)
else:
- self.rrc_sc_timer = int(values[1])
+ self.rrc_sc_timer = int(
+ parameters[self.PARAM_RRC_STATUS_CHANGE_TIMER])
self.anritsu.set_umts_rrc_status_change(True)
self.anritsu.set_umts_dch_stat_timer(self.rrc_sc_timer)
- # Setup uplink power
-
- ul_power = self.get_uplink_power_from_parameters(parameters)
-
- # Power is not set on the callbox until after the simulation is
- # started. Saving this value in a variable for later
- self.sim_ul_power = ul_power
-
- # Setup downlink power
-
- dl_power = self.get_downlink_power_from_parameters(parameters)
-
- # Power is not set on the callbox until after the simulation is
- # started. Saving this value in a variable for later
- self.sim_dl_power = dl_power
-
def set_release_version(self, bts, release_version):
""" Sets the release version.
diff --git a/acts/framework/acts/controllers/cellular_simulator.py b/acts/framework/acts/controllers/cellular_simulator.py
index 99adbd8..0a026e6 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.controllers import cellular_lib as sims
+from acts.controllers import cellular_lib
class AbstractCellularSimulator:
@@ -25,15 +25,6 @@
This class defines the interface that every cellular simulator controller
needs to implement and shouldn't be instantiated by itself. """
- # Indicates if it is able to use 256 QAM as the downlink modulation for LTE
- LTE_SUPPORTS_DL_256QAM = None
-
- # Indicates if it is able to use 64 QAM as the uplink modulation for LTE
- LTE_SUPPORTS_UL_64QAM = None
-
- # Indicates if 4x4 MIMO is supported for LTE
- LTE_SUPPORTS_4X4_MIMO = None
-
# The maximum number of carriers that this simulator can support for LTE
LTE_MAX_CARRIERS = None
@@ -43,6 +34,7 @@
def __init__(self):
""" Initializes the cellular simulator. """
self.log = logger.create_tagged_trace_logger('CellularSimulator')
+ self.num_carriers = None
def destroy(self):
""" Sends finalization commands to the cellular equipment and closes
@@ -53,24 +45,11 @@
""" Configures the equipment for an LTE simulation. """
raise NotImplementedError()
- def setup_lte_ca_scenario(self):
- """ Configures the equipment for an LTE with CA simulation. """
- raise NotImplementedError()
-
- def set_ca_combination(self, combination):
+ def set_band_combination(self, bands):
""" Prepares the test equipment for the indicated CA combination.
- The reason why this is implemented in a separate method and not calling
- LteSimulation.BtsConfig for each separate band is that configuring each
- ssc cannot be done separately, as it is necessary to know which
- carriers are on the same band in order to decide which RF outputs can
- be shared in the test equipment.
-
Args:
- combination: carrier aggregation configurations are indicated
- with a list of strings consisting of the band number followed
- by the CA class. For example, for 5 CA using 3C 7C and 28A
- the parameter value should be [3c, 7c, 28a].
+ bands: a list of bands represented as ints or strings
"""
raise NotImplementedError()
@@ -90,7 +69,7 @@
if config.input_power:
self.set_input_power(bts_index, config.input_power)
- if isinstance(config, sims.LteSimulation.LteSimulation.BtsConfig):
+ if isinstance(config, cellular_lib.LteCellConfig.LteCellConfig):
self.configure_lte_bts(config, bts_index)
def configure_lte_bts(self, config, bts_index=0):
@@ -124,16 +103,16 @@
# Modulation order should be set before set_scheduling_mode being
# called.
- if config.dl_modulation_order:
- self.set_dl_modulation(bts_index, config.dl_modulation_order)
+ if config.dl_256_qam_enabled is not None:
+ self.set_dl_256_qam_enabled(bts_index, config.dl_256_qam_enabled)
- if config.ul_modulation_order:
- self.set_ul_modulation(bts_index, config.ul_modulation_order)
+ if config.ul_64_qam_enabled is not None:
+ self.set_ul_64_qam_enabled(bts_index, config.ul_64_qam_enabled)
if config.scheduling_mode:
if (config.scheduling_mode ==
- sims.LteSimulation.SchedulingMode.STATIC
+ cellular_lib.LteSimulation.SchedulingMode.STATIC
and not (config.dl_rbs and config.ul_rbs and config.dl_mcs
and config.ul_mcs)):
raise ValueError('When the scheduling mode is set to manual, '
@@ -147,8 +126,8 @@
# This variable stores a boolean value so the following is needed to
# differentiate False from None
- if config.tbs_pattern_on is not None:
- self.set_tbs_pattern_on(bts_index, config.tbs_pattern_on)
+ if config.mac_padding is not None:
+ self.set_mac_padding(bts_index, config.mac_padding)
if config.cfi:
self.set_cfi(bts_index, config.cfi)
@@ -286,30 +265,30 @@
"""
raise NotImplementedError()
- def set_dl_modulation(self, bts_index, modulation):
- """ Sets the DL modulation for the indicated base station.
+ def set_dl_256_qam_enabled(self, bts_index, enabled):
+ """ Determines what MCS table should be used for the downlink.
Args:
bts_index: the base station number
- modulation: the new DL modulation
+ enabled: whether 256 QAM should be used
"""
raise NotImplementedError()
- def set_ul_modulation(self, bts_index, modulation):
- """ Sets the UL modulation for the indicated base station.
+ def set_ul_64_qam_enabled(self, bts_index, enabled):
+ """ Determines what MCS table should be used for the uplink.
Args:
bts_index: the base station number
- modulation: the new UL modulation
+ enabled: whether 64 QAM should be used
"""
raise NotImplementedError()
- def set_tbs_pattern_on(self, bts_index, tbs_pattern_on):
- """ Enables or disables TBS pattern in the indicated base station.
+ def set_mac_padding(self, bts_index, mac_padding):
+ """ Enables or disables MAC padding in the indicated base station.
Args:
bts_index: the base station number
- tbs_pattern_on: the new TBS pattern setting
+ mac_padding: the new MAC padding setting
"""
raise NotImplementedError()
diff --git a/acts/framework/acts/controllers/fuchsia_device.py b/acts/framework/acts/controllers/fuchsia_device.py
index 6e4419e..f2b8866 100644
--- a/acts/framework/acts/controllers/fuchsia_device.py
+++ b/acts/framework/acts/controllers/fuchsia_device.py
@@ -17,57 +17,59 @@
import backoff
import json
import logging
-import platform
import os
import random
import re
import requests
-import subprocess
import socket
+import subprocess
import time
from acts import context
from acts import logger as acts_logger
-from acts import utils
from acts import signals
-
+from acts import utils
from acts.controllers import pdu
+from acts.libs.proc import job
+from acts.utils import get_fuchsia_mdns_ipv6_address
from acts.controllers.fuchsia_lib.audio_lib import FuchsiaAudioLib
from acts.controllers.fuchsia_lib.backlight_lib import FuchsiaBacklightLib
-from acts.controllers.fuchsia_lib.bt.avdtp_lib import FuchsiaAvdtpLib
-from acts.controllers.fuchsia_lib.bt.hfp_lib import FuchsiaHfpLib
-from acts.controllers.fuchsia_lib.light_lib import FuchsiaLightLib
-
from acts.controllers.fuchsia_lib.basemgr_lib import FuchsiaBasemgrLib
+from acts.controllers.fuchsia_lib.bt.avdtp_lib import FuchsiaAvdtpLib
from acts.controllers.fuchsia_lib.bt.ble_lib import FuchsiaBleLib
from acts.controllers.fuchsia_lib.bt.bts_lib import FuchsiaBtsLib
from acts.controllers.fuchsia_lib.bt.gattc_lib import FuchsiaGattcLib
from acts.controllers.fuchsia_lib.bt.gatts_lib import FuchsiaGattsLib
+from acts.controllers.fuchsia_lib.bt.hfp_lib import FuchsiaHfpLib
+from acts.controllers.fuchsia_lib.bt.rfcomm_lib import FuchsiaRfcommLib
from acts.controllers.fuchsia_lib.bt.sdp_lib import FuchsiaProfileServerLib
+from acts.controllers.fuchsia_lib.ffx import FFX
from acts.controllers.fuchsia_lib.gpio_lib import FuchsiaGpioLib
from acts.controllers.fuchsia_lib.hardware_power_statecontrol_lib import FuchsiaHardwarePowerStatecontrolLib
from acts.controllers.fuchsia_lib.hwinfo_lib import FuchsiaHwinfoLib
from acts.controllers.fuchsia_lib.i2c_lib import FuchsiaI2cLib
from acts.controllers.fuchsia_lib.input_report_lib import FuchsiaInputReportLib
from acts.controllers.fuchsia_lib.kernel_lib import FuchsiaKernelLib
+from acts.controllers.fuchsia_lib.lib_controllers.netstack_controller import NetstackController
+from acts.controllers.fuchsia_lib.lib_controllers.wlan_controller import WlanController
+from acts.controllers.fuchsia_lib.lib_controllers.wlan_policy_controller import WlanPolicyController
+from acts.controllers.fuchsia_lib.light_lib import FuchsiaLightLib
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.session_manager_lib import FuchsiaSessionManagerLib
from acts.controllers.fuchsia_lib.sysinfo_lib import FuchsiaSysInfoLib
-from acts.controllers.fuchsia_lib.utils_lib import create_ssh_connection
+from acts.controllers.fuchsia_lib.syslog_lib import FuchsiaSyslogError
+from acts.controllers.fuchsia_lib.syslog_lib import create_syslog_process
from acts.controllers.fuchsia_lib.utils_lib import SshResults
+from acts.controllers.fuchsia_lib.utils_lib import create_ssh_connection
+from acts.controllers.fuchsia_lib.utils_lib import flash
+from acts.controllers.fuchsia_lib.wlan_ap_policy_lib import FuchsiaWlanApPolicyLib
from acts.controllers.fuchsia_lib.wlan_deprecated_configuration_lib import FuchsiaWlanDeprecatedConfigurationLib
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.controllers.fuchsia_lib.lib_controllers.wlan_controller import WlanController
-from acts.controllers.fuchsia_lib.lib_controllers.wlan_policy_controller import WlanPolicyController
-from acts.libs.proc import job
-from acts.utils import get_fuchsia_mdns_ipv6_address
MOBLY_CONTROLLER_CONFIG_NAME = "FuchsiaDevice"
ACTS_CONTROLLER_REFERENCE_NAME = "fuchsia_devices"
@@ -104,13 +106,12 @@
FUCHSIA_RECONNECT_AFTER_REBOOT_TIME = 5
-ENABLE_LOG_LISTENER = True
-
CHANNEL_OPEN_TIMEOUT = 5
FUCHSIA_GET_VERSION_CMD = 'cat /config/build-info/version'
FUCHSIA_REBOOT_TYPE_SOFT = 'soft'
+FUCHSIA_REBOOT_TYPE_SOFT_AND_FLASH = 'flash'
FUCHSIA_REBOOT_TYPE_HARD = 'hard'
FUCHSIA_DEFAULT_CONNECT_TIMEOUT = 60
@@ -192,6 +193,7 @@
sl4f_port: The SL4F HTTP port number of the Fuchsia device.
ssh_config: The ssh_config for connecting to the Fuchsia device.
"""
+
def __init__(self, fd_conf_data):
"""
Args:
@@ -211,17 +213,30 @@
if "ip" not in fd_conf_data:
raise FuchsiaDeviceError(FUCHSIA_DEVICE_NO_IP_MSG)
self.ip = fd_conf_data["ip"]
+ self.orig_ip = fd_conf_data["ip"]
self.sl4f_port = fd_conf_data.get("sl4f_port", 80)
self.ssh_port = fd_conf_data.get("ssh_port", 22)
self.ssh_config = fd_conf_data.get("ssh_config", None)
+ self.ssh_priv_key = fd_conf_data.get("ssh_priv_key", None)
+ self.authorized_file = fd_conf_data.get("authorized_file_loc", None)
+ self.serial_number = fd_conf_data.get("serial_number", None)
+ self.device_type = fd_conf_data.get("device_type", None)
+ self.product_type = fd_conf_data.get("product_type", None)
+ self.board_type = fd_conf_data.get("board_type", None)
+ self.build_number = fd_conf_data.get("build_number", None)
+ self.build_type = fd_conf_data.get("build_type", None)
+ self.server_path = fd_conf_data.get("server_path", None)
+ self.specific_image = fd_conf_data.get("specific_image", None)
+ self.ffx_binary_path = fd_conf_data.get("ffx_binary_path", None)
+ self.mdns_name = fd_conf_data.get("mdns_name", None)
- # Instead of the input ssh_config, a new config with
- # proper ControlPath values is set and written to
- # /tmp/temp_fuchsia_ssh_config.config.
- self._set_control_path_config(self.ssh_config,
- "/tmp/temp_fuchsia_ssh_config.config")
-
- self.ssh_config = "/tmp/temp_fuchsia_ssh_config.config"
+ # Instead of the input ssh_config, a new config is generated with proper
+ # ControlPath to the test output directory.
+ output_path = context.get_current_context().get_base_output_path()
+ generated_ssh_config = os.path.join(output_path,
+ "ssh_config_{}".format(self.ip))
+ self._set_control_path_config(self.ssh_config, generated_ssh_config)
+ self.ssh_config = generated_ssh_config
self.ssh_username = fd_conf_data.get("ssh_username",
FUCHSIA_SSH_USERNAME)
@@ -234,6 +249,14 @@
'country_code', FUCHSIA_DEFAULT_COUNTRY_CODE_US).upper()
self._persistent_ssh_conn = None
+ # WLAN interface info is populated inside configure_wlan
+ self.wlan_client_interfaces = {}
+ self.wlan_ap_interfaces = {}
+ self.wlan_client_test_interface_name = fd_conf_data.get(
+ 'wlan_client_test_interface', None)
+ self.wlan_ap_test_interface_name = fd_conf_data.get(
+ 'wlan_ap_test_interface', None)
+
# Whether to use 'policy' or 'drivers' for WLAN connect/disconnect calls
# If set to None, wlan is not configured.
self.association_mechanism = None
@@ -259,13 +282,16 @@
else:
time.sleep(1)
if mdns_ip and utils.is_valid_ipv6_address(mdns_ip):
+ # self.ip was actually an mdns name. Use it for self.mdns_name
+ # unless one was explicitly provided.
+ self.mdns_name = self.mdns_name or self.ip
self.ip = mdns_ip
self.address = "http://[{}]:{}".format(self.ip, self.sl4f_port)
else:
raise ValueError('Invalid IP: %s' % self.ip)
self.log = acts_logger.create_tagged_trace_logger(
- "FuchsiaDevice | %s" % self.ip)
+ "FuchsiaDevice | %s" % self.orig_ip)
self.init_address = self.address + "/init"
self.cleanup_address = self.address + "/cleanup"
@@ -284,6 +310,41 @@
self.log_path, "fuchsialog_%s_debug.txt" % self.serial)
self.log_process = None
+ self.init_libraries()
+
+ self.setup_commands = fd_conf_data.get('setup_commands', [])
+ self.teardown_commands = fd_conf_data.get('teardown_commands', [])
+
+ try:
+ self.start_services()
+ self.run_commands_from_config(self.setup_commands)
+ except Exception as e:
+ # Prevent a threading error, since controller isn't fully up yet.
+ self.clean_up()
+ raise e
+
+ def _set_control_path_config(self, old_config, new_config):
+ """Given an input ssh_config, write to a new config with proper
+ ControlPath values in place, if it doesn't exist already.
+
+ Args:
+ old_config: string, path to the input config
+ new_config: string, path to store the new config
+ """
+ if os.path.isfile(new_config):
+ return
+
+ ssh_config_copy = ""
+
+ with open(old_config, 'r') as file:
+ ssh_config_copy = re.sub('(\sControlPath\s.*)',
+ CONTROL_PATH_REPLACE_VALUE,
+ file.read(),
+ flags=re.M)
+ with open(new_config, 'w') as file:
+ file.write(ssh_config_copy)
+
+ def init_libraries(self):
# Grab commands from FuchsiaAudioLib
self.audio_lib = FuchsiaAudioLib(self.address, self.test_counter,
self.client_id)
@@ -296,6 +357,10 @@
self.hfp_lib = FuchsiaHfpLib(self.address, self.test_counter,
self.client_id)
+ # Grab commands from FuchsiaRfcommLib
+ self.rfcomm_lib = FuchsiaRfcommLib(self.address, self.test_counter,
+ self.client_id)
+
# Grab commands from FuchsiaLightLib
self.light_lib = FuchsiaLightLib(self.address, self.test_counter,
self.client_id)
@@ -326,8 +391,10 @@
self.client_id)
# Grab commands from FuchsiaHardwarePowerStatecontrolLib
- self.hardware_power_statecontrol_lib = FuchsiaHardwarePowerStatecontrolLib(
- self.address, self.test_counter, self.client_id)
+ self.hardware_power_statecontrol_lib = (
+ FuchsiaHardwarePowerStatecontrolLib(self.address,
+ self.test_counter,
+ self.client_id))
# Grab commands from FuchsiaHwinfoLib
self.hwinfo_lib = FuchsiaHwinfoLib(self.address, self.test_counter,
@@ -370,9 +437,14 @@
self.sysinfo_lib = FuchsiaSysInfoLib(self.address, self.test_counter,
self.client_id)
+ # Grab commands from FuchsiaSessionManagerLib
+ self.session_manager_lib = FuchsiaSessionManagerLib(self)
+
# Grabs command from FuchsiaWlanDeprecatedConfigurationLib
- self.wlan_deprecated_configuration_lib = FuchsiaWlanDeprecatedConfigurationLib(
- self.address, self.test_counter, self.client_id)
+ self.wlan_deprecated_configuration_lib = (
+ FuchsiaWlanDeprecatedConfigurationLib(self.address,
+ self.test_counter,
+ self.client_id))
# Grab commands from FuchsiaWlanLib
self.wlan_lib = FuchsiaWlanLib(self.address, self.test_counter,
@@ -387,54 +459,23 @@
self.test_counter,
self.client_id)
+ # Contains Netstack functions
+ self.netstack_controller = NetstackController(self)
+
# Contains WLAN core functions
self.wlan_controller = WlanController(self)
# Contains WLAN policy functions like save_network, remove_network, etc
self.wlan_policy_controller = WlanPolicyController(self)
- self.skip_sl4f = False
- # Start sl4f on device
- self.start_services(skip_sl4f=self.skip_sl4f)
- # Init server
- self.init_server_connection()
-
- self.setup_commands = fd_conf_data.get('setup_commands', [])
- self.teardown_commands = fd_conf_data.get('teardown_commands', [])
-
- try:
- self.run_commands_from_config(self.setup_commands)
- except FuchsiaDeviceError:
- # Prevent a threading error, since controller isn't fully up yet.
- self.clean_up()
- raise FuchsiaDeviceError('Failed to run setup commands.')
-
- def _set_control_path_config(self, old_config, new_config):
- """Given an input ssh_config, write to a new config with
- proper ControlPath values in place.
-
- Args:
- old_config: string, path to the input config
- new_config: string, path to store the new config
- """
- ssh_config_copy = ""
-
- with open(old_config, 'r') as file:
- ssh_config_copy = re.sub('(\sControlPath\s.*)',
- CONTROL_PATH_REPLACE_VALUE,
- file.read(),
- flags=re.M)
- with open(new_config, 'w') as file:
- file.write(ssh_config_copy)
-
@backoff.on_exception(
backoff.constant,
(ConnectionRefusedError, requests.exceptions.ConnectionError),
interval=1.5,
max_tries=4)
- def init_server_connection(self):
+ def init_sl4f_connection(self):
"""Initializes HTTP connection with SL4F server."""
- self.log.debug("Initializing server connection")
+ self.log.debug("Initializing SL4F server connection")
init_data = json.dumps({
"jsonrpc": "2.0",
"id": self.build_id(self.test_counter),
@@ -447,6 +488,71 @@
requests.get(url=self.init_address, data=init_data)
self.test_counter += 1
+ def init_ffx_connection(self):
+ """Initializes ffx's connection to the device.
+
+ If ffx has already been initialized, it will be reinitialized. This will
+ break any running tests calling ffx for this device.
+ """
+ self.log.debug("Initializing ffx connection")
+
+ if not self.ffx_binary_path:
+ raise ValueError(
+ 'Must provide "ffx_binary_path: <path to FFX binary>" in the device config'
+ )
+ if not self.mdns_name:
+ raise ValueError(
+ 'Must provide "mdns_name: <device mDNS name>" in the device config'
+ )
+
+ if hasattr(self, 'ffx'):
+ self.ffx.clean_up()
+
+ self.ffx = FFX(self.ffx_binary_path, self.mdns_name, self.ssh_priv_key)
+
+ # Wait for the device to be available. If the device isn't available within
+ # a short time (e.g. 5 seconds), log a warning before waiting longer.
+ try:
+ self.ffx.run("target wait", timeout_sec=5)
+ except job.TimeoutError as e:
+ longer_wait_sec = 60
+ self.log.info(
+ "Device is not immediately available via ffx." +
+ f" Waiting up to {longer_wait_sec} seconds for device to be reachable."
+ )
+ self.ffx.run("target wait", timeout_sec=longer_wait_sec)
+
+ # Test actual connectivity to the device by getting device information.
+ # Use a shorter timeout than default because this command can hang for
+ # a long time if the device is not actually connectable.
+ try:
+ result = self.ffx.run("target show --json", timeout_sec=15)
+ except Exception as e:
+ self.log.error(
+ f'Failed to reach target device. Try running "{self.ffx_binary_path}'
+ + ' doctor" to diagnose issues.')
+ raise e
+
+ # Compare the device's version to the ffx version
+ result_json = json.loads(result.stdout)
+ build_info = next(
+ filter(lambda s: s.get('label') == 'build', result_json))
+ version_info = next(
+ filter(lambda s: s.get('label') == 'version', build_info['child']))
+ device_version = version_info.get('value')
+ ffx_version = self.ffx.run("version").stdout
+
+ if not getattr(self, '_have_logged_ffx_version', False):
+ self._have_logged_ffx_version = True
+ self.log.info(
+ f"Device version: {device_version}, ffx version: {ffx_version}"
+ )
+ if device_version != ffx_version:
+ self.log.warning(
+ "ffx versions that differ from device versions may" +
+ " have compatibility issues. It is recommended to" +
+ " use versions within 6 weeks of each other.")
+
def run_commands_from_config(self, cmd_dicts):
"""Runs commands on the Fuchsia device from the config file. Useful for
device and/or Fuchsia specific configuration.
@@ -552,6 +658,9 @@
self.wlan_policy_controller._configure_wlan(
preserve_saved_networks)
+ # Retrieve WLAN client and AP interfaces
+ self.wlan_controller.update_wlan_interfaces()
+
def deconfigure_wlan(self):
"""
Stops WLAN functionality (if it has been started). Used to allow
@@ -581,8 +690,8 @@
testbed_pdus=None):
"""Reboot a FuchsiaDevice.
- Soft reboots the device, verifies it becomes unreachable, then verfifies
- it comes back online. Reinitializes SL4F so the tests can continue.
+ Soft reboots the device, verifies it becomes unreachable, then verifies
+ it comes back online. Re-initializes services so the tests can continue.
Args:
use_ssh: bool, if True, use fuchsia shell command via ssh to reboot
@@ -599,6 +708,7 @@
ConnectionError, if device fails to become unreachable, fails to
come back up, or if SL4F does not setup correctly.
"""
+ skip_unreachable_check = False
# Call Reboot
if reboot_type == FUCHSIA_REBOOT_TYPE_SOFT:
if use_ssh:
@@ -615,8 +725,14 @@
self.hardware_power_statecontrol_lib.suspendReboot(
timeout=3)
self.clean_up_services()
+ elif reboot_type == FUCHSIA_REBOOT_TYPE_SOFT_AND_FLASH:
+ flash(self, use_ssh, FUCHSIA_RECONNECT_AFTER_REBOOT_TIME)
+ skip_unreachable_check = True
elif reboot_type == FUCHSIA_REBOOT_TYPE_HARD:
self.log.info('Power cycling FuchsiaDevice (%s)' % self.ip)
+ if not testbed_pdus:
+ raise AttributeError('Testbed PDUs must be supplied '
+ 'to hard reboot a fuchsia_device.')
device_pdu, device_pdu_port = pdu.get_pdu_port_for_device(
self.device_pdu_config, testbed_pdus)
with utils.SuppressLogOutput():
@@ -625,24 +741,26 @@
device_pdu.off(str(device_pdu_port))
else:
raise ValueError('Invalid reboot type: %s' % reboot_type)
- # Wait for unreachable
- self.log.info('Verifying device is unreachable.')
- timeout = time.time() + unreachable_timeout
- while (time.time() < timeout):
- if utils.can_ping(job, self.ip):
- self.log.debug('Device is still pingable. Retrying.')
+ if not skip_unreachable_check:
+ # Wait for unreachable
+ self.log.info('Verifying device is unreachable.')
+ timeout = time.time() + unreachable_timeout
+ while (time.time() < timeout):
+ if utils.can_ping(job, self.ip):
+ self.log.debug('Device is still pingable. Retrying.')
+ else:
+ if reboot_type == FUCHSIA_REBOOT_TYPE_HARD:
+ self.log.info(
+ 'Restoring power to FuchsiaDevice (%s)...' %
+ self.ip)
+ device_pdu.on(str(device_pdu_port))
+ break
else:
- if reboot_type == FUCHSIA_REBOOT_TYPE_HARD:
- self.log.info('Restoring power to FuchsiaDevice (%s)...' %
- self.ip)
- device_pdu.on(str(device_pdu_port))
- break
- else:
- self.log.info('Device failed to go offline. Reintializing Sl4F.')
- self.start_services()
- self.init_server_connection()
- raise ConnectionError('Device never went down.')
- self.log.info('Device is unreachable as expected.')
+ self.log.info(
+ 'Device failed to go offline. Restarting services...')
+ self.start_services()
+ raise ConnectionError('Device never went down.')
+ self.log.info('Device is unreachable as expected.')
if reboot_type == FUCHSIA_REBOOT_TYPE_HARD:
self.log.info('Restoring power to FuchsiaDevice (%s)...' % self.ip)
device_pdu.on(str(device_pdu_port))
@@ -676,16 +794,12 @@
# Creating new log process, start it, start new persistent ssh session,
# start SL4F, and connect via SL4F
- self.log.info(
- 'Restarting log process and reinitiating SL4F on FuchsiaDevice %s'
- % self.ip)
+ self.log.info(f'Restarting services on FuchsiaDevice {self.ip}')
self.start_services()
# Verify SL4F is up.
- self.log.info(
- 'Initiating connection to SL4F and verifying commands can run.')
+ self.log.info('Verifying SL4F commands can run.')
try:
- self.init_server_connection()
self.hwinfo_lib.getDeviceInfo()
except Exception as err:
raise ConnectionError(
@@ -758,6 +872,22 @@
ssh_conn.close()
return command_result
+ def version(self, timeout=FUCHSIA_DEFAULT_COMMAND_TIMEOUT):
+ """Returns the version of Fuchsia running on the device.
+
+ Args:
+ timeout: (int) Seconds to wait for command to run.
+
+ Returns:
+ A string containing the Fuchsia version number.
+ For example, "5.20210713.2.1".
+
+ Raises:
+ DeviceOffline: If SSH to the device fails.
+ """
+ return self.send_command_ssh(FUCHSIA_GET_VERSION_CMD,
+ timeout=timeout).stdout
+
def ping(self,
dest_ip,
count=3,
@@ -940,7 +1070,7 @@
process_name: the name of the process to start or stop
action: specify whether to start or stop a process
"""
- if not process_name[-4:] == '.cmx':
+ if not (process_name[-4:] == '.cmx' or process_name[-4:] == '.cml'):
process_name = '%s.cmx' % process_name
unable_to_connect_msg = None
process_state = False
@@ -1075,60 +1205,60 @@
(FuchsiaSyslogError, socket.timeout),
interval=1.5,
max_tries=4)
- def start_services(self, skip_sl4f=False):
+ def start_services(self):
"""Starts long running services on the Fuchsia device.
- 1. Start SL4F if not skipped.
+ Starts a syslog streaming process, SL4F server, initializes a connection
+ to the SL4F server, then starts an isolated ffx daemon.
- Args:
- skip_sl4f: Does not attempt to start SL4F if True.
"""
self.log.debug("Attempting to start Fuchsia device services on %s." %
self.ip)
if self.ssh_config:
- self.log_process = start_syslog(self.serial,
- self.log_path,
- self.ip,
- self.ssh_username,
- self.ssh_config,
- ssh_port=self.ssh_port)
+ self.log_process = create_syslog_process(self.serial,
+ self.log_path,
+ self.ip,
+ self.ssh_username,
+ self.ssh_config,
+ ssh_port=self.ssh_port)
- if ENABLE_LOG_LISTENER:
- try:
- self.log_process.start()
- except FuchsiaSyslogError as e:
- # Before backing off and retrying, stop the syslog if it
- # failed to setup correctly, to prevent threading error when
- # retrying
- self.log_process.stop()
- raise
+ try:
+ self.log_process.start()
+ except FuchsiaSyslogError as e:
+ # Before backing off and retrying, stop the syslog if it
+ # failed to setup correctly, to prevent threading error when
+ # retrying
+ self.log_process.stop()
+ raise
- if not skip_sl4f:
- self.control_daemon("sl4f.cmx", "start")
+ self.control_daemon("sl4f.cmx", "start")
+ self.init_sl4f_connection()
out_name = "fuchsia_device_%s_%s.txt" % (self.serial, 'fw_version')
full_out_path = os.path.join(self.log_path, out_name)
- fuchsia_version = self.send_command_ssh(
- FUCHSIA_GET_VERSION_CMD).stdout
fw_file = open(full_out_path, 'w')
- fw_file.write('%s\n' % fuchsia_version)
+ fw_file.write('%s\n' % self.version())
fw_file.close()
+ self.init_ffx_connection()
+
def stop_services(self):
"""Stops long running services on the fuchsia device.
- Terminate sl4f sessions if exist.
+ Terminates the syslog streaming process, the SL4F server on the device,
+ and the ffx daemon.
"""
self.log.debug("Attempting to stop Fuchsia device services on %s." %
self.ip)
+ if hasattr(self, 'ffx'):
+ self.ffx.clean_up()
if self.ssh_config:
try:
self.control_daemon("sl4f.cmx", "stop")
except Exception as err:
self.log.exception("Failed to stop sl4f.cmx with: %s" % err)
if self.log_process:
- if ENABLE_LOG_LISTENER:
- self.log_process.stop()
+ self.log_process.stop()
def load_config(self, config):
pass
diff --git a/acts/framework/acts/controllers/fuchsia_lib/OWNERS b/acts/framework/acts/controllers/fuchsia_lib/OWNERS
index ba880d9..130db54 100644
--- a/acts/framework/acts/controllers/fuchsia_lib/OWNERS
+++ b/acts/framework/acts/controllers/fuchsia_lib/OWNERS
@@ -1,3 +1,9 @@
+chcl@google.com
+dhobsd@google.com
haydennix@google.com
jmbrenna@google.com
+mnck@google.com
+nickchee@google.com
+sbalana@google.com
+silberst@google.com
tturney@google.com
diff --git a/acts/framework/acts/controllers/fuchsia_lib/bt/hfp_lib.py b/acts/framework/acts/controllers/fuchsia_lib/bt/hfp_lib.py
index 220ba38..cd789cf 100644
--- a/acts/framework/acts/controllers/fuchsia_lib/bt/hfp_lib.py
+++ b/acts/framework/acts/controllers/fuchsia_lib/bt/hfp_lib.py
@@ -75,7 +75,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetActivePeer"
- test_args = { "peer_id": peer_id }
+ test_args = {"peer_id": peer_id}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -94,18 +94,19 @@
return self.send_command(test_id, test_cmd, test_args)
- def newCall(self, remote, state):
+ def newCall(self, remote, state, direction):
"""Opens a new call channel and alerts the HFP peer.
Args:
remote: The number of the remote party.
state: The state of the call.
+ direction: The direction of the call. Can be "incoming" or "outgoing".
Returns:
Dictionary, call_id if success, error if error.
"""
test_cmd = "hfp_facade.NewCall"
- test_args = {"remote": remote, "state": state }
+ test_args = {"remote": remote, "state": state, "direction": direction}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -121,6 +122,23 @@
Dictionary, call_id if success, error if error.
"""
test_cmd = "hfp_facade.IncomingCall"
+ test_args = {"remote": remote}
+ test_id = self.build_id(self.test_counter)
+ self.test_counter += 1
+
+ return self.send_command(test_id, test_cmd, test_args)
+
+ def initiateIncomingWaitingCall(self, remote):
+ """Opens an incoming call when there is an onging call and alerts
+ the HFP peer.
+
+ Args:
+ remote: The number of the remote party.
+
+ Returns:
+ Dictionary, call_id if success, error if error.
+ """
+ test_cmd = "hfp_facade.IncomingWaitingCall"
test_args = {"remote": remote }
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -137,7 +155,7 @@
Dictionary, call_id if success, error if error.
"""
test_cmd = "hfp_facade.OutgoingCall"
- test_args = {"remote": remote }
+ test_args = {"remote": remote}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -153,7 +171,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetCallActive"
- test_args = {"call_id": call_id }
+ test_args = {"call_id": call_id}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -169,7 +187,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetCallHeld"
- test_args = {"call_id": call_id }
+ test_args = {"call_id": call_id}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -185,7 +203,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetCallTerminated"
- test_args = {"call_id": call_id }
+ test_args = {"call_id": call_id}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -201,7 +219,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetCallTransferredToAg"
- test_args = {"call_id": call_id }
+ test_args = {"call_id": call_id}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -217,7 +235,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetSpeakerGain"
- test_args = {"value": value }
+ test_args = {"value": value}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -233,7 +251,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetMicrophoneGain"
- test_args = {"value": value }
+ test_args = {"value": value}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -249,7 +267,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetServiceAvailable"
- test_args = {"value": value }
+ test_args = {"value": value}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -265,7 +283,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetRoaming"
- test_args = {"value": value }
+ test_args = {"value": value}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -281,7 +299,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetSignalStrength"
- test_args = {"value": value }
+ test_args = {"value": value}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -297,7 +315,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetSubscriberNumber"
- test_args = {"value": value }
+ test_args = {"value": value}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -313,7 +331,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetOperator"
- test_args = {"value": value }
+ test_args = {"value": value}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -329,7 +347,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetNrecSupport"
- test_args = {"value": value }
+ test_args = {"value": value}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -345,7 +363,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetBatteryLevel"
- test_args = {"value": value }
+ test_args = {"value": value}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -361,7 +379,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetLastDialed"
- test_args = {"number": number }
+ test_args = {"number": number}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -391,7 +409,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetMemoryLocation"
- test_args = {"location": location, "number": number }
+ test_args = {"location": location, "number": number}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -408,7 +426,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.ClearMemoryLocation"
- test_args = {"location": location }
+ test_args = {"location": location}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -426,7 +444,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "hfp_facade.SetDialResult"
- test_args = {"number": number, "status": status }
+ test_args = {"number": number, "status": status}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -444,3 +462,19 @@
self.test_counter += 1
return self.send_command(test_id, test_cmd, test_args)
+
+ def setConnectionBehavior(self, autoconnect):
+ """Set the Service Level Connection behavior when a new peer connects.
+
+ Args:
+ autoconnect: Enable/Disable autoconnection of SLC.
+
+ Returns:
+ Dictionary, None if success, error if error.
+ """
+ test_cmd = "hfp_facade.SetConnectionBehavior"
+ test_args = {"autoconnect": autoconnect}
+ 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/bt/rfcomm_lib.py b/acts/framework/acts/controllers/fuchsia_lib/bt/rfcomm_lib.py
new file mode 100644
index 0000000..6cc08b8
--- /dev/null
+++ b/acts/framework/acts/controllers/fuchsia_lib/bt/rfcomm_lib.py
@@ -0,0 +1,129 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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 FuchsiaRfcommLib(BaseLib):
+ def __init__(self, addr, tc, client_id):
+ self.address = addr
+ self.test_counter = tc
+ self.client_id = client_id
+
+ def init(self):
+ """Initializes the RFCOMM service.
+
+ Returns:
+ Dictionary, None if success, error if error.
+ """
+ test_cmd = "rfcomm_facade.RfcommInit"
+
+ test_args = {}
+ test_id = self.build_id(self.test_counter)
+ self.test_counter += 1
+
+ return self.send_command(test_id, test_cmd, test_args)
+
+ def removeService(self):
+ """Removes the RFCOMM service from the Fuchsia device
+
+ Returns:
+ Dictionary, None if success, error if error.
+ """
+ test_cmd = "rfcomm_facade.RfcommRemoveService"
+ test_args = {}
+ test_id = self.build_id(self.test_counter)
+ self.test_counter += 1
+
+ return self.send_command(test_id, test_cmd, test_args)
+
+ def disconnectSession(self, peer_id):
+ """Closes the RFCOMM Session with the remote peer
+
+ Returns:
+ Dictionary, None if success, error if error.
+ """
+ test_cmd = "rfcomm_facade.DisconnectSession"
+ test_args = {"peer_id": peer_id}
+ test_id = self.build_id(self.test_counter)
+ self.test_counter += 1
+
+ return self.send_command(test_id, test_cmd, test_args)
+
+ def connectRfcommChannel(self, peer_id, server_channel_number):
+ """Makes an outgoing RFCOMM connection to the remote peer
+
+ Returns:
+ Dictionary, None if success, error if error.
+ """
+ test_cmd = "rfcomm_facade.ConnectRfcommChannel"
+ test_args = {
+ "peer_id": peer_id,
+ "server_channel_number": server_channel_number
+ }
+ test_id = self.build_id(self.test_counter)
+ self.test_counter += 1
+
+ return self.send_command(test_id, test_cmd, test_args)
+
+ def disconnectRfcommChannel(self, peer_id, server_channel_number):
+ """Closes the RFCOMM channel with the remote peer
+
+ Returns:
+ Dictionary, None if success, error if error.
+ """
+ test_cmd = "rfcomm_facade.DisconnectRfcommChannel"
+ test_args = {
+ "peer_id": peer_id,
+ "server_channel_number": server_channel_number
+ }
+ test_id = self.build_id(self.test_counter)
+ self.test_counter += 1
+
+ return self.send_command(test_id, test_cmd, test_args)
+
+ def sendRemoteLineStatus(self, peer_id, server_channel_number):
+ """Sends a Remote Line Status update to the remote peer for the provided channel number
+
+ Returns:
+ Dictionary, None if success, error if error.
+ """
+ test_cmd = "rfcomm_facade.SendRemoteLineStatus"
+ test_args = {
+ "peer_id": peer_id,
+ "server_channel_number": server_channel_number
+ }
+ test_id = self.build_id(self.test_counter)
+ self.test_counter += 1
+
+ return self.send_command(test_id, test_cmd, test_args)
+
+ def writeRfcomm(self, peer_id, server_channel_number, data):
+ """Sends data to the remote peer over the RFCOMM channel
+
+ Returns:
+ Dictionary, None if success, error if error.
+ """
+ test_cmd = "rfcomm_facade.RfcommWrite"
+ test_args = {
+ "peer_id": peer_id,
+ "server_channel_number": server_channel_number,
+ "data": data
+ }
+ 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/ffx.py b/acts/framework/acts/controllers/fuchsia_lib/ffx.py
new file mode 100644
index 0000000..3f0aa37
--- /dev/null
+++ b/acts/framework/acts/controllers/fuchsia_lib/ffx.py
@@ -0,0 +1,167 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - 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 os
+import tempfile
+
+from pathlib import Path
+
+from acts import context
+from acts import logger
+from acts import signals
+from acts.libs.proc import job
+
+FFX_DEFAULT_COMMAND_TIMEOUT = 60
+
+
+class FFXError(signals.TestError):
+ pass
+
+
+class FFX:
+ """Device-specific controller for the ffx tool.
+
+ Attributes:
+ log: Logger for the device-specific instance of ffx.
+ binary_path: Path to the ffx binary.
+ config_path: Path to the ffx configuration JSON file.
+ ssh_auth_sock_path: Path to the temporary ssh_auth_sock file.
+ overnet_socket_path: Path to the temporary overnet socket file.
+ """
+
+ def __init__(self, binary_path, target, ssh_private_key_path=None):
+ """
+ Args:
+ binary_path: Path to ffx binary.
+ target: Fuchsia mDNS nodename of default target.
+ ssh_private_key_path: Path to SSH private key for talking to the
+ Fuchsia DUT.
+ """
+ self.log = logger.create_tagged_trace_logger(f"ffx | {target}")
+ self.binary_path = binary_path
+
+ # Create a new isolated environment for ffx. This is needed to avoid
+ # overlapping ffx daemons while testing in parallel, causing the ffx
+ # invocations to “upgrade” one daemon to another, which appears as a
+ # flap/restart to another test.
+ root_dir = context.get_current_context(
+ context.ContextLevel.ROOT).get_full_output_path()
+ target_dir = os.path.join(root_dir, target)
+ ffx_daemon_log_dir = os.path.join(target_dir, "ffx_daemon_logs")
+
+ for dir in [target_dir, ffx_daemon_log_dir]:
+ os.makedirs(dir, exist_ok=True)
+
+ # Sockets need to be created in a different directory to be guaranteed
+ # to stay under the maximum socket path length of 104 characters.
+ # See https://unix.stackexchange.com/q/367008
+ self.ssh_auth_sock_path = tempfile.mkstemp(suffix="ssh_auth_sock")[1]
+ self.overnet_socket_path = tempfile.mkstemp(suffix="overnet_socket")[1]
+
+ config = {
+ "target": {
+ "default": target,
+ },
+ # Use user-specific and device-specific locations for sockets.
+ # Avoids user permission errors in a multi-user test environment.
+ # Avoids daemon upgrades when running tests in parallel in a CI
+ # environment.
+ "ssh": {
+ "auth-sock": self.ssh_auth_sock_path,
+ },
+ "overnet": {
+ "socket": self.overnet_socket_path,
+ },
+ # Configure the ffx daemon to log to a place where we can read it.
+ # Note, ffx client will still output to stdout, not this log
+ # directory.
+ "log": {
+ "enabled": True,
+ "dir": [ffx_daemon_log_dir],
+ },
+ # Disable analytics to decrease noise on the network.
+ "ffx": {
+ "analytics": {
+ "disabled": True,
+ },
+ },
+ }
+
+ # ffx looks for the private key in several default locations. For
+ # testbeds which have the private key in another location, set it now.
+ if ssh_private_key_path:
+ config["ssh"]["priv"] = ssh_private_key_path
+
+ self.config_path = os.path.join(target_dir, "ffx_config.json")
+ with open(self.config_path, 'w', encoding="utf-8") as f:
+ json.dump(config, f, ensure_ascii=False, indent=4)
+
+ # The ffx daemon will started automatically when needed. There is no
+ # need to start it manually here.
+
+ def clean_up(self):
+ self.run("daemon stop")
+
+ # Remove socket files.
+ # TODO(https://fxbug.dev/93599): Replace the for-loop below once labs
+ # run Python 3.8 or higher. It should be replaced with:
+ # Path(self.ssh_auth_sock_path).unlink(missing_ok=True)
+ # Path(self.overnet_socket_path).unlink(missing_ok=True)
+ for filename in [self.ssh_auth_sock_path, self.overnet_socket_path]:
+ file = Path(filename)
+ if file.exists():
+ file.unlink()
+
+ def run(self,
+ command,
+ timeout_sec=FFX_DEFAULT_COMMAND_TIMEOUT,
+ skip_status_code_check=False):
+ """Runs an ffx command.
+
+ Args:
+ command: string, command to run with ffx.
+ timeout_sec: Seconds to wait for a command to complete.
+ skip_status_code_check: Whether to check for the status code.
+
+ Raises:
+ job.TimeoutError: when the command times out.
+ Error: when the command returns non-zero and skip_status_code_check is False.
+ FFXError: when stderr has contents and skip_status_code_check is False.
+
+ Returns:
+ A job.Result object containing the results of the command.
+ """
+ self.log.debug(f'Running "{command}".')
+
+ full_command = f'{self.binary_path} -c {self.config_path} {command}'
+ result = job.run(command=full_command,
+ timeout=timeout_sec,
+ ignore_status=skip_status_code_check)
+
+ if isinstance(result, Exception):
+ raise result
+
+ elif not skip_status_code_check and result.stderr:
+ self.log.warning(
+ f'Ran "{full_command}", exit status {result.exit_status}')
+ self.log.warning(f'stdout: {result.stdout}')
+ self.log.warning(f'stderr: {result.stderr}')
+
+ raise FFXError(
+ f'Error when running "{full_command}": {result.stderr}')
+
+ return result
diff --git a/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/netstack_controller.py b/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/netstack_controller.py
new file mode 100644
index 0000000..e7ca026
--- /dev/null
+++ b/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/netstack_controller.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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 logger
+from acts import signals
+
+
+class NetstackControllerError(signals.ControllerError):
+ pass
+
+
+class NetstackController:
+ """Contains methods related to netstack, to be used in FuchsiaDevice object"""
+
+ def __init__(self, fuchsia_device):
+ self.device = fuchsia_device
+ self.log = logger.create_tagged_trace_logger(
+ 'NetstackController for FuchsiaDevice | %s' % self.device.ip)
+
+ def list_interfaces(self):
+ """Retrieve netstack interfaces from netstack facade
+
+ Returns:
+ List of dicts, one for each interface, containing interface
+ information
+ """
+ response = self.device.netstack_lib.netstackListInterfaces()
+ if response.get('error'):
+ raise NetstackControllerError(
+ 'Failed to get network interfaces list: %s' %
+ response['error'])
+ return response['result']
diff --git a/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/wlan_controller.py b/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/wlan_controller.py
index 032a93f..d50f726 100644
--- a/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/wlan_controller.py
+++ b/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/wlan_controller.py
@@ -30,6 +30,7 @@
class WlanController:
"""Contains methods related to wlan core, to be used in FuchsiaDevice object"""
+
def __init__(self, fuchsia_device):
self.device = fuchsia_device
self.log = logger.create_tagged_trace_logger(
@@ -44,86 +45,87 @@
def _deconfigure_wlan(self):
pass
- def get_wlan_client_interface_id(self):
- """ Returns the wlan interface id of the first found wlan client
- interface.
+ def update_wlan_interfaces(self):
+ """ Retrieves WLAN interfaces from device and sets the FuchsiaDevice
+ attributes.
"""
- # Retrieve wlan ifaces
+ wlan_interfaces = self.get_interfaces_by_role()
+ self.device.wlan_client_interfaces = wlan_interfaces['client']
+ self.device.wlan_ap_interfaces = wlan_interfaces['ap']
+
+ # Set test interfaces to value from config, else the first found
+ # interface, else None
+ self.device.wlan_client_test_interface_name = self.device.conf_data.get(
+ 'wlan_client_test_interface',
+ next(iter(self.device.wlan_client_interfaces), None))
+
+ self.device.wlan_ap_test_interface_name = self.device.conf_data.get(
+ 'wlan_ap_test_interface',
+ next(iter(self.device.wlan_ap_interfaces), None))
+
+ def get_interfaces_by_role(self):
+ """ Retrieves WLAN interface information, supplimented by netstack info.
+
+ Returns:
+ Dict with keys 'client' and 'ap', each of which contain WLAN
+ interfaces.
+ """
+
+ # Retrieve WLAN interface IDs
response = self.device.wlan_lib.wlanGetIfaceIdList()
if response.get('error'):
raise WlanControllerError('Failed to get WLAN iface ids: %s' %
response['error'])
- # If iface has role 'client', retunr id
- iface_ids = response.get('result', [])
- for id in iface_ids:
- query_response = self.device.wlan_lib.wlanQueryInterface(id)
- if query_response.get('error'):
+ wlan_iface_ids = response.get('result', [])
+ if len(wlan_iface_ids) < 1:
+ return {'client': {}, 'ap': {}}
+
+ # Use IDs to get WLAN interface info and mac addresses
+ wlan_ifaces_by_mac = {}
+ for id in wlan_iface_ids:
+ response = self.device.wlan_lib.wlanQueryInterface(id)
+ if response.get('error'):
raise WlanControllerError(
'Failed to query wlan iface id %s: %s' %
- (id, query_response['error']))
+ (id, response['error']))
- if query_response['result'].get('role').lower() == 'client':
- return id
+ mac = response['result'].get('sta_addr', None)
+ if mac is None:
+ # Fallback to older field name to maintain backwards
+ # compatibility with older versions of SL4F's
+ # QueryIfaceResponse. See https://fxrev.dev/562146.
+ mac = response['result'].get('mac_addr')
- return None
+ wlan_ifaces_by_mac[utils.mac_address_list_to_str(
+ mac)] = response['result']
- def get_wlan_interface_mac_addr_from_id(self, iface_id):
- """ Retrieves the mac address of a wlan iface, using the wlan iface
- id.
+ # Use mac addresses to query the interfaces from the netstack view,
+ # which allows us to supplement the interface information with the name,
+ # netstack_id, etc.
- Args:
- iface_id: int, wlan iface id
+ # TODO(fxb/75909): This tedium is necessary to get the interface name
+ # because only netstack has that information. The bug linked here is
+ # to reconcile some of the information between the two perspectives, at
+ # which point we can eliminate step.
+ net_ifaces = self.device.netstack_controller.list_interfaces()
+ wlan_ifaces_by_role = {'client': {}, 'ap': {}}
+ for iface in net_ifaces:
+ try:
+ # Some interfaces might not have a MAC
+ iface_mac = utils.mac_address_list_to_str(iface['mac'])
+ except Exception as e:
+ self.log.debug(f'Error {e} getting MAC for iface {iface}')
+ continue
+ if iface_mac in wlan_ifaces_by_mac:
+ wlan_ifaces_by_mac[iface_mac]['netstack_id'] = iface['id']
- Returns:
- string, mac address of wlan iface
- """
- query_response = self.device.wlan_lib.wlanQueryInterface(iface_id)
- if query_response.get('error'):
- raise WlanControllerError('Failed to query wlan iface id %s: %s' %
- (iface_id, query_response['error']))
- return utils.mac_address_list_to_str(
- query_response['result'].get('mac_addr'))
+ # Add to return dict, mapped by role then name.
+ wlan_ifaces_by_role[
+ wlan_ifaces_by_mac[iface_mac]['role'].lower()][
+ iface['name']] = wlan_ifaces_by_mac[iface_mac]
- def get_wlan_interface_name(self, mac_addr=None):
- """ Retrieves name (netstack) of wlan interface using the mac address. If
- mac address is not provided, returns the name of the first found wlan
- client (as opposed to AP) interface.
-
- Args:
- mac_addr: optional, string or list of decimal octets representing
- the mac addr of the wlan interface. e.g. "44:07:0b:50:c1:ef" or
- [68, 7, 11, 80, 193, 239]
-
- Returns:
- string, name of wlan interface
- """
- # Default to first found client wlan interface
- if not mac_addr:
- client_iface_id = self.get_wlan_client_interface_id()
- mac_addr = self.get_wlan_interface_mac_addr_from_id(
- client_iface_id)
-
- # Convert mac addr to list, for comparison
- if type(mac_addr) == str:
- mac_addr = utils.mac_address_str_to_list(mac_addr)
-
- err = self.device.netstack_lib.init().get('error')
- if err:
- raise WlanControllerError('Failed to init netstack_lib: %s' % err)
-
- # Retrieve net ifaces
- response = self.device.netstack_lib.netstackListInterfaces()
- if response.get('error'):
- raise WlanControllerError(
- 'Failed to get network interfaces list: %s' %
- response['error'])
-
- # Find iface with matching mac addr, and return name
- for iface_info in response['result']:
- if iface_info['mac'] == mac_addr:
- return iface_info['name']
- return None
+ return wlan_ifaces_by_role
def set_country_code(self, country_code):
"""Sets country code through the regulatory region service and waits
diff --git a/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/wlan_policy_controller.py b/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/wlan_policy_controller.py
index e99656e..e5b8fce 100644
--- a/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/wlan_policy_controller.py
+++ b/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/wlan_policy_controller.py
@@ -20,6 +20,10 @@
from acts import logger
from acts import signals
+import typing
+if typing.TYPE_CHECKING:
+ from acts.controllers.fuchsia_device import FuchsiaDevice
+
SAVED_NETWORKS = "saved_networks"
CLIENT_STATE = "client_connections_state"
CONNECTIONS_ENABLED = "ConnectionsEnabled"
@@ -39,13 +43,15 @@
"""Contains methods related to the wlan policy layer, to be used in the
FuchsiaDevice object.
"""
+
def __init__(self, fuchsia_device):
- self.device = fuchsia_device
+ self.device: FuchsiaDevice = fuchsia_device
self.log = logger.create_tagged_trace_logger(
'WlanPolicyController for FuchsiaDevice | %s' % self.device.ip)
self.client_controller = False
self.preserved_networks_and_client_state = None
self.policy_configured = False
+ self._paused_session = False
def _configure_wlan(self, preserve_saved_networks, timeout=15):
"""Sets up wlan policy layer.
@@ -56,7 +62,7 @@
"""
end_time = time.time() + timeout
- # Kill basemgr
+ # Kill basemgr (Component v1 version of session manager)
while time.time() < end_time:
response = self.device.basemgr_lib.killBasemgr()
if not response.get('error'):
@@ -68,6 +74,16 @@
raise WlanPolicyControllerError(
'Failed to issue successful basemgr kill call.')
+ # Stop the session manager, which also holds the Policy controller.
+ response = self.device.session_manager_lib.pauseSession()
+ if response.get('error'):
+ self.log.error('Failed to stop the session.')
+ raise WlanPolicyControllerError(response['error'])
+ else:
+ if response.get('result') == 'Success':
+ self._paused_session = True
+ self.log.debug(f"Paused session: {response.get('result')}")
+
# Acquire control of policy layer
while time.time() < end_time:
# Create a client controller
@@ -113,6 +129,13 @@
if not self.policy_configured:
self._configure_wlan()
self.restore_preserved_networks_and_client_state()
+ if self._paused_session:
+ response = self.device.session_manager_lib.resumeSession()
+ if response.get('error'):
+ self.log.warning('Failed to resume the session.')
+ self.log.warning(response['error'])
+ else:
+ self.log.debug(f"Resumed session: {response.get('result')}")
def start_client_connections(self):
"""Allow device to connect to networks via policy layer (including
@@ -474,6 +497,10 @@
Returns:
True, if successful. False, if still connected after timeout.
"""
+ # If there are already no existing connections when this function is called,
+ # then an update won't be generated by the device, and we'll time out.
+ # Force an update by getting a new listener.
+ self.device.wlan_policy_lib.wlanSetNewListener()
end_time = time.time() + timeout
while time.time() < end_time:
time_left = max(1, int(end_time - time.time()))
diff --git a/acts/framework/acts/controllers/fuchsia_lib/logging_lib.py b/acts/framework/acts/controllers/fuchsia_lib/logging_lib.py
index 71678aa..78a9dd4 100644
--- a/acts/framework/acts/controllers/fuchsia_lib/logging_lib.py
+++ b/acts/framework/acts/controllers/fuchsia_lib/logging_lib.py
@@ -53,9 +53,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "logging_facade.LogInfo"
- test_args = {
- "message": '[%s] %s' % (datetime.datetime.now(), message)
- }
+ test_args = {"message": '[%s] %s' % (datetime.datetime.now(), message)}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -71,9 +69,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "logging_facade.LogWarn"
- test_args = {
- "message": '[%s] %s' % (datetime.datetime.now(), message)
- }
+ test_args = {"message": '[%s] %s' % (datetime.datetime.now(), message)}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
diff --git a/acts/framework/acts/controllers/fuchsia_lib/netstack/netstack_lib.py b/acts/framework/acts/controllers/fuchsia_lib/netstack/netstack_lib.py
index 578612c..173127c 100644
--- a/acts/framework/acts/controllers/fuchsia_lib/netstack/netstack_lib.py
+++ b/acts/framework/acts/controllers/fuchsia_lib/netstack/netstack_lib.py
@@ -16,6 +16,7 @@
from acts.controllers.fuchsia_lib.base_lib import BaseLib
+
class FuchsiaNetstackLib(BaseLib):
def __init__(self, addr, tc, client_id):
self.address = addr
@@ -35,37 +36,6 @@
return self.send_command(test_id, test_cmd, test_args)
- def init(self):
- """ListInterfaces command
-
- Returns:
- Dictionary, None if success, error if error.
- """
- test_cmd = "netstack_facade.InitNetstack"
- test_args = {}
- test_id = self.build_id(self.test_counter)
- self.test_counter += 1
-
- return self.send_command(test_id, test_cmd, test_args)
-
- def getInterfaceInfo(self, id):
- """Get interface info.
-
- Args:
- id: The interface ID.
-
- Returns:
- Dictionary, None if success, error if error.
- """
- test_cmd = "netstack_facade.GetInterfaceInfo"
- test_args = {
- "identifier": id
- }
- test_id = self.build_id(self.test_counter)
- self.test_counter += 1
-
- return self.send_command(test_id, test_cmd, test_args)
-
def enableInterface(self, id):
"""Enable Interface
@@ -76,9 +46,7 @@
Dictionary, None if success, error if error.
"""
test_cmd = "netstack_facade.EnableInterface"
- test_args = {
- "identifier": id
- }
+ test_args = {"identifier": id}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
@@ -94,11 +62,8 @@
Dictionary, None if success, error if error.
"""
test_cmd = "netstack_facade.DisableInterface"
- test_args = {
- "identifier": id
- }
+ test_args = {"identifier": id}
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/session_manager_lib.py b/acts/framework/acts/controllers/fuchsia_lib/session_manager_lib.py
new file mode 100644
index 0000000..fc03c14
--- /dev/null
+++ b/acts/framework/acts/controllers/fuchsia_lib/session_manager_lib.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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 typing
+if typing.TYPE_CHECKING:
+ from acts.controllers.fuchsia_device import FuchsiaDevice
+
+
+class FuchsiaSessionManagerLib():
+ def __init__(self, fuchsia_device):
+ self.device: FuchsiaDevice = fuchsia_device
+
+ def resumeSession(self):
+ """Resumes a previously paused session
+
+ Returns:
+ Dictionary:
+ error: None, unless an error occurs
+ result: 'Success' or None if error
+ """
+ try:
+ self.device.ffx.run(
+ "component start /core/session-manager/session:session")
+ return {'error': None, 'result': 'Success'}
+ except Exception as e:
+ return {'error': e, 'result': None}
+
+ def pauseSession(self):
+ """Pause the session, allowing for later resumption
+
+ Returns:
+ Dictionary:
+ error: None, unless an error occurs
+ result: 'Success', 'NoSessionToPause', or None if error
+ """
+ result = self.device.ffx.run(
+ "component stop -r /core/session-manager/session:session",
+ skip_status_code_check=True)
+
+ if result.exit_status == 0:
+ return {'error': None, 'result': 'Success'}
+ else:
+ if "InstanceNotFound" in result.stderr:
+ return {'error': None, 'result': 'NoSessionToPause'}
+ else:
+ return {'error': result, 'result': None}
diff --git a/acts/framework/acts/controllers/fuchsia_lib/syslog_lib.py b/acts/framework/acts/controllers/fuchsia_lib/syslog_lib.py
index 17c0e5a..67a850a 100644
--- a/acts/framework/acts/controllers/fuchsia_lib/syslog_lib.py
+++ b/acts/framework/acts/controllers/fuchsia_lib/syslog_lib.py
@@ -33,6 +33,7 @@
def _log_line_func(log, timestamp_tracker):
"""Returns a lambda that logs a message to the given logger."""
+
def log_line(message):
timestamp_tracker.read_output(message)
log.info(message)
@@ -40,13 +41,13 @@
return log_line
-def start_syslog(serial,
- base_path,
- ip_address,
- ssh_username,
- ssh_config,
- ssh_port=22,
- extra_params=''):
+def create_syslog_process(serial,
+ base_path,
+ ip_address,
+ ssh_username,
+ ssh_config,
+ ssh_port=22,
+ extra_params=''):
"""Creates a FuchsiaSyslogProcess that automatically attempts to reconnect.
Args:
@@ -80,12 +81,9 @@
class FuchsiaSyslogProcess(object):
"""A class representing a Fuchsia Syslog object that communicates over ssh.
"""
- def __init__(self,
- ssh_username,
- ssh_config,
- ip_address,
- extra_params,
- ssh_port):
+
+ def __init__(self, ssh_username, ssh_config, ip_address, extra_params,
+ ssh_port):
"""
Args:
ssh_username: The username to connect to Fuchsia over ssh.
diff --git a/acts/framework/acts/controllers/fuchsia_lib/utils_lib.py b/acts/framework/acts/controllers/fuchsia_lib/utils_lib.py
index 91f217e..3fc1813 100644
--- a/acts/framework/acts/controllers/fuchsia_lib/utils_lib.py
+++ b/acts/framework/acts/controllers/fuchsia_lib/utils_lib.py
@@ -15,15 +15,21 @@
# limitations under the License.
import backoff
+import itertools
import os
import logging
import paramiko
+import psutil
+import shutil
import socket
+import tarfile
import time
+import usbinfo
from acts import utils
from acts.controllers.fuchsia_lib.base_lib import DeviceOffline
from acts.libs.proc import job
+from acts.utils import get_fuchsia_mdns_ipv6_address
logging.getLogger("paramiko").setLevel(logging.WARNING)
# paramiko-ng will throw INFO messages when things get disconnect or cannot
@@ -32,6 +38,15 @@
# Therefore, in order to reduce confusion in the logs the log level is set to
# WARNING.
+MDNS_LOOKUP_RETRY_MAX = 3
+FASTBOOT_TIMEOUT = 30
+AFTER_FLASH_BOOT_TIME = 30
+WAIT_FOR_EXISTING_FLASH_TO_FINISH_SEC = 360
+PROCESS_CHECK_WAIT_TIME_SEC = 30
+
+FUCHSIA_SDK_URL = "gs://fuchsia-sdk/development"
+FUCHSIA_RELEASE_TESTING_URL = "gs://fuchsia-release-testing/images"
+
def get_private_key(ip_address, ssh_config):
"""Tries to load various ssh key types.
@@ -82,6 +97,7 @@
ip_address: IP address of ssh server.
ssh_username: Username for ssh server.
ssh_config: ssh_config location for the ssh server.
+ ssh_port: port for the ssh server.
connect_timeout: Timeout value for connecting to ssh_server.
auth_timeout: Timeout value to wait for authentication.
banner_timeout: Timeout to wait for ssh banner.
@@ -156,6 +172,7 @@
stderr: The file descriptor to the stderr of the SSH connection.
exit_status: The file descriptor of the SSH command.
"""
+
def __init__(self, stdin, stdout, stderr, exit_status):
self._raw_stdout = stdout.read()
self._stdout = self._raw_stdout.decode('utf-8', errors='replace')
@@ -177,3 +194,171 @@
@property
def exit_status(self):
return self._exit_status
+
+
+def flash(fuchsia_device, use_ssh=False,
+ fuchsia_reconnect_after_reboot_time=5):
+ """A function to flash, not pave, a fuchsia_device
+
+ Args:
+ fuchsia_device: An ACTS fuchsia_device
+
+ Returns:
+ True if successful.
+ """
+ if not fuchsia_device.authorized_file:
+ raise ValueError('A ssh authorized_file must be present in the '
+ 'ACTS config to flash fuchsia_devices.')
+ # This is the product type from the fx set command.
+ # Do 'fx list-products' to see options in Fuchsia source tree.
+ if not fuchsia_device.product_type:
+ raise ValueError('A product type must be specified to flash '
+ 'fuchsia_devices.')
+ # This is the board type from the fx set command.
+ # Do 'fx list-boards' to see options in Fuchsia source tree.
+ if not fuchsia_device.board_type:
+ raise ValueError('A board type must be specified to flash '
+ 'fuchsia_devices.')
+ if not fuchsia_device.build_number:
+ fuchsia_device.build_number = 'LATEST'
+ if (utils.is_valid_ipv4_address(fuchsia_device.orig_ip)
+ or utils.is_valid_ipv6_address(fuchsia_device.orig_ip)):
+ raise ValueError('The fuchsia_device ip must be the mDNS name to be '
+ 'able to flash.')
+
+ if not fuchsia_device.specific_image:
+ file_download_needed = True
+ product_build = fuchsia_device.product_type
+ if fuchsia_device.build_type:
+ product_build = '{}_{}'.format(product_build,
+ fuchsia_device.build_type)
+ if 'LATEST' in fuchsia_device.build_number:
+ sdk_version = 'sdk'
+ if 'LATEST_F' in fuchsia_device.build_number:
+ f_branch = fuchsia_device.build_number.split('LATEST_F', 1)[1]
+ sdk_version = 'f{}_sdk'.format(f_branch)
+ file_to_download = '{}/{}-{}.{}-release.tgz'.format(
+ FUCHSIA_RELEASE_TESTING_URL, sdk_version, product_build,
+ fuchsia_device.board_type)
+ else:
+ # Must be a fully qualified build number (e.g. 5.20210721.4.1215)
+ file_to_download = '{}/{}/images/{}.{}-release.tgz'.format(
+ FUCHSIA_SDK_URL, fuchsia_device.build_number, product_build,
+ fuchsia_device.board_type)
+ elif 'gs://' in fuchsia_device.specific_image:
+ file_download_needed = True
+ file_to_download = fuchsia_device.specific_image
+ elif tarfile.is_tarfile(fuchsia_device.specific_image):
+ file_download_needed = False
+ file_to_download = fuchsia_device.specific_image
+ else:
+ raise ValueError('A suitable build could not be found.')
+
+ tmp_path = '/tmp/%s_%s' % (str(int(
+ time.time() * 10000)), fuchsia_device.board_type)
+ os.mkdir(tmp_path)
+ if file_download_needed:
+ job.run('gsutil cp %s %s' % (file_to_download, tmp_path))
+ logging.info('Downloading %s to %s' % (file_to_download, tmp_path))
+ image_tgz = os.path.basename(file_to_download)
+ else:
+ job.run('cp %s %s' % (fuchsia_device.specific_image, tmp_path))
+ logging.info('Copying %s to %s' % (file_to_download, tmp_path))
+ image_tgz = os.path.basename(fuchsia_device.specific_image)
+
+ job.run('tar xfvz %s/%s -C %s' % (tmp_path, image_tgz, tmp_path))
+ all_files = []
+ for root, _dirs, files in itertools.islice(os.walk(tmp_path), 1, None):
+ for filename in files:
+ all_files.append(os.path.join(root, filename))
+ for filename in all_files:
+ shutil.move(filename, tmp_path)
+
+ if use_ssh:
+ logging.info('Sending reboot command via SSH to '
+ 'get into bootloader.')
+ with utils.SuppressLogOutput():
+ fuchsia_device.clean_up_services()
+ # Sending this command will put the device in fastboot
+ # but it does not guarantee the device will be in fastboot
+ # after this command. There is no check so if there is an
+ # expectation of the device being in fastboot, then some
+ # other check needs to be done.
+ fuchsia_device.send_command_ssh(
+ 'dm rb',
+ timeout=fuchsia_reconnect_after_reboot_time,
+ skip_status_code_check=True)
+ else:
+ pass
+ ## Todo: Add elif for SL4F if implemented in SL4F
+
+ time_counter = 0
+ while time_counter < FASTBOOT_TIMEOUT:
+ logging.info('Checking to see if fuchsia_device(%s) SN: %s is in '
+ 'fastboot. (Attempt #%s Timeout: %s)' %
+ (fuchsia_device.orig_ip, fuchsia_device.serial_number,
+ str(time_counter + 1), FASTBOOT_TIMEOUT))
+ for usb_device in usbinfo.usbinfo():
+ if (usb_device['iSerialNumber'] == fuchsia_device.serial_number
+ and usb_device['iProduct'] == 'USB_download_gadget'):
+ logging.info(
+ 'fuchsia_device(%s) SN: %s is in fastboot.' %
+ (fuchsia_device.orig_ip, fuchsia_device.serial_number))
+ time_counter = FASTBOOT_TIMEOUT
+ time_counter = time_counter + 1
+ if time_counter == FASTBOOT_TIMEOUT:
+ for fail_usb_device in usbinfo.usbinfo():
+ logging.debug(fail_usb_device)
+ raise TimeoutError(
+ 'fuchsia_device(%s) SN: %s '
+ 'never went into fastboot' %
+ (fuchsia_device.orig_ip, fuchsia_device.serial_number))
+ time.sleep(1)
+
+ end_time = time.time() + WAIT_FOR_EXISTING_FLASH_TO_FINISH_SEC
+ # Attempt to wait for existing flashing process to finish
+ while time.time() < end_time:
+ flash_process_found = False
+ for proc in psutil.process_iter():
+ if "bash" in proc.name() and "flash.sh" in proc.cmdline():
+ logging.info(
+ "Waiting for existing flash.sh process to complete.")
+ time.sleep(PROCESS_CHECK_WAIT_TIME_SEC)
+ flash_process_found = True
+ if not flash_process_found:
+ break
+ logging.info(f'Flashing {fuchsia_device.orig_ip} with {tmp_path}/{image_tgz} using authorized keys "{fuchsia_device.authorized_file}".')
+ try:
+ flash_output = job.run(f'bash {tmp_path}/flash.sh --ssh-key={fuchsia_device.authorized_file} -s {fuchsia_device.serial_number}', timeout=120)
+ logging.debug(flash_output.stderr)
+ except job.TimeoutError as err:
+ raise TimeoutError(err)
+ try:
+ os.rmdir(tmp_path)
+ except Exception:
+ job.run('rm -fr %s' % tmp_path)
+ logging.info('Waiting %s seconds for device'
+ ' to come back up after flashing.' % AFTER_FLASH_BOOT_TIME)
+ time.sleep(AFTER_FLASH_BOOT_TIME)
+ logging.info('Updating device to new IP addresses.')
+ mdns_ip = None
+ for retry_counter in range(MDNS_LOOKUP_RETRY_MAX):
+ mdns_ip = get_fuchsia_mdns_ipv6_address(fuchsia_device.orig_ip)
+ if mdns_ip:
+ break
+ else:
+ time.sleep(1)
+ if mdns_ip and utils.is_valid_ipv6_address(mdns_ip):
+ logging.info('IP for fuchsia_device(%s) changed from %s to %s' %
+ (fuchsia_device.orig_ip, fuchsia_device.ip, mdns_ip))
+ fuchsia_device.ip = mdns_ip
+ fuchsia_device.address = "http://[{}]:{}".format(
+ fuchsia_device.ip, fuchsia_device.sl4f_port)
+ fuchsia_device.init_address = fuchsia_device.address + "/init"
+ fuchsia_device.cleanup_address = fuchsia_device.address + "/cleanup"
+ fuchsia_device.print_address = fuchsia_device.address + "/print_clients"
+ fuchsia_device.init_libraries()
+ else:
+ raise ValueError('Invalid IP: %s after flashing.' %
+ fuchsia_device.orig_ip)
+ return True
diff --git a/acts/framework/acts/controllers/fuchsia_lib/wlan_lib.py b/acts/framework/acts/controllers/fuchsia_lib/wlan_lib.py
index 8247041..d3dc448 100644
--- a/acts/framework/acts/controllers/fuchsia_lib/wlan_lib.py
+++ b/acts/framework/acts/controllers/fuchsia_lib/wlan_lib.py
@@ -25,6 +25,7 @@
COMMAND_GET_PHY_ID_LIST = "wlan.get_phy_id_list"
COMMAND_DESTROY_IFACE = "wlan.destroy_iface"
COMMAND_GET_COUNTRY = "wlan_phy.get_country"
+COMMAND_GET_DEV_PATH = "wlan_phy.get_dev_path"
COMMAND_QUERY_IFACE = "wlan.query_iface"
@@ -130,18 +131,25 @@
return self.send_command(test_id, test_cmd, {})
- def wlanStatus(self):
+ def wlanStatus(self, iface_id=None):
""" Request connection status
+ Args:
+ iface_id: unsigned 16-bit int, the wlan interface id
+ (defaults to None)
+
Returns:
Client state summary containing WlanClientState and
status of various networks connections
"""
test_cmd = COMMAND_STATUS
+ test_args = {}
+ if iface_id:
+ test_args = {'iface_id': iface_id}
test_id = self.build_id(self.test_counter)
self.test_counter += 1
- return self.send_command(test_id, test_cmd, {})
+ return self.send_command(test_id, test_cmd, test_args)
def wlanGetCountry(self, phy_id):
""" Reads the currently configured country for `phy_id`.
@@ -159,6 +167,22 @@
return self.send_command(test_id, test_cmd, test_args)
+ def wlanGetDevPath(self, phy_id):
+ """ Queries the device path for `phy_id`.
+
+ Args:
+ phy_id: unsigned 16-bit integer.
+
+ Returns:
+ Dictionary, String if success, error if error.
+ """
+ test_cmd = COMMAND_GET_DEV_PATH
+ test_args = {"phy_id": phy_id}
+ test_id = self.build_id(self.test_counter)
+ self.test_counter += 1
+
+ return self.send_command(test_id, test_cmd, test_args)
+
def wlanQueryInterface(self, iface_id):
""" Retrieves interface info for given wlan iface id.
diff --git a/acts/framework/acts/controllers/iperf_client.py b/acts/framework/acts/controllers/iperf_client.py
index b31d54f..6c889b1 100644
--- a/acts/framework/acts/controllers/iperf_client.py
+++ b/acts/framework/acts/controllers/iperf_client.py
@@ -36,6 +36,7 @@
from acts.event.event import TestClassEndEvent
from acts.libs.proc import job
from paramiko.buffered_pipe import PipeTimeout
+from paramiko.ssh_exception import SSHException
MOBLY_CONTROLLER_CONFIG_NAME = 'IPerfClient'
ACTS_CONTROLLER_REFERENCE_NAME = 'iperf_clients'
@@ -243,8 +244,10 @@
except socket.timeout:
raise TimeoutError('Socket timeout. Timed out waiting for iperf '
'client to finish.')
- except Exception as e:
- logging.exception('iperf run failed.')
+ except SSHException as err:
+ raise ConnectionError('SSH connection failed: {}'.format(err))
+ except Exception as err:
+ logging.exception('iperf run failed: {}'.format(err))
return full_out_path
diff --git a/acts/framework/acts/controllers/openwrt_ap.py b/acts/framework/acts/controllers/openwrt_ap.py
index ac0712d..482c901 100644
--- a/acts/framework/acts/controllers/openwrt_ap.py
+++ b/acts/framework/acts/controllers/openwrt_ap.py
@@ -3,21 +3,25 @@
import random
import re
import time
+
from acts import logger
from acts import signals
from acts.controllers.ap_lib import hostapd_constants
from acts.controllers.openwrt_lib import network_settings
from acts.controllers.openwrt_lib import wireless_config
from acts.controllers.openwrt_lib import wireless_settings_applier
+from acts.controllers.openwrt_lib.openwrt_constants import OpenWrtModelMap as modelmap
+from acts.controllers.openwrt_lib.openwrt_constants import OpenWrtWifiSetting
+from acts.controllers.openwrt_lib.openwrt_constants import SYSTEM_INFO_CMD
from acts.controllers.utils_lib.ssh import connection
from acts.controllers.utils_lib.ssh import settings
-from acts.controllers.openwrt_lib.openwrt_constants import OpenWrtWifiSetting
import yaml
+
MOBLY_CONTROLLER_CONFIG_NAME = "OpenWrtAP"
ACTS_CONTROLLER_REFERENCE_NAME = "access_points"
OPEN_SECURITY = "none"
-PSK1_SECURITY = 'psk'
+PSK1_SECURITY = "psk"
PSK_SECURITY = "psk2"
WEP_SECURITY = "wep"
ENT_SECURITY = "wpa2"
@@ -99,7 +103,9 @@
ssh_settings: The ssh settings being used by the ssh connection.
log: Logging object for AccessPoint.
wireless_setting: object holding wireless configuration.
- network_setting: Object for network configuration
+ network_setting: Object for network configuration.
+ model: OpenWrt HW model.
+ radios: Fit interface for test.
"""
def __init__(self, config):
@@ -111,6 +117,11 @@
self.wireless_setting = None
self.network_setting = network_settings.NetworkSettings(
self.ssh, self.ssh_settings, self.log)
+ self.model = self.get_model_name()
+ if self.model in modelmap.__dict__:
+ self.radios = modelmap.__dict__[self.model]
+ else:
+ self.radios = DEFAULT_RADIOS
def configure_ap(self, wifi_configs, channel_2g, channel_5g):
"""Configure AP with the required settings.
@@ -150,7 +161,7 @@
# 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.ssh, wireless_configs, channel_2g, channel_5g, self.radios[1], self.radios[0])
self.wireless_setting.apply_wireless_settings()
def start_ap(self):
@@ -182,31 +193,16 @@
Dictionary of SSID - BSSID map for both bands.
"""
bssid_map = {"2g": {}, "5g": {}}
- for radio in ["radio0", "radio1"]:
+ for radio in self.radios:
ssid_ifname_map = self.get_ifnames_for_ssids(radio)
- if radio == "radio0":
+ if radio == self.radios[0]:
for ssid, ifname in ssid_ifname_map.items():
bssid_map["5g"][ssid] = self.get_bssid(ifname)
- elif radio == "radio1":
+ elif radio == self.radios[1]:
for ssid, ifname in ssid_ifname_map.items():
bssid_map["2g"][ssid] = self.get_bssid(ifname)
return bssid_map
- def get_wifi_status(self):
- """Check if radios are up for both 2G and 5G bands.
-
- Returns:
- True if both radios are up. False if not.
- """
- radios = ["radio0", "radio1"]
- status = True
- for radio in radios:
- str_output = self.ssh.run("wifi status %s" % radio).stdout
- wifi_status = yaml.load(str_output.replace("\t", "").replace("\n", ""),
- Loader=yaml.FullLoader)
- status = wifi_status[radio]["up"] and status
- return status
-
def get_ifnames_for_ssids(self, radio):
"""Get interfaces for wifi networks.
@@ -219,7 +215,7 @@
ssid_ifname_map = {}
str_output = self.ssh.run("wifi status %s" % radio).stdout
wifi_status = yaml.load(str_output.replace("\t", "").replace("\n", ""),
- Loader=yaml.FullLoader)
+ Loader=yaml.SafeLoader)
wifi_status = wifi_status[radio]
if wifi_status["up"]:
interfaces = wifi_status["interfaces"]
@@ -250,32 +246,32 @@
"""
str_output = self.ssh.run("wifi status").stdout
wifi_status = yaml.load(str_output.replace("\t", "").replace("\n", ""),
- Loader=yaml.FullLoader)
+ Loader=yaml.SafeLoader)
# Counting how many interface are enabled.
total_interface = 0
- for radio in ["radio0", "radio1"]:
- num_interface = len(wifi_status[radio]['interfaces'])
+ for radio in self.radios:
+ num_interface = len(wifi_status[radio]["interfaces"])
total_interface += num_interface
# Iterates every interface to get and set wpa encryption.
default_extra_interface = 2
for i in range(total_interface + default_extra_interface):
origin_encryption = self.ssh.run(
- 'uci get wireless.@wifi-iface[{}].encryption'.format(i)).stdout
- origin_psk_pattern = re.match(r'psk\b', origin_encryption)
- target_psk_pattern = re.match(r'psk\b', encryption)
- origin_psk2_pattern = re.match(r'psk2\b', origin_encryption)
- target_psk2_pattern = re.match(r'psk2\b', encryption)
+ "uci get wireless.@wifi-iface[{}].encryption".format(i)).stdout
+ origin_psk_pattern = re.match(r"psk\b", origin_encryption)
+ target_psk_pattern = re.match(r"psk\b", encryption)
+ origin_psk2_pattern = re.match(r"psk2\b", origin_encryption)
+ target_psk2_pattern = re.match(r"psk2\b", encryption)
if origin_psk_pattern == target_psk_pattern:
self.ssh.run(
- 'uci set wireless.@wifi-iface[{}].encryption={}'.format(
+ "uci set wireless.@wifi-iface[{}].encryption={}".format(
i, encryption))
if origin_psk2_pattern == target_psk2_pattern:
self.ssh.run(
- 'uci set wireless.@wifi-iface[{}].encryption={}'.format(
+ "uci set wireless.@wifi-iface[{}].encryption={}".format(
i, encryption))
self.ssh.run("uci commit wireless")
@@ -296,7 +292,7 @@
self.log.error("Password must only contains ascii letters and digits")
else:
self.ssh.run(
- 'uci set wireless.@wifi-iface[{}].key={}'.format(3, pwd_5g))
+ "uci set wireless.@wifi-iface[{}].key={}".format(3, pwd_5g))
self.log.info("Set 5G password to :{}".format(pwd_5g))
if pwd_2g:
@@ -307,7 +303,7 @@
self.log.error("Password must only contains ascii letters and digits")
else:
self.ssh.run(
- 'uci set wireless.@wifi-iface[{}].key={}'.format(2, pwd_2g))
+ "uci set wireless.@wifi-iface[{}].key={}".format(2, pwd_2g))
self.log.info("Set 2G password to :{}".format(pwd_2g))
self.ssh.run("uci commit wireless")
@@ -326,7 +322,7 @@
# Only accept ascii letters and digits
else:
self.ssh.run(
- 'uci set wireless.@wifi-iface[{}].ssid={}'.format(3, ssid_5g))
+ "uci set wireless.@wifi-iface[{}].ssid={}".format(3, ssid_5g))
self.log.info("Set 5G SSID to :{}".format(ssid_5g))
if ssid_2g:
@@ -335,42 +331,44 @@
# Only accept ascii letters and digits
else:
self.ssh.run(
- 'uci set wireless.@wifi-iface[{}].ssid={}'.format(2, ssid_2g))
+ "uci set wireless.@wifi-iface[{}].ssid={}".format(2, ssid_2g))
self.log.info("Set 2G SSID to :{}".format(ssid_2g))
self.ssh.run("uci commit wireless")
self.ssh.run("wifi")
def generate_mobility_domain(self):
- """Generate 4-character hexadecimal ID
+ """Generate 4-character hexadecimal ID.
- Returns: String; a 4-character hexadecimal ID.
- """
- md = "{:04x}".format(random.getrandbits(16))
- self.log.info("Mobility Domain ID: {}".format(md))
- return md
+ Returns:
+ String; a 4-character hexadecimal ID.
+ """
+ md = "{:04x}".format(random.getrandbits(16))
+ self.log.info("Mobility Domain ID: {}".format(md))
+ return md
def enable_80211r(self, iface, md):
"""Enable 802.11r for one single radio.
- Args:
- iface: index number of wifi-iface.
+ Args:
+ iface: index number of wifi-iface.
2: radio1
3: radio0
- md: mobility domain. a 4-character hexadecimal ID.
- Raises: TestSkip if 2g or 5g radio is not up or 802.11r is not enabled.
- """
+ md: mobility domain. a 4-character hexadecimal ID.
+ Raises:
+ TestSkip if 2g or 5g radio is not up or 802.11r is not enabled.
+ """
str_output = self.ssh.run("wifi status").stdout
wifi_status = yaml.load(str_output.replace("\t", "").replace("\n", ""),
- Loader=yaml.FullLoader)
+ Loader=yaml.SafeLoader)
# Check if the radio is up.
if iface == OpenWrtWifiSetting.IFACE_2G:
- if wifi_status['radio1']['up']:
+ if wifi_status[self.radios[1]]["up"]:
self.log.info("2g network is ENABLED")
else:
raise signals.TestSkip("2g network is NOT ENABLED")
elif iface == OpenWrtWifiSetting.IFACE_5G:
- if wifi_status['radio0']['up']:
+ if wifi_status[self.radios[0]]["up"]:
self.log.info("5g network is ENABLED")
else:
raise signals.TestSkip("5g network is NOT ENABLED")
@@ -380,10 +378,10 @@
"uci set wireless.@wifi-iface[{}].ieee80211r='1'".format(iface))
self.ssh.run(
"uci set wireless.@wifi-iface[{}].ft_psk_generate_local='1'"
- .format(iface))
+ .format(iface))
self.ssh.run(
"uci set wireless.@wifi-iface[{}].mobility_domain='{}'"
- .format(iface, md))
+ .format(iface, md))
self.ssh.run(
"uci commit wireless")
self.ssh.run("wifi")
@@ -391,7 +389,7 @@
# Check if 802.11r is enabled.
result = self.ssh.run(
"uci get wireless.@wifi-iface[{}].ieee80211r".format(iface)).stdout
- if result == '1':
+ if result == "1":
self.log.info("802.11r is ENABLED")
else:
raise signals.TestSkip("802.11r is NOT ENABLED")
@@ -588,27 +586,24 @@
return wifi_network
return None
- def get_wifi_status(self, radios=DEFAULT_RADIOS):
+ def get_wifi_status(self):
"""Check if radios are up. Default are 2G and 5G bands.
- Args:
- radios: Wifi interfaces for check status.
Returns:
True if both radios are up. False if not.
"""
status = True
- for radio in radios:
+ for radio in self.radios:
str_output = self.ssh.run("wifi status %s" % radio).stdout
wifi_status = yaml.load(str_output.replace("\t", "").replace("\n", ""),
- Loader=yaml.FullLoader)
+ Loader=yaml.SafeLoader)
status = wifi_status[radio]["up"] and status
return status
- def verify_wifi_status(self, radios=DEFAULT_RADIOS, timeout=20):
+ def verify_wifi_status(self, timeout=20):
"""Ensure wifi interfaces are ready.
Args:
- radios: Wifi interfaces for check status.
timeout: An integer that is the number of times to try
wait for interface ready.
Returns:
@@ -617,11 +612,25 @@
start_time = time.time()
end_time = start_time + timeout
while time.time() < end_time:
- if self.get_wifi_status(radios):
+ if self.get_wifi_status():
return True
time.sleep(1)
return False
+ def get_model_name(self):
+ """Get Openwrt model name.
+
+ Returns:
+ A string include device brand and model. e.g. NETGEAR_R8000
+ """
+ out = self.ssh.run(SYSTEM_INFO_CMD).stdout.split("\n")
+ for line in out:
+ if "board_name" in line:
+ model = (line.split()[1].strip("\",").split(","))
+ return "_".join(map(lambda i: i.upper(), model))
+ self.log.info("Failed to retrieve OpenWrt model information.")
+ return None
+
def close(self):
"""Reset wireless and network settings to default and stop AP."""
if self.network_setting.config:
@@ -632,3 +641,8 @@
def close_ssh(self):
"""Close SSH connection to AP."""
self.ssh.close()
+
+ def reboot(self):
+ """Reboot Openwrt."""
+ self.ssh.run("reboot")
+
diff --git a/acts/framework/acts/controllers/openwrt_lib/OWNERS b/acts/framework/acts/controllers/openwrt_lib/OWNERS
index 1840d87..6ddb5ea 100644
--- a/acts/framework/acts/controllers/openwrt_lib/OWNERS
+++ b/acts/framework/acts/controllers/openwrt_lib/OWNERS
@@ -1,3 +1,4 @@
jerrypcchen@google.com
gmoturu@google.com
martschneider@google.com
+sishichen@google.com
diff --git a/acts/framework/acts/controllers/openwrt_lib/network_const.py b/acts/framework/acts/controllers/openwrt_lib/network_const.py
index 0a3fb42..3aba0de 100644
--- a/acts/framework/acts/controllers/openwrt_lib/network_const.py
+++ b/acts/framework/acts/controllers/openwrt_lib/network_const.py
@@ -1,3 +1,5 @@
+LOCALHOST = "192.168.1.1"
+
# params for ipsec.conf
IPSEC_CONF = {
"config setup": {
@@ -15,7 +17,7 @@
"conn L2TP_PSK": {
"keyexchange": "ikev1",
"type": "transport",
- "left": "192.168.1.1",
+ "left": LOCALHOST,
"leftprotoport": "17/1701",
"leftauth": "psk",
"right": "%any",
@@ -30,7 +32,7 @@
"conn L2TP_RSA": {
"keyexchange": "ikev1",
"type": "transport",
- "left": "192.168.1.1",
+ "left": LOCALHOST,
"leftprotoport": "17/1701",
"leftauth": "pubkey",
"leftcert": "serverCert.der",
@@ -45,7 +47,7 @@
IPSEC_HYBRID_RSA = {
"conn HYBRID_RSA": {
"keyexchange": "ikev1",
- "left": "192.168.1.1",
+ "left": LOCALHOST,
"leftsubnet": "0.0.0.0/0",
"leftauth": "pubkey",
"leftcert": "serverCert.der",
@@ -62,7 +64,7 @@
IPSEC_XAUTH_PSK = {
"conn XAUTH_PSK": {
"keyexchange": "ikev1",
- "left": "192.168.1.1",
+ "left": LOCALHOST,
"leftsubnet": "0.0.0.0/0",
"leftauth": "psk",
"right": "%any",
@@ -76,7 +78,7 @@
IPSEC_XAUTH_RSA = {
"conn XAUTH_RSA": {
"keyexchange": "ikev1",
- "left": "192.168.1.1",
+ "left": LOCALHOST,
"leftsubnet": "0.0.0.0/0",
"leftcert": "serverCert.der",
"leftsendcert": "always",
@@ -88,6 +90,100 @@
}
}
+IPSEC_IKEV2_MSCHAPV2 = {
+ "conn IKEV2_MSCHAPV2": {
+ "keyexchange": "ikev2",
+ "left": LOCALHOST,
+ "leftid": LOCALHOST,
+ "leftcert": "serverCert.der",
+ "leftsubnet": "0.0.0.0/0",
+ "leftauth": "pubkey",
+ "leftsendcert": "always",
+ "right": "%any",
+ "rightid": "vpntest",
+ "rightauth": "eap-mschapv2",
+ "auto": "add"
+ }
+}
+
+IPSEC_IKEV2_PSK = {
+ "conn IKEV2_PSK": {
+ "keyexchange": "ikev2",
+ "left": LOCALHOST,
+ "leftid": LOCALHOST,
+ "leftauth": "psk",
+ "leftsubnet": "0.0.0.0/0",
+ "right": "%any",
+ "rightid": "vpntest",
+ "rightauth": "psk",
+ "auto": "add"
+ }
+}
+
+IPSEC_IKEV2_RSA = {
+ "conn IKEV2_RSA": {
+ "keyexchange": "ikev2",
+ "left": LOCALHOST,
+ "leftid": LOCALHOST,
+ "leftcert": "serverCert.der",
+ "leftsubnet": "0.0.0.0/0",
+ "leftauth": "pubkey",
+ "leftsendcert": "always",
+ "right": "%any",
+ "rightid": "vpntest@%s" % LOCALHOST,
+ "rightauth": "pubkey",
+ "rightcert": "clientCert.pem",
+ "auto": "add"
+ }
+}
+
+IPSEC_IKEV2_MSCHAPV2_HOSTNAME = {
+ "conn IKEV2_MSCHAPV2_HOSTNAME": {
+ "keyexchange": "ikev2",
+ "left": LOCALHOST,
+ "leftid": "strongswan-vpn-server.android-iperf.com",
+ "leftcert": "serverCert.der",
+ "leftsubnet": "0.0.0.0/0",
+ "leftauth": "pubkey",
+ "leftsendcert": "always",
+ "right": "%any",
+ "rightid": "vpntest",
+ "rightauth": "eap-mschapv2",
+ "auto": "add"
+ }
+}
+
+IPSEC_IKEV2_PSK_HOSTNAME = {
+ "conn IKEV2_PSK_HOSTNAME": {
+ "keyexchange": "ikev2",
+ "left": LOCALHOST,
+ "leftid": "strongswan-vpn-server.android-iperf.com",
+ "leftauth": "psk",
+ "leftsubnet": "0.0.0.0/0",
+ "right": "%any",
+ "rightid": "vpntest",
+ "rightauth": "psk",
+ "auto": "add"
+ }
+}
+
+IPSEC_IKEV2_RSA_HOSTNAME = {
+ "conn IKEV2_RSA_HOSTNAME": {
+ "keyexchange": "ikev2",
+ "left": LOCALHOST,
+ "leftid": "strongswan-vpn-server.android-iperf.com",
+ "leftcert": "serverCert.der",
+ "leftsubnet": "0.0.0.0/0",
+ "leftauth": "pubkey",
+ "leftsendcert": "always",
+ "right": "%any",
+ "rightid": "vpntest@strongswan-vpn-server.android-iperf.com",
+ "rightauth": "pubkey",
+ "rightcert": "clientCert.pem",
+ "auto": "add"
+ }
+}
+
# parmas for lx2tpd
XL2TPD_CONF_GLOBAL = (
@@ -149,7 +245,6 @@
"iptables -I FORWARD -m policy --dir out --pol ipsec --proto esp -j ACCEPT",
"iptables -I OUTPUT -m policy --dir out --pol ipsec --proto esp -j ACCEPT",
"iptables -t nat -I POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT",
- "iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT",
"iptables -A INPUT -p esp -j ACCEPT",
"iptables -A INPUT -i eth0.2 -p udp --dport 500 -j ACCEPT",
"iptables -A INPUT -i eth0.2 -p tcp --dport 500 -j ACCEPT",
diff --git a/acts/framework/acts/controllers/openwrt_lib/network_settings.py b/acts/framework/acts/controllers/openwrt_lib/network_settings.py
index efbd590..b3c1e4e 100644
--- a/acts/framework/acts/controllers/openwrt_lib/network_settings.py
+++ b/acts/framework/acts/controllers/openwrt_lib/network_settings.py
@@ -28,11 +28,12 @@
SERVICE_IPSEC = "ipsec"
SERVICE_XL2TPD = "xl2tpd"
SERVICE_ODHCPD = "odhcpd"
-SERVICE_NODOGSPLASH = "nodogsplash"
+SERVICE_OPENNDS = "opennds"
+SERVICE_UHTTPD = "uhttpd"
PPTP_PACKAGE = "pptpd kmod-nf-nathelper-extra"
L2TP_PACKAGE = "strongswan-full openssl-util xl2tpd"
NAT6_PACKAGE = "ip6tables kmod-ipt-nat6"
-CAPTIVE_PORTAL_PACKAGE = "nodogsplash"
+CAPTIVE_PORTAL_PACKAGE = "opennds php7-cli php7-mod-openssl php7-cgi php7"
MDNS_PACKAGE = "avahi-utils avahi-daemon-service-http avahi-daemon-service-ssh libavahi-client avahi-dbus-daemon"
STUNNEL_CONFIG_PATH = "/etc/stunnel/DoTServer.conf"
HISTORY_CONFIG_PATH = "/etc/dirty_configs"
@@ -41,6 +42,7 @@
XL2TPD_OPTION_CONFIG_PATH = "/etc/ppp/options.xl2tpd"
FIREWALL_CUSTOM_OPTION_PATH = "/etc/firewall.user"
PPP_CHAP_SECRET_PATH = "/etc/ppp/chap-secrets"
+IKEV2_VPN_CERT_KEYS_PATH = "/var/ikev2_cert.sh"
TCPDUMP_DIR = "/tmp/tcpdump/"
LOCALHOST = "192.168.1.1"
DEFAULT_PACKAGE_INSTALL_TIMEOUT = 200
@@ -89,6 +91,7 @@
"ipv6_prefer_option": self.remove_ipv6_prefer_option,
"block_dns_response": self.unblock_dns_response,
"setup_mdns": self.remove_mdns,
+ "add_dhcp_rapid_commit": self.remove_dhcp_rapid_commit,
"setup_captive_portal": self.remove_cpative_portal
}
# This map contains cleanup functions to restore the configuration to
@@ -188,13 +191,28 @@
return False
def path_exists(self, abs_path):
- """Check if dir exist on OpenWrt."""
+ """Check if dir exist on OpenWrt.
+
+ Args:
+ abs_path: absolutely path for create folder.
+ """
try:
self.ssh.run("ls %s" % abs_path)
except:
return False
return True
+ def create_folder(self, abs_path):
+ """If dir not exist, create it.
+
+ Args:
+ abs_path: absolutely path for create folder.
+ """
+ if not self.path_exists(abs_path):
+ self.ssh.run("mkdir %s" % abs_path)
+ else:
+ self.log.info("%s already existed." %abs_path)
+
def count(self, config, key):
"""Count in uci config.
@@ -446,7 +464,11 @@
# setup vpn server local ip
self.setup_vpn_local_ip()
# generate cert and key for rsa
- self.generate_vpn_cert_keys(country, org)
+ if self.l2tp.name == "ikev2-server":
+ self.generate_ikev2_vpn_cert_keys(country, org)
+ self.add_resource_record(self.l2tp.hostname, LOCALHOST)
+ else:
+ self.generate_vpn_cert_keys(country, org)
# restart service
self.service_manager.need_restart(SERVICE_IPSEC)
self.service_manager.need_restart(SERVICE_XL2TPD)
@@ -458,6 +480,8 @@
self.config.discard("setup_vpn_l2tp_server")
self.restore_firewall_rules_for_l2tp()
self.remove_vpn_local_ip()
+ if self.l2tp.name == "ikev2-server":
+ self.clear_resource_record()
self.service_manager.need_restart(SERVICE_IPSEC)
self.service_manager.need_restart(SERVICE_XL2TPD)
self.service_manager.need_restart(SERVICE_FIREWALL)
@@ -491,6 +515,12 @@
config.append("")
config = []
+ load_ipsec_config(network_const.IPSEC_IKEV2_MSCHAPV2, True)
+ load_ipsec_config(network_const.IPSEC_IKEV2_PSK, True)
+ load_ipsec_config(network_const.IPSEC_IKEV2_RSA, True)
+ load_ipsec_config(network_const.IPSEC_IKEV2_MSCHAPV2_HOSTNAME, True)
+ load_ipsec_config(network_const.IPSEC_IKEV2_PSK_HOSTNAME, True)
+ load_ipsec_config(network_const.IPSEC_IKEV2_RSA_HOSTNAME, True)
load_ipsec_config(network_const.IPSEC_CONF)
load_ipsec_config(network_const.IPSEC_L2TP_PSK)
load_ipsec_config(network_const.IPSEC_L2TP_RSA)
@@ -584,6 +614,54 @@
self.ssh.run("mv clientPkcs.p12 /www/downloads/")
self.ssh.run("chmod 664 /www/downloads/clientPkcs.p12")
+ def generate_ikev2_vpn_cert_keys(self, country, org):
+ rsa = "--type rsa"
+ lifetime = "--lifetime 365"
+ size = "--size 4096"
+
+ if not self.path_exists("/www/downloads/"):
+ self.ssh.run("mkdir /www/downloads/")
+
+ ikev2_vpn_cert_keys = [
+ "ipsec pki --gen %s %s --outform der > caKey.der" % (rsa, size),
+ "ipsec pki --self --ca %s --in caKey.der %s --dn "
+ "\"C=%s, O=%s, CN=%s\" --outform der > caCert.der" %
+ (lifetime, rsa, country, org, self.l2tp.hostname),
+ "ipsec pki --gen %s %s --outform der > serverKey.der" % (size, rsa),
+ "ipsec pki --pub --in serverKey.der %s | ipsec pki --issue %s "
+ r"--cacert caCert.der --cakey caKey.der --dn \"C=%s, O=%s, CN=%s\" "
+ "--san %s --san %s --flag serverAuth --flag ikeIntermediate "
+ "--outform der > serverCert.der" % (rsa, lifetime, country, org,
+ self.l2tp.hostname, LOCALHOST,
+ self.l2tp.hostname),
+ "ipsec pki --gen %s %s --outform der > clientKey.der" % (size, rsa),
+ "ipsec pki --pub --in clientKey.der %s | ipsec pki --issue %s "
+ r"--cacert caCert.der --cakey caKey.der --dn \"C=%s, O=%s, CN=%s@%s\" "
+ r"--san \"%s\" --san \"%s@%s\" --san \"%s@%s\" --outform der "
+ "> clientCert.der" % (rsa, lifetime, country, org, self.l2tp.username,
+ self.l2tp.hostname, self.l2tp.username,
+ self.l2tp.username, LOCALHOST,
+ self.l2tp.username, self.l2tp.hostname),
+ "openssl rsa -inform DER -in clientKey.der "
+ "-out clientKey.pem -outform PEM",
+ "openssl x509 -inform DER -in clientCert.der "
+ "-out clientCert.pem -outform PEM",
+ "openssl x509 -inform DER -in caCert.der "
+ "-out caCert.pem -outform PEM",
+ "openssl pkcs12 -in clientCert.pem -inkey clientKey.pem "
+ "-certfile caCert.pem -export -out clientPkcs.p12 -passout pass:",
+ "mv caCert.pem /etc/ipsec.d/cacerts/",
+ "mv *Cert* /etc/ipsec.d/certs/",
+ "mv *Key* /etc/ipsec.d/private/",
+ "mv clientPkcs.p12 /www/downloads/",
+ "chmod 664 /www/downloads/clientPkcs.p12",
+ ]
+ file_string = "\n".join(ikev2_vpn_cert_keys)
+ self.create_config_file(file_string, IKEV2_VPN_CERT_KEYS_PATH)
+
+ self.ssh.run("chmod +x %s" % IKEV2_VPN_CERT_KEYS_PATH)
+ self.ssh.run("%s" % IKEV2_VPN_CERT_KEYS_PATH)
+
def update_firewall_rules_list(self):
"""Update rule list in /etc/config/firewall."""
new_rules_list = []
@@ -838,6 +916,18 @@
self.service_manager.need_restart(SERVICE_DNSMASQ)
self.commit_changes()
+ def add_dhcp_rapid_commit(self):
+ self.create_config_file("dhcp-rapid-commit\n","/etc/dnsmasq.conf")
+ self.config.add("add_dhcp_rapid_commit")
+ self.service_manager.need_restart(SERVICE_DNSMASQ)
+ self.commit_changes()
+
+ def remove_dhcp_rapid_commit(self):
+ self.create_config_file("","/etc/dnsmasq.conf")
+ self.config.discard("add_dhcp_rapid_commit")
+ self.service_manager.need_restart(SERVICE_DNSMASQ)
+ self.commit_changes()
+
def start_tcpdump(self, test_name, args="", interface="br-lan"):
""""Start tcpdump on OpenWrt.
@@ -849,6 +939,7 @@
tcpdump_file_name: tcpdump file name on OpenWrt.
pid: tcpdump process id.
"""
+ self.package_install("tcpdump")
if not self.path_exists(TCPDUMP_DIR):
self.ssh.run("mkdir %s" % TCPDUMP_DIR)
tcpdump_file_name = "openwrt_%s_%s.pcap" % (test_name,
@@ -889,9 +980,11 @@
return tcpdump_remote_path if pull_dir else None
def clear_tcpdump(self):
- self.ssh.run("killall tpcdump", ignore_status=True)
- if self.ssh.run("pgrep tpcdump", ignore_status=True).stdout:
+ self.ssh.run("killall tcpdump", ignore_status=True)
+ if self.ssh.run("pgrep tcpdump", ignore_status=True).stdout:
raise signals.TestFailure("Failed to clean up tcpdump process.")
+ if self.path_exists(TCPDUMP_DIR):
+ self.ssh.run("rm -f %s/*" % TCPDUMP_DIR)
def _get_tcpdump_pid(self, tcpdump_file_name):
"""Check tcpdump process on OpenWrt."""
@@ -920,15 +1013,54 @@
self.service_manager.need_restart(SERVICE_FIREWALL)
self.commit_changes()
- def setup_captive_portal(self):
+ def setup_captive_portal(self, fas_fdqn,fas_port=2080):
+ """Create captive portal with Forwarding Authentication Service.
+
+ Args:
+ fas_fdqn: String for captive portal page's fdqn add to local dns server.
+ fas_port: Port for captive portal page.
+ """
self.package_install(CAPTIVE_PORTAL_PACKAGE)
- self.config.add("setup_captive_portal")
- self.service_manager.need_restart(SERVICE_NODOGSPLASH)
+ self.config.add("setup_captive_portal %s" % fas_port)
+ self.ssh.run("uci set opennds.@opennds[0].fas_secure_enabled=2")
+ self.ssh.run("uci set opennds.@opennds[0].gatewayport=2050")
+ self.ssh.run("uci set opennds.@opennds[0].fasport=%s" % fas_port)
+ self.ssh.run("uci set opennds.@opennds[0].fasremotefqdn=%s" % fas_fdqn)
+ self.ssh.run("uci set opennds.@opennds[0].faspath=\"/nds/fas-aes.php\"")
+ self.ssh.run("uci set opennds.@opennds[0].faskey=1234567890")
+ self.service_manager.need_restart(SERVICE_OPENNDS)
+ # Config uhttpd
+ self.ssh.run("uci set uhttpd.main.interpreter=.php=/usr/bin/php-cgi")
+ self.ssh.run("uci add_list uhttpd.main.listen_http=0.0.0.0:%s" % fas_port)
+ self.ssh.run("uci add_list uhttpd.main.listen_http=[::]:%s" % fas_port)
+ self.service_manager.need_restart(SERVICE_UHTTPD)
+ # cp fas-aes.php
+ self.create_folder("/www/nds/")
+ self.ssh.run("cp /etc/opennds/fas-aes.php /www/nds")
+ # Add fdqn
+ self.add_resource_record(fas_fdqn, LOCALHOST)
self.commit_changes()
- def remove_cpative_portal(self):
+ def remove_cpative_portal(self, fas_port=2080):
+ """Remove captive portal.
+
+ Args:
+ fas_port: Port for captive portal page.
+ """
+ # Remove package
self.package_remove(CAPTIVE_PORTAL_PACKAGE)
- self.config.discard("setup_captive_portal")
+ # Clean up config
+ self.ssh.run("rm /etc/config/opennds")
+ # Remove fdqn
+ self.clear_resource_record()
+ # Restore uhttpd
+ self.ssh.run("uci del uhttpd.main.interpreter")
+ self.ssh.run("uci del_list uhttpd.main.listen_http=\'0.0.0.0:%s\'" % fas_port)
+ self.ssh.run("uci del_list uhttpd.main.listen_http=\'[::]:%s\'" % fas_port)
+ self.service_manager.need_restart(SERVICE_UHTTPD)
+ # Clean web root
+ self.ssh.run("rm -r /www/nds")
+ self.config.discard("setup_captive_portal %s" % fas_port)
self.commit_changes()
diff --git a/acts/framework/acts/controllers/openwrt_lib/openwrt_constants.py b/acts/framework/acts/controllers/openwrt_lib/openwrt_constants.py
index 5ab4124..c0a408d 100644
--- a/acts/framework/acts/controllers/openwrt_lib/openwrt_constants.py
+++ b/acts/framework/acts/controllers/openwrt_lib/openwrt_constants.py
@@ -14,6 +14,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+SYSTEM_INFO_CMD = "ubus call system board"
+
+
class OpenWrtWifiSecurity:
# Used by OpenWrt AP
WPA_PSK_DEFAULT = "psk"
@@ -25,6 +28,11 @@
WPA2_PSK_TKIP = "psk2+tkip"
WPA2_PSK_TKIP_AND_CCMP = "psk2+tkip+ccmp"
+
class OpenWrtWifiSetting:
IFACE_2G = 2
- IFACE_5G = 3
\ No newline at end of file
+ IFACE_5G = 3
+
+
+class OpenWrtModelMap:
+ NETGEAR_R8000 = ("radio2", "radio1")
diff --git a/acts/framework/acts/controllers/openwrt_lib/wireless_settings_applier.py b/acts/framework/acts/controllers/openwrt_lib/wireless_settings_applier.py
index a366c02..dd37cc2 100644
--- a/acts/framework/acts/controllers/openwrt_lib/wireless_settings_applier.py
+++ b/acts/framework/acts/controllers/openwrt_lib/wireless_settings_applier.py
@@ -19,6 +19,8 @@
ENABLE_RADIO = "0"
DISABLE_RADIO = "1"
ENABLE_HIDDEN = "1"
+RADIO_2G = "radio1"
+RADIO_5G = "radio0"
class WirelessSettingsApplier(object):
@@ -33,7 +35,7 @@
channel_5g: channel for 5G band.
"""
- def __init__(self, ssh, configs, channel_2g, channel_5g):
+ def __init__(self, ssh, configs, channel_2g, channel_5g, radio_2g=RADIO_2G, radio_5g=RADIO_5G):
"""Initialize wireless settings.
Args:
@@ -48,59 +50,63 @@
self.wireless_configs = configs
self.channel_2g = channel_2g
self.channel_5g = channel_5g
+ self.radio_2g = radio_2g
+ self.radio_5g = radio_5g
def apply_wireless_settings(self):
"""Configure wireless settings from a list of configs."""
+ default_2g_iface = "default_" + self.radio_2g
+ default_5g_iface = "default_" + self.radio_5g
# 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)
+ self.ssh.run("uci set wireless.%s.channel='%s'" % (self.radio_2g, self.channel_2g))
+ self.ssh.run("uci set wireless.%s.channel='%s'" % (self.radio_5g, self.channel_5g))
if self.channel_5g == 165:
- self.ssh.run("uci set wireless.radio0.htmode='VHT20'")
+ self.ssh.run("uci set wireless.%s.htmode='VHT20'" % self.radio_5g)
elif self.channel_5g == 132 or self.channel_5g == 136:
self.ssh.run("iw reg set ZA")
- self.ssh.run("uci set wireless.radio0.htmode='VHT40'")
+ self.ssh.run("uci set wireless.%s.htmode='VHT40'" % self.radio_5g)
if self.channel_2g == 13:
self.ssh.run("iw reg set AU")
# 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)
+ self.ssh.run("uci set wireless.%s.disabled='%s'" %
+ (default_2g_iface, DISABLE_RADIO))
+ self.ssh.run("uci set wireless.%s.disabled='%s'" %
+ (default_5g_iface, 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)
+ self.ssh.run("uci set wireless.%s.disabled='%s'" % (self.radio_2g, ENABLE_RADIO))
+ self.ssh.run("uci set wireless.%s.disabled='%s'" % (self.radio_5g, 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)
+ self.ssh.run("uci set wireless.%s.ssid='%s'" %
+ (default_2g_iface, config.ssid))
+ self.ssh.run("uci set wireless.%s.disabled='%s'" %
+ (default_2g_iface, ENABLE_RADIO))
if config.hidden:
- self.ssh.run("uci set wireless.default_radio1.hidden='%s'" %
- ENABLE_HIDDEN)
+ self.ssh.run("uci set wireless.%s.hidden='%s'" %
+ (default_2g_iface, 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)
+ self.ssh.run("uci set wireless.%s.ssid='%s'" %
+ (default_5g_iface, config.ssid))
+ self.ssh.run("uci set wireless.%s.disabled='%s'" %
+ (default_5g_iface, ENABLE_RADIO))
if config.hidden:
- self.ssh.run("uci set wireless.default_radio0.hidden='%s'" %
- ENABLE_HIDDEN)
+ self.ssh.run("uci set wireless.%s.hidden='%s'" %
+ (default_5g_iface, 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)
+ self.ssh.run("uci set wireless.%s.device='%s'" % (config.name, self.radio_2g))
else:
- self.ssh.run("uci set wireless.%s.device='radio0'" % config.name)
+ self.ssh.run("uci set wireless.%s.device='%s'" % (config.name, self.radio_5g))
self.ssh.run("uci set wireless.%s.network='%s'" %
(config.name, config.iface))
self.ssh.run("uci set wireless.%s.mode='ap'" % config.name)
@@ -145,3 +151,4 @@
self.ssh.run("cp %s.tmp %s" % (LEASE_FILE, LEASE_FILE))
self.service_manager.restart(SERVICE_DNSMASQ)
time.sleep(9)
+
diff --git a/acts/framework/acts/controllers/rohdeschwarz_lib/cmw500.py b/acts/framework/acts/controllers/rohdeschwarz_lib/cmw500.py
index 5cbf766..755962e 100644
--- a/acts/framework/acts/controllers/rohdeschwarz_lib/cmw500.py
+++ b/acts/framework/acts/controllers/rohdeschwarz_lib/cmw500.py
@@ -86,7 +86,7 @@
class RbPosition(Enum):
- """Supported RB postions."""
+ """Supported RB positions."""
LOW = 'LOW'
HIGH = 'HIGH'
P5 = 'P5'
@@ -123,7 +123,7 @@
class MimoScenario(Enum):
- """Supportted mimo scenarios"""
+ """Supported mimo scenarios"""
SCEN1x1 = 'SCELl:FLEXible SUA1,RF1C,RX1,RF1C,TX1'
SCEN2x2 = 'TRO:FLEXible SUA1,RF1C,RX1,RF1C,TX1,RF3C,TX2'
SCEN4x4 = 'FRO FLEXible SUA1,RF1C,RX1,RF1C,TX1,RF3C,TX2,RF2C,TX3,RF4C,TX4'
@@ -319,7 +319,7 @@
Args:
state: the RRC state that is being waited for.
- timeout: timeout for phone to be in connnected state.
+ timeout: timeout for phone to be in connected state.
Raises:
CmwError on time out.
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 6f97160..dfd7116 100644
--- a/acts/framework/acts/controllers/rohdeschwarz_lib/cmw500_cellular_simulator.py
+++ b/acts/framework/acts/controllers/rohdeschwarz_lib/cmw500_cellular_simulator.py
@@ -39,13 +39,6 @@
LteSimulation.MimoMode.MIMO_4x4: cmw500.MimoModes.MIMO4x4
}
-CMW_MODULATION_MAPPING = {
- LteSimulation.ModulationType.QPSK: cmw500.ModulationType.QPSK,
- LteSimulation.ModulationType.Q16: cmw500.ModulationType.Q16,
- LteSimulation.ModulationType.Q64: cmw500.ModulationType.Q64,
- LteSimulation.ModulationType.Q256: cmw500.ModulationType.Q256
-}
-
# get mcs vs tbsi map with 256-qam disabled(downlink)
get_mcs_tbsi_map_dl = {
cmw500.ModulationType.QPSK: {
@@ -167,15 +160,6 @@
""" A cellular simulator for telephony simulations based on the CMW 500
controller. """
- # Indicates if it is able to use 256 QAM as the downlink modulation for LTE
- LTE_SUPPORTS_DL_256QAM = True
-
- # Indicates if it is able to use 64 QAM as the uplink modulation for LTE
- LTE_SUPPORTS_UL_64QAM = True
-
- # Indicates if 4x4 MIMO is supported for LTE
- LTE_SUPPORTS_4X4_MIMO = True
-
# The maximum number of carriers that this simulator can support for LTE
LTE_MAX_CARRIERS = 1
@@ -208,9 +192,13 @@
self.bts = [self.cmw.get_base_station()]
self.cmw.switch_lte_signalling(cmw500.LteState.LTE_ON)
- def setup_lte_ca_scenario(self):
- """ Configures the equipment for an LTE with CA simulation. """
- raise NotImplementedError()
+ def set_band_combination(self, bands):
+ """ Prepares the test equipment for the indicated band combination.
+
+ Args:
+ bands: a list of bands represented as ints or strings
+ """
+ self.num_carriers = len(bands)
def set_lte_rrc_state_change_timer(self, enabled, time=10):
""" Configures the LTE RRC state change timer.
@@ -442,7 +430,7 @@
time.sleep(1)
- if self.dl_modulation == cmw500.ModulationType.Q256:
+ if self.dl_256_qam_enabled:
tbs = get_mcs_tbsi_map_for_256qam_dl[
self.dl_modulation][mcs_dl]
else:
@@ -452,49 +440,36 @@
self.log.info('dl rb configurations set to {}'.format(
bts.rb_configuration_dl))
- def set_dl_modulation(self, bts_index, modulation):
- """ Sets the DL modulation for the indicated base station.
-
- This function does not actually configure the test equipment with this
- setting, but stores the value to be used later on when setting the
- scheduling type. This is because the CMW500 API only allows to set
- this parameters together.
+ def set_dl_256_qam_enabled(self, bts_index, enabled):
+ """ Determines what MCS table should be used for the downlink.
+ This only saves the setting that will be used when configuring MCS.
Args:
bts_index: the base station number
- modulation: the new DL modulation
+ enabled: whether 256 QAM should be used
"""
- # Convert dl modulation type to CMW modulation type.
- self.dl_modulation = CMW_MODULATION_MAPPING[modulation]
+ self.log.info('Set 256 QAM DL MCS enabled: ' + str(enabled))
+ self.dl_modulation = cmw500.ModulationType.Q256
+ self.dl_256_qam_enabled = True
- self.log.warning('Modulation config stored but not applied until '
- 'set_scheduling_mode called.')
-
- def set_ul_modulation(self, bts_index, modulation):
- """ Sets the UL modulation for the indicated base station.
-
- This function does not actually configure the test equipment with this
- setting, but stores the value to be used later on when setting the
- scheduling type. This is because the CMW500 API only allows to set
- this parameters together.
+ def set_ul_64_qam_enabled(self, bts_index, enabled):
+ """ Determines what MCS table should be used for the uplink.
+ This only saves the setting that will be used when configuring MCS.
Args:
bts_index: the base station number
- modulation: the new UL modulation
+ enabled: whether 64 QAM should be used
"""
+ self.log.info('Set 64 QAM UL MCS enabled: ' + str(enabled))
+ self.dl_modulation = cmw500.ModulationType.Q64
+ self.ul_64_qam_enabled = True
- # Convert ul modulation type to CMW modulation type.
- self.ul_modulation = CMW_MODULATION_MAPPING[modulation]
-
- self.log.warning('Modulation config stored but not applied until '
- 'set_scheduling_mode called.')
-
- def set_tbs_pattern_on(self, bts_index, tbs_pattern_on):
- """ Enables or disables TBS pattern in the indicated base station.
+ def set_mac_padding(self, bts_index, mac_padding):
+ """ Enables or disables MAC padding in the indicated base station.
Args:
bts_index: the base station number
- tbs_pattern_on: the new TBS pattern setting
+ mac_padding: the new MAC padding setting
"""
# TODO (b/143918664): CMW500 doesn't have an equivalent setting.
pass
diff --git a/acts/framework/acts/controllers/rohdeschwarz_lib/cmx500.py b/acts/framework/acts/controllers/rohdeschwarz_lib/cmx500.py
index f5b298e..18c5ab3 100644
--- a/acts/framework/acts/controllers/rohdeschwarz_lib/cmx500.py
+++ b/acts/framework/acts/controllers/rohdeschwarz_lib/cmx500.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2020 - The Android Open Source Project
+# Copyright 2021 - 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.
@@ -14,47 +14,368 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import logging
+import time
+import sys
+
from enum import Enum
+from os import path
from acts.controllers import abstract_inst
-class BtsNumber(Enum):
- """Base station Identifiers."""
- BTS1 = 'PCC'
- BTS2 = 'SCC1'
- BTS3 = 'SCC2'
- BTS4 = 'SCC3'
- BTS5 = 'SCC4'
- BTS6 = 'SCC6'
- BTS7 = 'SCC7'
+DEFAULT_XLAPI_PATH = '/home/mobileharness/Rohde-Schwarz/XLAPI/latest/venv/lib/python3.7/site-packages'
+DEFAULT_LTE_STATE_CHANGE_TIMER = 10
+DEFAULT_CELL_SWITCH_ON_TIMER = 60
+DEFAULT_ENDC_TIMER = 300
+
+logger = logging.getLogger('Xlapi_cmx500')
+
+LTE_CELL_PROPERTIES = [
+ 'band',
+ 'bandwidth',
+ 'dl_earfcn',
+ 'ul_earfcn',
+ 'total_dl_power',
+ 'p_b',
+ 'dl_epre',
+ 'ref_signal_power',
+ 'm',
+ 'beamforming_antenna_ports',
+ 'p0_nominal_pusch',
+]
+
+LTE_MHZ_UPPER_BOUND_TO_RB = [
+ (1.5, 6),
+ (4.0, 15),
+ (7.5, 25),
+ (12.5, 50),
+ (17.5, 75),
+]
+
+class DciFormat(Enum):
+ """Support DCI Formats for MIMOs."""
+ DCI_FORMAT_0 = 1
+ DCI_FORMAT_1 = 2
+ DCI_FORMAT_1A = 3
+ DCI_FORMAT_1B = 4
+ DCI_FORMAT_1C = 5
+ DCI_FORMAT_2 = 6
+ DCI_FORMAT_2A = 7
+ DCI_FORMAT_2B = 8
+ DCI_FORMAT_2C = 9
+ DCI_FORMAT_2D = 10
+
+
+class DuplexMode(Enum):
+ """Duplex Modes."""
+ FDD = 'FDD'
+ TDD = 'TDD'
+ DL_ONLY = 'DL_ONLY'
+
+
+class LteBandwidth(Enum):
+ """Supported LTE bandwidths."""
+ BANDWIDTH_1MHz = 6 # MHZ_1 is RB_6
+ BANDWIDTH_3MHz = 15 # MHZ_3 is RB_15
+ BANDWIDTH_5MHz = 25 # MHZ_5 is RB_25
+ BANDWIDTH_10MHz = 50 # MHZ_10 is RB_50
+ BANDWIDTH_15MHz = 75 # MHZ_15 is RB_75
+ BANDWIDTH_20MHz = 100 # MHZ_20 is RB_100
+
+
+class LteState(Enum):
+ """LTE ON and OFF."""
+ LTE_ON = 'ON'
+ LTE_OFF = 'OFF'
+
+
+class MimoModes(Enum):
+ """MIMO Modes dl antennas."""
+ MIMO1x1 = 1
+ MIMO2x2 = 2
+ MIMO4x4 = 4
+
+
+class ModulationType(Enum):
+ """Supported Modulation Types."""
+ Q16 = 0
+ Q64 = 1
+ Q256 = 2
+
+
+class NasState(Enum):
+ """NAS state between callbox and dut."""
+ DEREGISTERED = 'OFF'
+ EMM_REGISTERED = 'EMM'
+ MM5G_REGISTERED = 'NR'
+
+
+class RrcState(Enum):
+ """States to enable/disable rrc."""
+ RRC_ON = 'ON'
+ RRC_OFF = 'OFF'
+
+
+class RrcConnectionState(Enum):
+ """RRC Connection states, describes possible DUT RRC connection states."""
+ IDLE = 1
+ IDLE_PAGING = 2
+ IDLE_CONNECTION_ESTABLISHMENT = 3
+ CONNECTED = 4
+ CONNECTED_CONNECTION_REESTABLISHMENT = 5
+ CONNECTED_SCG_FAILURE = 6
+ CONNECTED_HANDOVER = 7
+ CONNECTED_CONNECTION_RELEASE = 8
+
+
+class SchedulingMode(Enum):
+ """Supported scheduling modes."""
+ USERDEFINEDCH = 'UDCHannels'
+
+
+class TransmissionModes(Enum):
+ """Supported transmission modes."""
+ TM1 = 1
+ TM2 = 2
+ TM3 = 3
+ TM4 = 4
+ TM7 = 7
+ TM8 = 8
+ TM9 = 9
+
+
+MIMO_MAX_LAYER_MAPPING = {
+ MimoModes.MIMO1x1: 1,
+ MimoModes.MIMO2x2: 2,
+ MimoModes.MIMO4x4: 3,
+}
+
class Cmx500(abstract_inst.SocketInstrument):
- def __init__(self, ip_addr, port):
- """Init method to setup variables for controllers.
+ def __init__(self, ip_addr, port, xlapi_path=DEFAULT_XLAPI_PATH):
+ """Init method to setup variables for the controller.
Args:
ip_addr: Controller's ip address.
- port: Port
+ port: Port.
"""
- super(Cmx500, self).__init__(ip_addr, port)
- def switch_lte_signalling(self, state):
- """ Turns LTE signalling ON/OFF.
+ # keeps the socket connection for debug purpose for now
+ super().__init__(ip_addr, port)
+ if not xlapi_path in sys.path:
+ sys.path.insert(0, xlapi_path)
+ self._initial_xlapi()
+ self._settings.system.set_instrument_address(ip_addr)
+ logger.info('The instrument address is {}'.format(
+ self._settings.system.get_instrument_address()))
+
+ self.bts = []
+
+ # Stops all active cells if there is any
+ self.disconnect()
+
+ # loads cell default settings from parameter file if there is one
+ default_setup_path = 'default_cell_setup.rsxp'
+ if path.exists(default_setup_path):
+ self._settings.session.set_test_param_files(default_setup_path)
+
+ self.dut = self._network.get_dut()
+ self.lte_cell = self._network.create_lte_cell('ltecell0')
+ self.nr_cell = self._network.create_nr_cell('nrcell0')
+ self._config_antenna_ports()
+ self.lte_rrc_state_change_timer = DEFAULT_LTE_STATE_CHANGE_TIMER
+ self.rrc_state_change_time_enable = False
+ self.cell_switch_on_timer = DEFAULT_CELL_SWITCH_ON_TIMER
+
+ # _config_antenna_ports for the special RF connection with cmw500 + cmx500.
+ def _config_antenna_ports(self):
+ from rs_mrt.testenvironment.signaling.sri.rat.common import CsiRsAntennaPorts
+ from rs_mrt.testenvironment.signaling.sri.rat.lte import CrsAntennaPorts
+
+ max_csi_rs_ports = CsiRsAntennaPorts.NUMBER_CSI_RS_ANTENNA_PORTS_FOUR
+ max_crs_ports = CrsAntennaPorts.NUMBER_CRS_ANTENNA_PORTS_FOUR
+
+ lte_cell_max_config = self.lte_cell.stub.GetMaximumConfiguration()
+ lte_cell_max_config.csi_rs_antenna_ports = max_csi_rs_ports
+ lte_cell_max_config.crs_antenna_ports = max_crs_ports
+ self.lte_cell.stub.SetMaximumConfiguration(lte_cell_max_config)
+
+ nr_cell_max_config = self.nr_cell.stub.GetMaximumConfiguration()
+ nr_cell_max_config.csi_rs_antenna_ports = max_csi_rs_ports
+ self.nr_cell.stub.SetMaximumConfiguration(nr_cell_max_config)
+
+ def _initial_xlapi(self):
+ import xlapi
+ import mrtype
+ from xlapi import network
+ from xlapi import settings
+
+ self._xlapi = xlapi
+ self._network = network
+ self._settings = settings
+
+ def configure_mimo_settings(self, mimo, bts_index=0):
+ """Sets the mimo scenario for the test.
Args:
- state: an instance of LteState indicating the state to which LTE
- signal has to be set.
+ mimo: mimo scenario to set.
"""
+ self.bts[bts_index].set_mimo_mode(mimo)
+
+ @property
+ def connection_type(self):
+ """Gets the connection type applied in callbox."""
+ state = self.dut.state.rrc_connection_state
+ return RrcConnectionState(state.value)
+
+ def create_base_station(self, cell):
+ """Creates the base station object with cell and current object.
+
+ Args:
+ cell: the XLAPI cell.
+
+ Returns:
+ base station object.
+ Raise:
+ CmxError if the cell is neither LTE nor NR.
+ """
+ from xlapi.lte_cell import LteCell
+ from xlapi.nr_cell import NrCell
+ if isinstance(cell, LteCell):
+ return LteBaseStation(self, cell)
+ elif isinstance(cell, NrCell):
+ return NrBaseStation(self, cell)
+ else:
+ raise CmxError('The cell type is neither LTE nor NR')
+
+ def detach(self):
+ """Detach callbox and controller."""
+ for bts in self.bts:
+ bts.stop()
+
+ def disable_packet_switching(self):
+ """Disable packet switching in call box."""
raise NotImplementedError()
+ def disconnect(self):
+ """Disconnect controller from device and switch to local mode."""
+
+ # Stops all lte and nr_cell
+ for cell in self._network.get_all_lte_cells():
+ if cell.is_on():
+ cell.stop()
+
+ for cell in self._network.get_all_nr_cells():
+ if cell.is_on():
+ cell.stop()
+ self.bts.clear()
+ self._network.reset()
+
def enable_packet_switching(self):
"""Enable packet switching in call box."""
raise NotImplementedError()
- def disable_packet_switching(self):
- """Disable packet switching in call box."""
+ def get_base_station(self, bts_index=0):
+ """Gets the base station object based on bts num. By default
+ bts_index set to 0 (PCC).
+
+ Args:
+ bts_num: base station identifier
+
+ Returns:
+ base station object.
+ """
+ return self.bts[bts_index]
+
+ def get_network(self):
+ """ Gets the network object from cmx500 object."""
+ return self._network
+
+ def init_lte_measurement(self):
+ """Gets the class object for lte measurement which can be used to
+ initiate measurements.
+
+ Returns:
+ lte measurement object.
+ """
raise NotImplementedError()
+ def reset(self):
+ """System level reset."""
+
+ self.disconnect()
+
+ @property
+ def rrc_connection(self):
+ """Gets the RRC connection state."""
+ return self.dut.state.rrc.is_connected
+
+ def set_timer(self, timeout):
+ """Sets timer for the Cmx500 class."""
+ self.rrc_state_change_time_enable = True
+ self.lte_rrc_state_change_timer = timeout
+
+ def switch_lte_signalling(self, state):
+ """ Turns LTE signalling ON/OFF.
+
+ Args:
+ state: an instance of LteState indicating the state to which LTE
+ signal has to be set.
+ """
+ if not isinstance(state, LteState):
+ raise ValueError('state should be the instance of LteState.')
+
+ if self.bts:
+ self.disconnect()
+ self.bts.append(LteBaseStation(self, self.lte_cell))
+ # Switch on the primary Lte cell for on state and switch all lte cells
+ # if the state is off state
+ if state.value == 'ON':
+ self.bts[0].start()
+ cell_status = self.bts[0].wait_cell_on(self.cell_switch_on_timer)
+ if cell_status:
+ logger.info('The LTE pcell status is on')
+ else:
+ raise CmxError('The LTE pcell cannot be switched on')
+ else:
+ for bts in self.bts:
+ if isinstance(bts, LteBaseStation):
+ bts.stop()
+ logger.info(
+ 'The LTE cell status is {} after stop'.format(bts.is_on()))
+
+ def switch_on_nsa_signalling(self):
+ if self.bts:
+ self.disconnect()
+ logger.info('Switches on NSA signalling')
+ self.bts.append(LteBaseStation(self, self.lte_cell))
+ self.bts.append(NrBaseStation(self, self.nr_cell))
+ self.bts[0].start()
+ lte_cell_status = self.bts[0].wait_cell_on(self.cell_switch_on_timer)
+ if lte_cell_status:
+ logger.info('The LTE pcell status is on')
+ else:
+ raise CmxError('The LTE pcell cannot be switched on')
+
+ self.bts[1].start()
+ nr_cell_status = self.bts[1].wait_cell_on(self.cell_switch_on_timer)
+ if nr_cell_status:
+ logger.info('The NR cell status is on')
+ else:
+ raise CmxError('The NR cell cannot be switched on')
+
+ def update_lte_cell_config(self, config):
+ """Updates lte cell settings with config."""
+ set_counts = 0
+ for property in LTE_CELL_PROPERTIES:
+ if property in config:
+ setter_name = 'set_' + property
+ setter = getattr(self.lte_cell, setter_name)
+ setter(config[property])
+ set_counts += 1
+ if set_counts < len(config):
+ logger.warning('Not all configs were set in update_cell_config')
+
@property
def use_carrier_specific(self):
"""Gets current status of carrier specific duplex configuration."""
@@ -69,38 +390,29 @@
"""
raise NotImplementedError()
- def send_and_recv(self, cmd):
- """Send and recv the status of the command.
+ def wait_for_rrc_state(self, state, timeout=120):
+ """ Waits until a certain RRC state is set.
Args:
- cmd: Command to send.
-
- Returns:
- status: returns the status of the command sent.
- """
- raise NotImplementedError()
-
- def configure_mimo_settings(self, mimo):
- """Sets the mimo scenario for the test.
-
- Args:
- mimo: mimo scenario to set.
- """
- raise NotImplementedError()
-
- def wait_for_pswitched_state(self, timeout=10):
- """Wait until pswitched state.
-
- Args:
- timeout: timeout for lte pswitched state.
+ state: the RRC state that is being waited for.
+ timeout: timeout for phone to be in connected state.
Raises:
- CmxError on timeout.
+ CmxError on time out.
"""
- raise NotImplementedError()
+ is_idle = (state.value == 'OFF')
+ for idx in range(timeout):
+ time.sleep(1)
+ if self.dut.state.rrc.is_idle == is_idle:
+ logger.info('{} reached at {} s'.format(state.value, idx))
+ return True
+ error_message = 'Waiting for {} state timeout after {}'.format(
+ state.value, timeout)
+ logger.error(error_message)
+ raise CmxError(error_message)
- def wait_for_attached_state(self, timeout=120):
- """Attach the controller with device.
+ def wait_until_attached(self, timeout=120):
+ """Waits until Lte attached.
Args:
timeout: timeout for phone to get attached.
@@ -108,609 +420,665 @@
Raises:
CmxError on time out.
"""
- raise NotImplementedError()
-
- def wait_for_rrc_state(self, state, timeout=120):
- """ Waits until a certain RRC state is set.
-
- Args:
- state: the RRC state that is being waited for.
- timeout: timeout for phone to be in connnected state.
-
- Raises:
- CmxError on time out.
- """
- raise NotImplementedError()
-
- def reset(self):
- """System level reset"""
- raise NotImplementedError()
-
- @property
- def get_instrument_id(self):
- """Gets instrument identification number"""
- raise NotImplementedError()
-
- def disconnect(self):
- """Disconnect controller from device and switch to local mode."""
- raise NotImplementedError()
-
- def close_remote_mode(self):
- """Exits remote mode to local mode."""
- raise NotImplementedError()
-
- def detach(self):
- """Detach callbox and controller."""
- raise NotImplementedError()
-
- @property
- def rrc_connection(self):
- """Gets the RRC connection state."""
- raise NotImplementedError()
-
- @rrc_connection.setter
- def rrc_connection(self, state):
- """Selects whether the RRC connection is kept or released after attach.
-
- Args:
- mode: RRC State ON/OFF.
- """
- raise NotImplementedError()
-
- @property
- def rrc_connection_timer(self):
- """Gets the inactivity timeout for disabled rrc connection."""
- raise NotImplementedError()
-
- @rrc_connection_timer.setter
- def rrc_connection_timer(self, time_in_secs):
- """Sets the inactivity timeout for disabled rrc connection. By default
- the timeout is set to 5.
-
- Args:
- time_in_secs: timeout of inactivity in rrc connection.
- """
- raise NotImplementedError()
-
- @property
- def dl_mac_padding(self):
- """Gets the state of mac padding."""
- raise NotImplementedError()
-
- @dl_mac_padding.setter
- def dl_mac_padding(self, state):
- """Enables/Disables downlink padding at the mac layer.
-
- Args:
- state: ON/OFF
- """
- raise NotImplementedError()
-
- @property
- def connection_type(self):
- """Gets the connection type applied in callbox."""
- raise NotImplementedError()
-
- @connection_type.setter
- def connection_type(self, ctype):
- """Sets the connection type to be applied.
-
- Args:
- ctype: Connection type.
- """
- raise NotImplementedError()
-
- def get_base_station(self, bts_num=BtsNumber.BTS1):
- """Gets the base station object based on bts num. By default
- bts_num set to PCC
-
- Args:
- bts_num: base station identifier
-
- Returns:
- base station object.
- """
- raise NotImplementedError()
-
- def init_lte_measurement(self):
- """Gets the class object for lte measurement which can be used to
- initiate measurements.
-
- Returns:
- lte measurement object.
- """
- raise NotImplementedError()
+ try:
+ self.dut.signaling.wait_for_lte_attach(self.lte_cell, timeout)
+ except:
+ raise CmxError(
+ 'wait_until_attached timeout after {}'.format(timeout))
class BaseStation(object):
- """Class to interact with different base stations"""
+ """Class to interact with different the base stations."""
- def __init__(self, cmx, bts_num):
- if not isinstance(bts_num, BtsNumber):
- raise ValueError('bts_num should be an instance of BtsNumber.')
- self._bts = bts_num.value
+ def __init__(self, cmx, cell):
+ """Init method to setup variables for base station.
+
+ Args:
+ cmx: Controller (Cmx500) object.
+ cell: The cell for the base station.
+ """
+
+ self._cell = cell
self._cmx = cmx
+ self._cc = cmx.dut.cc(cell)
+ self._network = cmx.get_network()
+
+ @property
+ def band(self):
+ """Gets the current band of cell.
+
+ Return:
+ the band number in int.
+ """
+ cell_band = self._cell.get_band()
+ return int(cell_band)
+
+ @property
+ def dl_power(self):
+ """Gets RSPRE level.
+
+ Return:
+ the power level in dbm.
+ """
+ return self._cell.get_total_dl_power().in_dBm()
@property
def duplex_mode(self):
"""Gets current duplex of cell."""
- raise NotImplementedError()
+ band = self._cell.get_band()
+ if band.is_fdd():
+ return DuplexMode.FDD
+ if band.is_tdd():
+ return DuplexMode.TDD
+ if band.is_dl_only():
+ return DuplexMode.DL_ONLY
- @duplex_mode.setter
- def duplex_mode(self, mode):
- """Sets the Duplex mode of cell.
+ def is_on(self):
+ """Verifies if the cell is turned on.
- Args:
- mode: String indicating FDD or TDD.
+ Return:
+ boolean (if the cell is on).
"""
- raise NotImplementedError()
+ return self._cell.is_on()
- @property
- def band(self):
- """Gets the current band of cell."""
- raise NotImplementedError()
-
- @band.setter
- def band(self, band):
+ def set_band(self, band):
"""Sets the Band of cell.
Args:
band: band of cell.
"""
- raise NotImplementedError()
+ self._cell.set_band(band)
- @property
- def dl_channel(self):
- """Gets the downlink channel of cell."""
- raise NotImplementedError()
-
- @dl_channel.setter
- def dl_channel(self, channel):
- """Sets the downlink channel number of cell.
+ def set_dl_mac_padding(self, state):
+ """Enables/Disables downlink padding at the mac layer.
Args:
- channel: downlink channel number of cell.
+ state: a boolean
"""
- raise NotImplementedError()
+ self._cc.set_dl_mac_padding(state)
- @property
- def ul_channel(self):
- """Gets the uplink channel of cell."""
- raise NotImplementedError()
-
- @ul_channel.setter
- def ul_channel(self, channel):
- """Sets the up link channel number of cell.
-
- Args:
- channel: up link channel number of cell.
- """
- raise NotImplementedError()
-
- @property
- def bandwidth(self):
- """Get the channel bandwidth of the cell."""
- raise NotImplementedError()
-
- @bandwidth.setter
- def bandwidth(self, bandwidth):
- """Sets the channel bandwidth of the cell.
-
- Args:
- bandwidth: channel bandwidth of cell.
- """
- raise NotImplementedError()
-
- @property
- def ul_frequency(self):
- """Get the uplink frequency of the cell."""
- raise NotImplementedError()
-
- @ul_frequency.setter
- def ul_frequency(self, freq):
- """Get the uplink frequency of the cell.
-
- Args:
- freq: uplink frequency of the cell.
- """
- raise NotImplementedError()
-
- @property
- def dl_frequency(self):
- """Get the downlink frequency of the cell"""
- raise NotImplementedError()
-
- @dl_frequency.setter
- def dl_frequency(self, freq):
- """Get the downlink frequency of the cell.
-
- Args:
- freq: downlink frequency of the cell.
- """
- raise NotImplementedError()
-
- @property
- def transmode(self):
- """Gets the TM of cell."""
- raise NotImplementedError()
-
- @transmode.setter
- def transmode(self, tm_mode):
- """Sets the TM of cell.
-
- Args:
- tm_mode: TM of cell.
- """
- raise NotImplementedError()
-
- @property
- def downlink_power_level(self):
- """Gets RSPRE level."""
- raise NotImplementedError()
-
- @downlink_power_level.setter
- def downlink_power_level(self, pwlevel):
+ def set_dl_power(self, pwlevel):
"""Modifies RSPRE level.
Args:
pwlevel: power level in dBm.
"""
- raise NotImplementedError()
+ self._cell.set_total_dl_power(pwlevel)
- @property
- def uplink_power_control(self):
- """Gets open loop nominal power directly."""
- raise NotImplementedError()
-
- @uplink_power_control.setter
- def uplink_power_control(self, ul_power):
- """Sets open loop nominal power directly.
+ def set_ul_power(self, ul_power):
+ """Sets ul power
Args:
- ul_power: uplink power level.
+ ul_power: the uplink power in dbm
"""
- raise NotImplementedError()
+ self._cc.set_target_ul_power(ul_power)
- @property
- def uldl_configuration(self):
- """Gets uldl configuration of the cell."""
- raise NotImplementedError()
+ def start(self):
+ """Starts the cell."""
+ self._cell.start()
- @uldl_configuration.setter
- def uldl_configuration(self, uldl):
- """Sets the ul-dl configuration.
+ def stop(self):
+ """Stops the cell."""
+ self._cell.stop()
+
+ def wait_cell_on(self, timeout):
+ """Waits the cell on.
Args:
- uldl: Configuration value ranging from 0 to 6.
- """
- raise NotImplementedError()
-
- @property
- def tdd_special_subframe(self):
- """Gets special subframe of the cell."""
- raise NotImplementedError()
-
- @tdd_special_subframe.setter
- def tdd_special_subframe(self, sframe):
- """Sets the tdd special subframe of the cell.
-
- Args:
- sframe: Integer value ranging from 1 to 9.
- """
- raise NotImplementedError()
-
- @property
- def scheduling_mode(self):
- """Gets the current scheduling mode."""
- raise NotImplementedError()
-
- @scheduling_mode.setter
- def scheduling_mode(self, mode):
- """Sets the scheduling type for the cell.
-
- Args:
- mode: Selects the channel mode to be scheduled.
- """
- raise NotImplementedError()
-
- @property
- def rb_configuration_dl(self):
- """Gets rmc's rb configuration for down link. This function returns
- Number of Resource blocks, Resource block position and Modulation type.
- """
- raise NotImplementedError()
-
- @rb_configuration_dl.setter
- def rb_configuration_dl(self, rb_config):
- """Sets the rb configuration for down link for scheduling type.
-
- Args:
- rb_config: Tuple containing Number of resource blocks, resource
- block position and modulation type.
+ timeout: the time for waiting the cell on.
Raises:
- ValueError: If tuple unpacking fails.
+ CmxError on time out.
"""
- raise NotImplementedError()
+ waiting_time = 0
+ while waiting_time < timeout:
+ if self._cell.is_on():
+ return True
+ waiting_time += 1
+ time.sleep(1)
+ return self._cell.is_on()
- @property
- def rb_configuration_ul(self):
- """Gets rb configuration for up link. This function returns
- Number of Resource blocks, Resource block position and Modulation type.
- """
- raise NotImplementedError()
- @rb_configuration_ul.setter
- def rb_configuration_ul(self, rb_config):
- """Sets the rb configuration for down link for scheduling mode.
+class LteBaseStation(BaseStation):
+ """ LTE base station."""
+
+ def __init__(self, cmx, cell):
+ """Init method to setup variables for the LTE base station.
Args:
- rb_config: Tuple containing Number of resource blocks, resource
- block position and modulation type.
-
- Raises:
- ValueError: If tuple unpacking fails.
+ cmx: Controller (Cmx500) object.
+ cell: The cell for the LTE base station.
"""
- raise NotImplementedError()
+ from xlapi.lte_cell import LteCell
+ if not isinstance(cell, LteCell):
+ raise CmxError('The cell is not a LTE cell, LTE base station fails'
+ ' to create.')
+ super().__init__(cmx, cell)
- def validate_rb(self, rb):
- """Validates if rb is within the limits for bandwidth set.
+ def _config_scheduler(self, dl_mcs=None, dl_rb_alloc=None, dl_dci_ncce=None,
+ dl_dci_format=None, dl_tm=None, dl_num_layers=None, dl_mcs_table=None,
+ ul_mcs=None, ul_rb_alloc=None, ul_dci_ncce=None):
- Args:
- rb: No. of resource blocks.
+ from rs_mrt.testenvironment.signaling.sri.rat.lte import DciFormat
+ from rs_mrt.testenvironment.signaling.sri.rat.lte import DlTransmissionMode
+ from rs_mrt.testenvironment.signaling.sri.rat.lte import MaxLayersMIMO
+ from rs_mrt.testenvironment.signaling.sri.rat.lte import McsTable
+ from rs_mrt.testenvironment.signaling.sri.rat.lte import PdcchFormat
- Raises:
- ValueError if rb out of range.
- """
- raise NotImplementedError()
+ log_list = []
+ if dl_mcs:
+ log_list.append('dl_mcs: {}'.format(dl_mcs))
+ if ul_mcs:
+ log_list.append('ul_mcs: {}'.format(ul_mcs))
+ if dl_rb_alloc:
+ log_list.append('dl_rb_alloc: {}'.format(dl_rb_alloc))
+ if ul_rb_alloc:
+ log_list.append('ul_rb_alloc: {}'.format(ul_rb_alloc))
+ if dl_dci_ncce:
+ dl_dci_ncce = PdcchFormat(dl_dci_ncce)
+ log_list.append('dl_dci_ncce: {}'.format(dl_dci_ncce))
+ if ul_dci_ncce:
+ ul_dci_ncce = PdcchFormat(ul_dci_ncce)
+ log_list.append('ul_dci_ncce: {}'.format(ul_dci_ncce))
+ if dl_dci_format:
+ dl_dci_format = DciFormat(dl_dci_format)
+ log_list.append('dl_dci_format: {}'.format(dl_dci_format))
+ if dl_tm:
+ dl_tm = DlTransmissionMode(dl_tm.value)
+ log_list.append('dl_tm: {}'.format(dl_tm))
+ if dl_num_layers:
+ dl_num_layers = MaxLayersMIMO(dl_num_layers)
+ log_list.append('dl_num_layers: {}'.format(dl_num_layers))
+ if dl_mcs_table:
+ dl_mcs_table = McsTable(dl_mcs_table)
+ log_list.append('dl_mcs_table: {}'.format(dl_mcs_table))
+
+ is_on = self._cell.is_on()
+ num_crs_antenna_ports = self._cell.get_num_crs_antenna_ports()
+
+ # Sets num of crs antenna ports to 4 for configuring
+ if is_on:
+ self._cell.stop()
+ time.sleep(1)
+ self._cell.set_num_crs_antenna_ports(4)
+ scheduler = self._cmx.dut.get_scheduler(self._cell)
+ logger.info('configure scheduler for {}'.format(','.join(log_list)))
+ scheduler.configure_scheduler(
+ dl_mcs=dl_mcs, dl_rb_alloc=dl_rb_alloc, dl_dci_ncce=dl_dci_ncce,
+ dl_dci_format=dl_dci_format, dl_tm=dl_tm,
+ dl_num_layers=dl_num_layers, dl_mcs_table=dl_mcs_table,
+ ul_mcs=ul_mcs, ul_rb_alloc=ul_rb_alloc, ul_dci_ncce=ul_dci_ncce)
+ logger.info('Configure scheduler succeeds')
+
+ # Sets num of crs antenna ports back to previous value
+ self._cell.set_num_crs_antenna_ports(num_crs_antenna_ports)
+ self._network.apply_changes()
+
+ if is_on:
+ self._cell.start()
@property
- def rb_position_dl(self):
- """Gets the position of the allocated down link resource blocks within
- the channel band-width.
- """
- raise NotImplementedError()
+ def bandwidth(self):
+ """Get the channel bandwidth of the cell.
- @rb_position_dl.setter
- def rb_position_dl(self, rbpos):
- """Selects the position of the allocated down link resource blocks
- within the channel band-width
-
- Args:
- rbpos: position of resource blocks.
+ Return:
+ the number rb of the bandwidth.
"""
- raise NotImplementedError()
+ return self._cell.get_bandwidth().num_rb
@property
- def rb_position_ul(self):
- """Gets the position of the allocated up link resource blocks within
- the channel band-width.
- """
- raise NotImplementedError()
+ def dl_channel(self):
+ """Gets the downlink channel of cell.
- @rb_position_ul.setter
- def rb_position_ul(self, rbpos):
- """Selects the position of the allocated up link resource blocks
- within the channel band-width.
-
- Args:
- rbpos: position of resource blocks.
+ Return:
+ the downlink channel (earfcn) in int.
"""
- raise NotImplementedError()
+ return int(self._cell.get_dl_earfcn())
@property
- def dci_format(self):
- """Gets the downlink control information (DCI) format."""
- raise NotImplementedError()
+ def dl_frequency(self):
+ """Get the downlink frequency of the cell."""
+ from mrtype.frequency import Frequency
+ return self._cell.get_dl_earfcn().to_freq().in_units(
+ Frequency.Units.GHz)
- @dci_format.setter
- def dci_format(self, dci_format):
+ def _to_rb_bandwidth(self, bandwidth):
+ for idx in range(5):
+ if bandwidth < LTE_MHZ_UPPER_BOUND_TO_RB[idx][0]:
+ return LTE_MHZ_UPPER_BOUND_TO_RB[idx][1]
+ return 100
+
+ def set_bandwidth(self, bandwidth):
+ """Sets the channel bandwidth of the cell.
+
+ Args:
+ bandwidth: channel bandwidth of cell in MHz.
+ """
+ self._cell.set_bandwidth(self._to_rb_bandwidth(bandwidth))
+
+ def set_cell_frequency_band(self, tdd_cfg=None, ssf_cfg=None):
+ """Sets cell frequency band with tdd and ssf config.
+
+ Args:
+ tdd_cfg: the tdd subframe assignment config in number (from 0-6).
+ ssf_cfg: the special subframe pattern config in number (from 1-9).
+ """
+ from rs_mrt.testenvironment.signaling.sri.rat.lte import SpecialSubframePattern
+ from rs_mrt.testenvironment.signaling.sri.rat.lte import SubFrameAssignment
+ from rs_mrt.testenvironment.signaling.sri.rat.lte.config import CellFrequencyBand
+ from rs_mrt.testenvironment.signaling.sri.rat.lte.config import Tdd
+ tdd_subframe = None
+ ssf_pattern = None
+ if tdd_cfg:
+ tdd_subframe = SubFrameAssignment(tdd_cfg + 1)
+ if ssf_cfg:
+ ssf_pattern = SpecialSubframePattern(ssf_cfg)
+ tdd = Tdd(tdd_config=Tdd.TddConfigSignaling(
+ subframe_assignment=tdd_subframe,
+ special_subframe_pattern=ssf_pattern))
+ self._cell.stub.SetCellFrequencyBand(CellFrequencyBand(tdd=tdd))
+ self._network.apply_changes()
+
+ def set_cfi(self, cfi):
+ """Sets number of pdcch symbols (cfi).
+
+ Args:
+ cfi: the value of NumberOfPdcchSymbols
+ """
+ from rs_mrt.testenvironment.signaling.sri.rat.lte import NumberOfPdcchSymbols
+ from rs_mrt.testenvironment.signaling.sri.rat.lte.config import PdcchRegionReq
+
+ logger.info('The cfi enum to set is {}'.format(
+ NumberOfPdcchSymbols(cfi)))
+ req = PdcchRegionReq()
+ req.num_pdcch_symbols = NumberOfPdcchSymbols(cfi)
+ self._cell.stub.SetPdcchControlRegion(req)
+
+ def set_dci_format(self, dci_format):
"""Selects the downlink control information (DCI) format.
Args:
dci_format: supported dci.
"""
- raise NotImplementedError()
+ if not isinstance(dci_format, DciFormat):
+ raise CmxError('Wrong type for dci_format')
+ self._config_scheduler(dl_dci_format=dci_format.value)
+
+ def set_dl_channel(self, channel):
+ """Sets the downlink channel number of cell.
+
+ Args:
+ channel: downlink channel number of cell.
+ """
+ if self.dl_channel == channel:
+ logger.info('The dl_channel was at {}'.format(self.dl_channel))
+ return
+ self._cell.set_earfcn(channel)
+ logger.info('The dl_channel was set to {}'.format(self.dl_channel))
+
+ def set_dl_modulation_table(self, modulation):
+ """Sets down link modulation table.
+
+ Args:
+ modulation: modulation table setting (ModulationType).
+ """
+ if not isinstance(modulation, ModulationType):
+ raise CmxError('The modulation is not the type of Modulation')
+ self._config_scheduler(dl_mcs_table=modulation.value)
+
+ def set_mimo_mode(self, mimo):
+ """Sets mimo mode for Lte scenario.
+
+ Args:
+ mimo: the mimo mode.
+ """
+ if not isinstance(mimo, MimoModes):
+ raise CmxError("Wrong type of mimo mode")
+
+ is_on = self._cell.is_on()
+ if is_on:
+ self._cell.stop()
+ self._cell.set_num_crs_antenna_ports(mimo.value)
+ self._config_scheduler(dl_num_layers=MIMO_MAX_LAYER_MAPPING[mimo])
+ if is_on:
+ self._cell.start()
+
+ def set_scheduling_mode(
+ self, mcs_dl=None, mcs_ul=None, nrb_dl=None, nrb_ul=None):
+ """Sets scheduling mode.
+
+ Args:
+ scheduling: the new scheduling mode.
+ mcs_dl: Downlink MCS.
+ mcs_ul: Uplink MCS.
+ nrb_dl: Number of RBs for downlink.
+ nrb_ul: Number of RBs for uplink.
+ """
+ self._config_scheduler(dl_mcs=mcs_dl, ul_mcs=mcs_ul, dl_rb_alloc=nrb_dl,
+ ul_rb_alloc=nrb_ul)
+
+ def set_ssf_config(self, ssf_config):
+ """Sets ssf subframe assignment with tdd_config.
+
+ Args:
+ ssf_config: the special subframe pattern config (from 1-9).
+ """
+ self.set_cell_frequency_band(ssf_cfg=ssf_config)
+
+ def set_tdd_config(self, tdd_config):
+ """Sets tdd subframe assignment with tdd_config.
+
+ Args:
+ tdd_config: the subframe assignemnt config (from 0-6).
+ """
+ self.set_cell_frequency_band(tdd_cfg=tdd_config)
+
+ def set_transmission_mode(self, transmission_mode):
+ """Sets transmission mode with schedular.
+
+ Args:
+ transmission_mode: the download link transmission mode.
+ """
+ if not isinstance(transmission_mode, TransmissionModes):
+ raise CmxError('Wrong type of the trasmission mode')
+ self._config_scheduler(dl_tm=transmission_mode)
+
+ def set_ul_channel(self, channel):
+ """Sets the up link channel number of cell.
+
+ Args:
+ channel: up link channel number of cell.
+ """
+ if self.ul_channel == channel:
+ logger.info('The ul_channel is at {}'.format(self.ul_channel))
+ return
+ self._cell.set_earfcn(channel)
+ logger.info('The dl_channel was set to {}'.format(self.ul_channel))
@property
- def dl_antenna(self):
- """Gets dl antenna count of cell."""
- raise NotImplementedError()
+ def ul_channel(self):
+ """Gets the uplink channel of cell.
- @dl_antenna.setter
- def dl_antenna(self, num_antenna):
- """Sets the dl antenna count of cell.
-
- Args:
- num_antenna: Count of number of dl antennas to use.
+ Return:
+ the uplink channel (earfcn) in int
"""
- raise NotImplementedError()
+ return int(self._cell.get_ul_earfcn())
@property
- def reduced_pdcch(self):
- """Gets the reduction of PDCCH resources state."""
- raise NotImplementedError()
+ def ul_frequency(self):
+ """Get the uplink frequency of the cell.
- @reduced_pdcch.setter
- def reduced_pdcch(self, state):
- """Sets the reduction of PDCCH resources state.
+ Return:
+ The uplink frequency in GHz.
+ """
+ from mrtype.frequency import Frequency
+ return self._cell.get_ul_earfcn().to_freq().in_units(
+ Frequency.Units.GHz)
+
+ def set_ul_modulation_table(self, modulation):
+ """Sets up link modulation table.
Args:
- state: ON/OFF.
+ modulation: modulation table setting (ModulationType).
"""
- raise NotImplementedError()
+ if not isinstance(modulation, ModulationType):
+ raise CmxError('The modulation is not the type of Modulation')
+ if modulation == ModulationType.Q16:
+ self._cell.stub.SetPuschCommonConfig(False)
+ else:
+ self._cell.stub.SetPuschCommonConfig(True)
- def tpc_power_control(self, set_type):
- """Set and execute the Up Link Power Control via TPC.
+
+class NrBaseStation(BaseStation):
+ """ NR base station."""
+
+ def __init__(self, cmx, cell):
+ """Init method to setup variables for the NR base station.
Args:
- set_type: Type of tpc power control.
+ cmx: Controller (Cmx500) object.
+ cell: The cell for the NR base station.
"""
- raise NotImplementedError()
+ from xlapi.nr_cell import NrCell
+ if not isinstance(cell, NrCell):
+ raise CmxError('the cell is not a NR cell, NR base station fails'
+ ' to creat.')
+
+ super().__init__(cmx, cell)
+
+ def _config_scheduler(self, dl_mcs=None, dl_mcs_table=None,
+ dl_rb_alloc=None, dl_mimo_mode=None,
+ ul_mcs=None, ul_mcs_table=None, ul_rb_alloc=None,
+ ul_mimo_mode=None):
+
+ from rs_mrt.testenvironment.signaling.sri.rat.nr import McsTable
+
+ log_list = []
+ if dl_mcs:
+ log_list.append('dl_mcs: {}'.format(dl_mcs))
+ if ul_mcs:
+ log_list.append('ul_mcs: {}'.format(ul_mcs))
+
+ # If rb alloc is not a tuple, add 0 as start RBs for XLAPI NR scheduler
+ if dl_rb_alloc:
+ if not isinstance(dl_rb_alloc, tuple):
+ dl_rb_alloc = (0, dl_rb_alloc)
+ log_list.append('dl_rb_alloc: {}'.format(dl_rb_alloc))
+ if ul_rb_alloc:
+ if not isinstance(ul_rb_alloc, tuple):
+ ul_rb_alloc = (0, ul_rb_alloc)
+ log_list.append('ul_rb_alloc: {}'.format(ul_rb_alloc))
+ if dl_mcs_table:
+ dl_mcs_table = McsTable(dl_mcs_table)
+ log_list.append('dl_mcs_table: {}'.format(dl_mcs_table))
+ if ul_mcs_table:
+ ul_mcs_table = McsTable(ul_mcs_table)
+ log_list.append('ul_mcs_table: {}'.format(ul_mcs_table))
+ if dl_mimo_mode:
+ log_list.append('dl_mimo_mode: {}'.format(dl_mimo_mode))
+ if ul_mimo_mode:
+ log_list.append('ul_mimo_mode: {}'.format(ul_mimo_mode))
+
+ is_on = self._cell.is_on()
+ if is_on:
+ self._cell.stop()
+ time.sleep(1)
+ scheduler = self._cmx.dut.get_scheduler(self._cell)
+ logger.info('configure scheduler for {}'.format(','.join(log_list)))
+
+ scheduler.configure_ue_scheduler(
+ dl_mcs=dl_mcs, dl_mcs_table=dl_mcs_table,
+ dl_rb_alloc=dl_rb_alloc, dl_mimo_mode=dl_mimo_mode,
+ ul_mcs=ul_mcs, ul_mcs_table=ul_mcs_table,
+ ul_rb_alloc=ul_rb_alloc, ul_mimo_mode=ul_mimo_mode)
+ logger.info('Configure scheduler succeeds')
+ self._network.apply_changes()
+
+ if is_on:
+ self._cell.start()
+
+ def attach_as_secondary_cell(self, endc_timer=DEFAULT_ENDC_TIMER):
+ """Enable endc mode for NR cell.
+
+ Args:
+ endc_timer: timeout for endc state
+ """
+ logger.info('enable endc mode for nsa dual connection')
+ self._cmx.dut.signaling.nsa_dual_connect(self._cell)
+ time_count = 0
+ while time_count < endc_timer:
+ if str(self._cmx.dut.state.radio_connectivity) == \
+ 'RadioConnectivityMode.EPS_LTE_NR':
+ logger.info('enter endc mode')
+ return
+ time.sleep(1)
+ time_count += 1
+ if time_count % 30 == 0:
+ logger.info('did not reach endc at {} s'.format(time_count))
+ raise CmxError('Cannot reach endc after {} s'.format(endc_timer))
@property
- def tpc_closed_loop_target_power(self):
- """Gets the target powers for power control with the TPC setup."""
- raise NotImplementedError()
+ def dl_channel(self):
+ """Gets the downlink channel of cell.
- @tpc_closed_loop_target_power.setter
- def tpc_closed_loop_target_power(self, cltpower):
- """Sets the target powers for power control with the TPC setup.
+ Return:
+ the downlink channel (earfcn) in int.
+ """
+ return int(self._cell.get_dl_ref_a())
+
+ def _bandwidth_to_carrier_bandwidth(self, bandwidth):
+ """Converts bandwidth in MHz to CarrierBandwidth.
+ CarrierBandwidth Enum in XLAPI:
+ MHZ_5 = 0
+ MHZ_10 = 1
+ MHZ_15 = 2
+ MHZ_20 = 3
+ MHZ_25 = 4
+ MHZ_30 = 5
+ MHZ_40 = 6
+ MHZ_50 = 7
+ MHZ_60 = 8
+ MHZ_70 = 9
+ MHZ_80 = 10
+ MHZ_90 = 11
+ MHZ_100 = 12
+ MHZ_200 = 13
+ MHZ_400 = 14
+ Args:
+ bandwidth: channel bandwidth in MHz.
+
+ Return:
+ the corresponding NR Carrier Bandwidth.
+ """
+ from mrtype.nr.frequency import CarrierBandwidth
+ if bandwidth > 100:
+ return CarrierBandwidth(12 + bandwidth // 200)
+ elif bandwidth > 30:
+ return CarrierBandwidth(2 + bandwidth // 10)
+ else:
+ return CarrierBandwidth(bandwidth // 5 - 1)
+
+ def set_band(self, band, frequency_range=None):
+ """Sets the Band of cell.
Args:
- tpower: Target power.
+ band: band of cell.
+ frequency_range: LOW, MID and HIGH for NR cell
"""
- raise NotImplementedError()
+ from mrtype.frequency import FrequencyRange
+ if not frequency_range or frequency_range.upper() == 'LOW':
+ frequency_range = FrequencyRange.LOW
+ elif frequency_range.upper() == 'MID':
+ frequency_range = FrequencyRange.MID
+ elif frequency_range.upper() == 'HIGH':
+ frequency_range = FrequencyRange.HIGH
+ else:
+ raise CmxError('Wrong type FrequencyRange')
- @property
- def drx_connected_mode(self):
- """ Gets the Connected DRX LTE cell parameter
+ self._cell.set_dl_ref_a_offset(band, frequency_range)
+ logger.info('The band is set to {} and is {} after setting'.format(
+ band, self.band))
+
+ def set_bandwidth(self, bandwidth, scs=None):
+ """Sets the channel bandwidth of the cell.
Args:
- None
-
- Returns:
- DRX connected mode (OFF, AUTO, MANUAL)
+ bandwidth: channel bandwidth of cell.
+ scs: subcarrier spacing (SCS) of resource grid 0
"""
- raise NotImplementedError()
+ if not scs:
+ scs = self._cell.get_scs()
+ self._cell.set_carrier_bandwidth_and_scs(
+ self._bandwidth_to_carrier_bandwidth(bandwidth), scs)
+ logger.info('The bandwidth in MHz is {}. After setting, the value is {}'
+ .format(bandwidth, str(self._cell.get_carrier_bandwidth())))
- @drx_connected_mode.setter
- def drx_connected_mode(self, mode):
- """ Sets the Connected DRX LTE cell parameter
+ def set_dl_channel(self, channel):
+ """Sets the downlink channel number of cell.
Args:
- mode: DRX Connected mode
-
- Returns:
- None
+ channel: downlink channel number of cell.
"""
- raise NotImplementedError()
+ from mrtype.nr.frequency import NrArfcn
+ if self.dl_channel == channel:
+ logger.info('The dl_channel was at {}'.format(self.dl_channel))
+ return
+ self._cell.set_dl_ref_a_offset(self.band, NrArfcn(channel))
+ logger.info('The dl_channel was set to {}'.format(self.dl_channel))
- @property
- def drx_on_duration_timer(self):
- """ Gets the amount of PDCCH subframes to wait for data after
- waking up from a DRX cycle
+ def set_dl_modulation_table(self, modulation):
+ """Sets down link modulation table.
Args:
- None
-
- Returns:
- DRX mode duration timer
+ modulation: modulation table setting (ModulationType).
"""
- raise NotImplementedError()
+ if not isinstance(modulation, ModulationType):
+ raise CmxError('The modulation is not the type of Modulation')
+ self._config_scheduler(dl_mcs_table=modulation.value)
- @drx_on_duration_timer.setter
- def drx_on_duration_timer(self, time):
- """ Sets the amount of PDCCH subframes to wait for data after
- waking up from a DRX cycle
+ def set_mimo_mode(self, mimo):
+ """Sets mimo mode for NR nsa scenario.
Args:
- timer: Length of interval to wait for user data to be transmitted
-
- Returns:
- None
+ mimo: the mimo mode.
"""
- raise NotImplementedError()
+ from rs_mrt.testenvironment.signaling.sri.rat.nr import DownlinkMimoMode
+ if not isinstance(mimo, MimoModes):
+ raise CmxError("Wrong type of mimo mode")
- @property
- def drx_inactivity_timer(self):
- """ Gets the number of PDCCH subframes to wait before entering DRX mode
+ is_on = self._cell.is_on()
+ if is_on:
+ self._cell.stop()
+ self._cc.set_dl_mimo_mode(DownlinkMimoMode.Enum(mimo.value))
+ if is_on:
+ self._cell.start()
+
+ def set_scheduling_mode(
+ self, mcs_dl=None, mcs_ul=None, nrb_dl=None, nrb_ul=None):
+ """Sets scheduling mode.
Args:
- None
-
- Returns:
- DRX mode inactivity timer
+ mcs_dl: Downlink MCS.
+ mcs_ul: Uplink MCS.
+ nrb_dl: Number of RBs for downlink.
+ nrb_ul: Number of RBs for uplink.
"""
- raise NotImplementedError()
+ self._config_scheduler(dl_mcs=mcs_dl, ul_mcs=mcs_ul, dl_rb_alloc=nrb_dl,
+ ul_rb_alloc=nrb_ul)
- @drx_inactivity_timer.setter
- def drx_inactivity_timer(self, time):
- """ Sets the number of PDCCH subframes to wait before entering DRX mode
+ def set_ssf_config(self, ssf_config):
+ """Sets ssf subframe assignment with tdd_config.
Args:
- timer: Length of the interval to wait
-
- Returns:
- None
+ ssf_config: the special subframe pattern config (from 1-9).
"""
- raise NotImplementedError()
+ raise CmxError('the set ssf config for nr did not implemente yet')
- @property
- def drx_retransmission_timer(self):
- """ Gets the number of consecutive PDCCH subframes to wait
- for retransmission
+ def set_tdd_config(self, tdd_config):
+ """Sets tdd subframe assignment with tdd_config.
Args:
- None
-
- Returns:
- Number of PDCCH subframes to wait for retransmission
+ tdd_config: the subframe assignemnt config (from 0-6).
"""
- raise NotImplementedError()
+ raise CmxError('the set tdd config for nr did not implemente yet')
- @drx_retransmission_timer.setter
- def drx_retransmission_timer(self, time):
- """ Sets the number of consecutive PDCCH subframes to wait
- for retransmission
+ def set_transmission_mode(self, transmission_mode):
+ """Sets transmission mode with schedular.
Args:
- time: Number of PDCCH subframes to wait
- for retransmission
-
- Returns:
- None
+ transmission_mode: the download link transmission mode.
"""
- raise NotImplementedError()
+ logger.info('The set transmission mode for nr is set by mimo mode')
- @property
- def drx_long_cycle(self):
- """ Gets the amount of subframes representing a DRX long cycle
+ def set_ul_modulation_table(self, modulation):
+ """Sets down link modulation table.
Args:
- None
-
- Returns:
- The amount of subframes representing one long DRX cycle.
- One cycle consists of DRX sleep + DRX on duration
+ modulation: modulation table setting (ModulationType).
"""
- raise NotImplementedError()
-
- @drx_long_cycle.setter
- def drx_long_cycle(self, time):
- """ Sets the amount of subframes representing a DRX long cycle
-
- Args:
- long_cycle: The amount of subframes representing one long DRX cycle.
- One cycle consists of DRX sleep + DRX on duration
-
- Returns:
- None
- """
- raise NotImplementedError()
-
- @property
- def drx_long_cycle_offset(self):
- """ Gets the offset used to determine long cycle starting
- subframe
-
- Args:
- None
-
- Returns:
- Long cycle offset
- """
- raise NotImplementedError()
-
- @drx_long_cycle_offset.setter
- def drx_long_cycle_offset(self, offset):
- """ Sets the offset used to determine long cycle starting
- subframe
-
- Args:
- offset: Number in range 0...(long cycle - 1)
- """
- raise NotImplementedError()
+ if not isinstance(modulation, ModulationType):
+ raise CmxError('The modulation is not the type of Modulation')
+ self._config_scheduler(ul_mcs_table=modulation.value)
class CmxError(Exception):
diff --git a/acts/framework/acts/controllers/rohdeschwarz_lib/cmx500_cellular_simulator.py b/acts/framework/acts/controllers/rohdeschwarz_lib/cmx500_cellular_simulator.py
index 4175d5f..ca281d1 100644
--- a/acts/framework/acts/controllers/rohdeschwarz_lib/cmx500_cellular_simulator.py
+++ b/acts/framework/acts/controllers/rohdeschwarz_lib/cmx500_cellular_simulator.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2020 - The Android Open Source Project
+# Copyright 2021 - 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.
@@ -14,15 +14,40 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import logging
from acts.controllers.rohdeschwarz_lib import cmx500
+from acts.controllers.rohdeschwarz_lib.cmx500 import LteBandwidth
+from acts.controllers.rohdeschwarz_lib.cmx500 import LteState
from acts.controllers import cellular_simulator as cc
+from acts.controllers.cellular_lib import LteSimulation
+
+
+CMX_TM_MAPPING = {
+ LteSimulation.TransmissionMode.TM1: cmx500.TransmissionModes.TM1,
+ LteSimulation.TransmissionMode.TM2: cmx500.TransmissionModes.TM2,
+ LteSimulation.TransmissionMode.TM3: cmx500.TransmissionModes.TM3,
+ LteSimulation.TransmissionMode.TM4: cmx500.TransmissionModes.TM4,
+ LteSimulation.TransmissionMode.TM7: cmx500.TransmissionModes.TM7,
+ LteSimulation.TransmissionMode.TM8: cmx500.TransmissionModes.TM8,
+ LteSimulation.TransmissionMode.TM9: cmx500.TransmissionModes.TM9,
+}
+
+CMX_SCH_MAPPING = {
+ LteSimulation.SchedulingMode.STATIC: cmx500.SchedulingMode.USERDEFINEDCH
+}
+
+CMX_MIMO_MAPPING = {
+ LteSimulation.MimoMode.MIMO_1x1: cmx500.MimoModes.MIMO1x1,
+ LteSimulation.MimoMode.MIMO_2x2: cmx500.MimoModes.MIMO2x2,
+ LteSimulation.MimoMode.MIMO_4x4: cmx500.MimoModes.MIMO4x4,
+}
class CMX500CellularSimulator(cc.AbstractCellularSimulator):
""" A cellular simulator for telephony simulations based on the CMX 500
controller. """
- def __init__(self, ip_address, port):
+ def __init__(self, ip_address, port='5025'):
""" Initializes the cellular simulator.
Args:
@@ -30,24 +55,40 @@
port: the port number for the CMX500 controller
"""
super().__init__()
-
try:
self.cmx = cmx500.Cmx500(ip_address, port)
- except cmx500.CmxError:
- raise cc.CellularSimulatorError('Could not connect to CMX500.')
+ except:
+ raise cc.CellularSimulatorError('Error when Initializes CMX500.')
+
+ self.bts = self.cmx.bts
def destroy(self):
""" Sends finalization commands to the cellular equipment and closes
the connection. """
- raise NotImplementedError()
+ self.log.info('destroy the cmx500 simulator')
+ self.cmx.disconnect()
def setup_lte_scenario(self):
""" Configures the equipment for an LTE simulation. """
+ self.log.info('setup lte scenario')
+ self.cmx.switch_lte_signalling(cmx500.LteState.LTE_ON)
+
+ def setup_nr_sa_scenario(self):
+ """ Configures the equipment for an NR stand alone simulation. """
raise NotImplementedError()
- def setup_lte_ca_scenario(self):
- """ Configures the equipment for an LTE with CA simulation. """
- raise NotImplementedError()
+ def setup_nr_nsa_scenario(self):
+ """ Configures the equipment for an NR non stand alone simulation. """
+ self.log.info('setup nsa scenario (start lte cell and nr cell')
+ self.cmx.switch_on_nsa_signalling()
+
+ def set_band_combination(self, bands):
+ """ Prepares the test equipment for the indicated band combination.
+
+ Args:
+ bands: a list of bands represented as ints or strings
+ """
+ self.num_carriers = len(bands)
def set_lte_rrc_state_change_timer(self, enabled, time=10):
""" Configures the LTE RRC state change timer.
@@ -56,16 +97,25 @@
enabled: a boolean indicating if the timer should be on or off.
time: time in seconds for the timer to expire
"""
- raise NotImplementedError()
+ self.log.info('set timer enabled to {} and the time to {}'.format(
+ enabled, time))
+ self.cmx.rrc_state_change_time_enable = enabled
+ self.cmx.lte_rrc_state_change_timer = time
- def set_band(self, bts_index, band):
+
+ def set_band(self, bts_index, band, frequency_range=None):
""" Sets the band for the indicated base station.
Args:
bts_index: the base station number
band: the new band
"""
- raise NotImplementedError()
+ self.log.info('set band to {}'.format(band))
+ if frequency_range:
+ self.bts[bts_index].set_band(
+ int(band), frequency_range=frequency_range)
+ else:
+ self.bts[bts_index].set_band(int(band))
def get_duplex_mode(self, band):
""" Determines if the band uses FDD or TDD duplex mode
@@ -76,7 +126,10 @@
Returns:
an variable of class DuplexMode indicating if band is FDD or TDD
"""
- raise NotImplementedError()
+ if 33 <= int(band) <= 46:
+ return cmx500.DuplexMode.TDD
+ else:
+ return cmx500.DuplexMode.FDD
def set_input_power(self, bts_index, input_power):
""" Sets the input power for the indicated base station.
@@ -85,7 +138,12 @@
bts_index: the base station number
input_power: the new input power
"""
- raise NotImplementedError()
+ if input_power > 23:
+ self.log.warning('Open loop supports -50dBm to 23 dBm. '
+ 'Setting it to max power 23 dBm')
+ input_power = 23
+ self.log.info('set input power to {}'.format(input_power))
+ self.bts[bts_index].set_ul_power(input_power)
def set_output_power(self, bts_index, output_power):
""" Sets the output power for the indicated base station.
@@ -94,16 +152,18 @@
bts_index: the base station number
output_power: the new output power
"""
- raise NotImplementedError()
+ self.log.info('set output power to {}'.format(output_power))
+ self.bts[bts_index].set_dl_power(output_power)
def set_tdd_config(self, bts_index, tdd_config):
""" Sets the tdd configuration number for the indicated base station.
Args:
bts_index: the base station number
- tdd_config: the new tdd configuration number
+ tdd_config: the new tdd configuration number (from 0 to 6)
"""
- raise NotImplementedError()
+ self.log.info('set tdd config to {}'.format(tdd_config))
+ self.bts[bts_index].set_tdd_config(tdd_config)
def set_ssf_config(self, bts_index, ssf_config):
""" Sets the Special Sub-Frame config number for the indicated
@@ -111,27 +171,32 @@
Args:
bts_index: the base station number
- ssf_config: the new ssf config number
+ ssf_config: the new ssf config number (from 0 to 9)
"""
- raise NotImplementedError()
+ self.log.info('set ssf config to {}'.format(ssf_config))
+ self.bts[bts_index].set_ssf_config(ssf_config)
def set_bandwidth(self, bts_index, bandwidth):
""" Sets the bandwidth for the indicated base station.
Args:
bts_index: the base station number
- bandwidth: the new bandwidth
+ bandwidth: the new bandwidth in MHz
"""
- raise NotImplementedError()
+ self.log.info('set bandwidth of bts {} to {}'.format(
+ bts_index, bandwidth))
+ self.bts[bts_index].set_bandwidth(int(bandwidth))
def set_downlink_channel_number(self, bts_index, channel_number):
""" Sets the downlink channel number for the indicated base station.
Args:
bts_index: the base station number
- channel_number: the new channel number
+ channel_number: the new channel number (earfcn)
"""
- raise NotImplementedError()
+ self.log.info('Sets the downlink channel number to {}'.format(
+ channel_number))
+ self.bts[bts_index].set_dl_channel(channel_number)
def set_mimo_mode(self, bts_index, mimo_mode):
""" Sets the mimo mode for the indicated base station.
@@ -140,7 +205,9 @@
bts_index: the base station number
mimo_mode: the new mimo mode
"""
- raise NotImplementedError()
+ self.log.info('set mimo mode to {}'.format(mimo_mode))
+ mimo_mode = CMX_MIMO_MAPPING[mimo_mode]
+ self.bts[bts_index].set_mimo_mode(mimo_mode)
def set_transmission_mode(self, bts_index, tmode):
""" Sets the transmission mode for the indicated base station.
@@ -149,7 +216,9 @@
bts_index: the base station number
tmode: the new transmission mode
"""
- raise NotImplementedError()
+ self.log.info('set TransmissionMode to {}'.format(tmode))
+ tmode = CMX_TM_MAPPING[tmode]
+ self.bts[bts_index].set_transmission_mode(tmode)
def set_scheduling_mode(self, bts_index, scheduling, mcs_dl=None,
mcs_ul=None, nrb_dl=None, nrb_ul=None):
@@ -163,34 +232,56 @@
nrb_dl: Number of RBs for downlink.
nrb_ul: Number of RBs for uplink.
"""
- raise NotImplementedError()
+ if scheduling not in CMX_SCH_MAPPING:
+ raise cc.CellularSimulatorError(
+ "This scheduling mode is not supported")
+ log_list = []
+ if mcs_dl:
+ log_list.append('mcs_dl: {}'.format(mcs_dl))
+ if mcs_ul:
+ log_list.append('mcs_ul: {}'.format(mcs_ul))
+ if nrb_dl:
+ log_list.append('nrb_dl: {}'.format(nrb_dl))
+ if nrb_ul:
+ log_list.append('nrb_ul: {}'.format(nrb_ul))
- def set_dl_modulation(self, bts_index, modulation):
- """ Sets the DL modulation for the indicated base station.
+ self.log.info('set scheduling mode to {}'.format(','.join(log_list)))
+ self.bts[bts_index].set_scheduling_mode(
+ mcs_dl=mcs_dl, mcs_ul=mcs_ul, nrb_dl=nrb_dl, nrb_ul=nrb_ul)
+
+ def set_dl_256_qam_enabled(self, bts_index, enabled):
+ """ Determines what MCS table should be used for the downlink.
Args:
bts_index: the base station number
- modulation: the new DL modulation
+ enabled: whether 256 QAM should be used
"""
- raise NotImplementedError()
+ self.log.info('Set 256 QAM DL MCS enabled: ' + str(enabled))
+ self.bts[bts_index].set_dl_modulation_table(
+ cmx500.ModulationType.Q256 if enabled else cmx500.ModulationType.
+ Q64)
- def set_ul_modulation(self, bts_index, modulation):
- """ Sets the UL modulation for the indicated base station.
+ def set_ul_64_qam_enabled(self, bts_index, enabled):
+ """ Determines what MCS table should be used for the uplink.
Args:
bts_index: the base station number
- modulation: the new UL modulation
+ enabled: whether 64 QAM should be used
"""
- raise NotImplementedError()
+ self.log.info('Set 64 QAM UL MCS enabled: ' + str(enabled))
+ self.bts[bts_index].set_ul_modulation_table(
+ cmx500.ModulationType.Q64 if enabled else cmx500.ModulationType.Q16
+ )
- def set_tbs_pattern_on(self, bts_index, tbs_pattern_on):
- """ Enables or disables TBS pattern in the indicated base station.
+ def set_mac_padding(self, bts_index, mac_padding):
+ """ Enables or disables MAC padding in the indicated base station.
Args:
bts_index: the base station number
- tbs_pattern_on: the new TBS pattern setting
+ mac_padding: the new MAC padding setting
"""
- raise NotImplementedError()
+ self.log.info('set mac pad on {}'.format(mac_padding))
+ self.bts[bts_index].set_dl_mac_padding(mac_padding)
def set_cfi(self, bts_index, cfi):
""" Sets the Channel Format Indicator for the indicated base station.
@@ -199,7 +290,16 @@
bts_index: the base station number
cfi: the new CFI setting
"""
- raise NotImplementedError()
+ if cfi == 'BESTEFFORT':
+ self.log.info('The cfi is BESTEFFORT, use default value')
+ return
+ try:
+ index = int(cfi) + 1
+ except Exception as e:
+ index = 1
+ finally:
+ self.log.info('set the cfi and the cfi index is {}'.format(index))
+ self.bts[bts_index].set_cfi(index)
def set_paging_cycle(self, bts_index, cycle_duration):
""" Sets the paging cycle duration for the indicated base station.
@@ -208,7 +308,8 @@
bts_index: the base station number
cycle_duration: the new paging cycle duration in milliseconds
"""
- raise NotImplementedError()
+ self.log.warning('The set_paging_cycle method is not implememted, '
+ 'use default value')
def set_phich_resource(self, bts_index, phich):
""" Sets the PHICH Resource setting for the indicated base station.
@@ -217,7 +318,8 @@
bts_index: the base station number
phich: the new PHICH resource setting
"""
- raise NotImplementedError()
+ self.log.warning('The set_phich_resource method is not implememted, '
+ 'use default value')
def lte_attach_secondary_carriers(self, ue_capability_enquiry):
""" Activates the secondary carriers for CA. Requires the DUT to be
@@ -227,7 +329,8 @@
ue_capability_enquiry: UE capability enquiry message to be sent to
the UE before starting carrier aggregation.
"""
- raise NotImplementedError()
+ self.wait_until_communication_state()
+ self.bts[1].attach_as_secondary_cell()
def wait_until_attached(self, timeout=120):
""" Waits until the DUT is attached to the primary carrier.
@@ -236,7 +339,8 @@
timeout: after this amount of time the method will raise a
CellularSimulatorError exception. Default is 120 seconds.
"""
- raise NotImplementedError()
+ self.log.info('wait until attached')
+ self.cmx.wait_until_attached(timeout)
def wait_until_communication_state(self, timeout=120):
""" Waits until the DUT is in Communication state.
@@ -244,8 +348,13 @@
Args:
timeout: after this amount of time the method will raise a
CellularSimulatorError exception. Default is 120 seconds.
+ Return:
+ True if cmx reach rrc state within timeout
+ Raise:
+ CmxError if tiemout
"""
- raise NotImplementedError()
+ self.log.info('wait for rrc on state')
+ return self.cmx.wait_for_rrc_state(cmx500.RrcState.RRC_ON, timeout)
def wait_until_idle_state(self, timeout=120):
""" Waits until the DUT is in Idle state.
@@ -253,22 +362,28 @@
Args:
timeout: after this amount of time the method will raise a
CellularSimulatorError exception. Default is 120 seconds.
+ Return:
+ True if cmx reach rrc state within timeout
+ Raise:
+ CmxError if tiemout
"""
- raise NotImplementedError()
+ self.log.info('wait for rrc off state')
+ return self.cmx.wait_for_rrc_state(cmx500.RrcState.RRC_OFF, timeout)
def detach(self):
""" Turns off all the base stations so the DUT loose connection."""
- self.cmx.detach()
+ self.log.info('Bypass simulator detach step for now')
def stop(self):
""" Stops current simulation. After calling this method, the simulator
will need to be set up again. """
- raise NotImplementedError()
+ self.log.info('Stops current simulation and disconnect cmx500')
+ self.cmx.disconnect()
def start_data_traffic(self):
""" Starts transmitting data from the instrument to the DUT. """
- raise NotImplementedError()
+ self.log.warning('The start_data_traffic is not implemented yet')
def stop_data_traffic(self):
""" Stops transmitting data from the instrument to the DUT. """
- raise NotImplementedError()
+ self.log.warning('The stop_data_traffic is not implemented yet')
diff --git a/acts/framework/acts/controllers/rohdeschwarz_lib/contest.py b/acts/framework/acts/controllers/rohdeschwarz_lib/contest.py
index f34a62b..4f7ebdc 100644
--- a/acts/framework/acts/controllers/rohdeschwarz_lib/contest.py
+++ b/acts/framework/acts/controllers/rohdeschwarz_lib/contest.py
@@ -121,7 +121,7 @@
def execute_testplan(self, testplan):
""" Executes a test plan with Contest's Remote Server sequencer.
- Waits until and exit code is provided in the output. Logs the ouput with
+ Waits until and exit code is provided in the output. Logs the output with
the class logger and pulls the json report from the server if the test
succeeds.
diff --git a/acts/framework/acts/controllers/sl4a_lib/error_reporter.py b/acts/framework/acts/controllers/sl4a_lib/error_reporter.py
index b910338..4e90326 100644
--- a/acts/framework/acts/controllers/sl4a_lib/error_reporter.py
+++ b/acts/framework/acts/controllers/sl4a_lib/error_reporter.py
@@ -75,6 +75,7 @@
return False
report = ErrorLogger('%s|%s' % (self.name, ticket))
+ report.info('Creating error report.')
(self.report_on_adb(sl4a_manager.adb, report)
and self.report_device_processes(sl4a_manager.adb, report) and
@@ -212,6 +213,7 @@
def _get_report_ticket(self):
"""Returns the next ticket, or none if all tickets have been used."""
+ logging.debug('Getting ticket for SL4A error report.')
with self._ticket_lock:
self._ticket_number += 1
ticket_number = self._ticket_number
diff --git a/acts/framework/acts/controllers/sl4a_lib/sl4a_manager.py b/acts/framework/acts/controllers/sl4a_lib/sl4a_manager.py
index 181048d..959274d 100644
--- a/acts/framework/acts/controllers/sl4a_lib/sl4a_manager.py
+++ b/acts/framework/acts/controllers/sl4a_lib/sl4a_manager.py
@@ -25,6 +25,8 @@
ATTEMPT_INTERVAL = .25
MAX_WAIT_ON_SERVER_SECONDS = 5
+SL4A_PKG_NAME = 'com.googlecode.android_scripting'
+
_SL4A_LAUNCH_SERVER_CMD = (
'am startservice -a com.googlecode.android_scripting.action.LAUNCH_SERVER '
'--ei com.googlecode.android_scripting.extra.USE_SERVICE_PORT %s '
@@ -203,8 +205,7 @@
def is_sl4a_installed(self):
"""Returns True if SL4A is installed on the AndroidDevice."""
return bool(
- self.adb.shell('pm path com.googlecode\.android_scripting',
- ignore_status=True))
+ self.adb.shell('pm path %s' % SL4A_PKG_NAME, ignore_status=True))
def start_sl4a_service(self):
"""Starts the SL4A Service on the device.
@@ -217,14 +218,11 @@
if not self.is_sl4a_installed():
raise rpc_client.Sl4aNotInstalledError(
'SL4A is not installed on device %s' % self.adb.serial)
- if self.adb.shell(
- '(ps | grep "S com.googlecode.android_scripting") || true'
- ):
+ if self.adb.shell('(ps | grep "S %s") || true' % SL4A_PKG_NAME):
# Close all SL4A servers not opened by this manager.
# TODO(markdr): revert back to closing all ports after
# b/76147680 is resolved.
- self.adb.shell(
- 'kill -9 $(pidof com.googlecode.android_scripting)')
+ self.adb.shell('kill -9 $(pidof %s)' % SL4A_PKG_NAME)
self.adb.shell(
'settings put global hidden_api_blacklist_exemptions "*"')
# Start the service if it is not up already.
@@ -286,7 +284,12 @@
return session
def stop_service(self):
- """Stops The SL4A Service."""
+ """Stops The SL4A Service. Force-stops the SL4A apk."""
+ try:
+ self.adb.shell('am force-stop %s' % SL4A_PKG_NAME,
+ ignore_status=True)
+ except Exception as e:
+ self.log.warning("Fail to stop package %s: %s", SL4A_PKG_NAME, e)
self._started = False
def terminate_all_sessions(self):
diff --git a/acts/framework/acts/controllers/utils_lib/commands/shell.py b/acts/framework/acts/controllers/utils_lib/commands/shell.py
index 81a2f13..8073e45 100644
--- a/acts/framework/acts/controllers/utils_lib/commands/shell.py
+++ b/acts/framework/acts/controllers/utils_lib/commands/shell.py
@@ -28,6 +28,7 @@
Note: At the moment this only works with the ssh runner.
"""
+
def __init__(self, runner, working_dir=None):
"""Creates a new shell command invoker.
@@ -103,8 +104,12 @@
"""
try:
result = self.run('ps aux | grep -v grep | grep %s' % identifier)
- except job.Error:
- raise StopIteration
+ except job.Error as e:
+ if e.exit_status == 1:
+ # Grep returns exit status 1 when no lines are selected. This is
+ # an expected return code.
+ return
+ raise e
lines = result.stdout.splitlines()
@@ -115,7 +120,10 @@
# USER PID ...
for line in lines:
pieces = line.split()
- yield int(pieces[1])
+ try:
+ yield int(pieces[1])
+ except StopIteration:
+ return
def search_file(self, search_string, file_name):
"""Searches through a file for a string.
diff --git a/acts/framework/acts/libs/proc/job.py b/acts/framework/acts/libs/proc/job.py
index a8128e1..4907ff6 100644
--- a/acts/framework/acts/libs/proc/job.py
+++ b/acts/framework/acts/libs/proc/job.py
@@ -25,6 +25,7 @@
class Error(Exception):
"""Indicates that a command failed, is fatal to the test unless caught."""
+
def __init__(self, result):
super(Error, self).__init__(result)
self.result = result
@@ -48,6 +49,7 @@
duration: How long the process ran for.
did_timeout: True if the program timed out and was killed.
"""
+
@property
def stdout(self):
"""String representation of standard output."""
@@ -128,8 +130,7 @@
Raises:
job.TimeoutError: When the remote command took to long to execute.
- Error: When the ssh connection failed to be created.
- CommandError: Ssh worked, but the command had an error executing.
+ Error: When the command had an error executing and ignore_status==False.
"""
start_time = time.time()
proc = subprocess.Popen(command,
diff --git a/acts/framework/acts/libs/utils/multithread.py b/acts/framework/acts/libs/utils/multithread.py
new file mode 100644
index 0000000..800b144
--- /dev/null
+++ b/acts/framework/acts/libs/utils/multithread.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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 concurrent.futures
+import logging
+
+def task_wrapper(task):
+ """Task wrapper for multithread_func
+
+ Args:
+ task[0]: function to be wrapped.
+ task[1]: function args.
+
+ Returns:
+ Return value of wrapped function call.
+ """
+ func = task[0]
+ params = task[1]
+ return func(*params)
+
+
+def run_multithread_func_async(log, task):
+ """Starts a multi-threaded function asynchronously.
+
+ Args:
+ log: log object.
+ task: a task to be executed in parallel.
+
+ Returns:
+ Future object representing the execution of the task.
+ """
+ executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
+ try:
+ future_object = executor.submit(task_wrapper, task)
+ except Exception as e:
+ log.error("Exception error %s", e)
+ raise
+ return future_object
+
+
+def run_multithread_func(log, tasks):
+ """Run multi-thread functions and return results.
+
+ Args:
+ log: log object.
+ tasks: a list of tasks to be executed in parallel.
+
+ Returns:
+ results for tasks.
+ """
+ MAX_NUMBER_OF_WORKERS = 10
+ number_of_workers = min(MAX_NUMBER_OF_WORKERS, len(tasks))
+ executor = concurrent.futures.ThreadPoolExecutor(
+ max_workers=number_of_workers)
+ if not log: log = logging
+ try:
+ results = list(executor.map(task_wrapper, tasks))
+ except Exception as e:
+ log.error("Exception error %s", e)
+ raise
+ executor.shutdown()
+ if log:
+ log.info("multithread_func %s result: %s",
+ [task[0].__name__ for task in tasks], results)
+ return results
+
+
+def multithread_func(log, tasks):
+ """Multi-thread function wrapper.
+
+ Args:
+ log: log object.
+ tasks: tasks to be executed in parallel.
+
+ Returns:
+ True if all tasks return True.
+ False if any task return False.
+ """
+ results = run_multithread_func(log, tasks)
+ for r in results:
+ if not r:
+ return False
+ return True
+
+
+def multithread_func_and_check_results(log, tasks, expected_results):
+ """Multi-thread function wrapper.
+
+ Args:
+ log: log object.
+ tasks: tasks to be executed in parallel.
+ expected_results: check if the results from tasks match expected_results.
+
+ Returns:
+ True if expected_results are met.
+ False if expected_results are not met.
+ """
+ return_value = True
+ results = run_multithread_func(log, tasks)
+ log.info("multithread_func result: %s, expecting %s", results,
+ expected_results)
+ for task, result, expected_result in zip(tasks, results, expected_results):
+ if result != expected_result:
+ logging.info("Result for task %s is %s, expecting %s", task[0],
+ result, expected_result)
+ return_value = False
+ return return_value
diff --git a/acts/framework/acts/logger.py b/acts/framework/acts/logger.py
index f18190a..eba5620 100755
--- a/acts/framework/acts/logger.py
+++ b/acts/framework/acts/logger.py
@@ -247,7 +247,11 @@
link_path = os.path.join(os.path.dirname(actual_path), "latest")
if os.path.islink(link_path):
os.remove(link_path)
- os.symlink(actual_path, link_path)
+ try:
+ os.symlink(actual_path, link_path)
+ except OSError:
+ logging.warning('Failed to create symlink to latest logs dir.',
+ exc_info=True)
def setup_test_logger(log_path, prefix=None):
diff --git a/acts/framework/acts/utils.py b/acts/framework/acts/utils.py
index c07f044..70becb9 100755
--- a/acts/framework/acts/utils.py
+++ b/acts/framework/acts/utils.py
@@ -46,6 +46,9 @@
# the file names we output fits within the limit.
MAX_FILENAME_LEN = 255
+# All Fuchsia devices use this suffix for link-local mDNS host names.
+FUCHSIA_MDNS_TYPE = '_fuchsia._udp.local.'
+
class ActsUtilsError(Exception):
"""Generic error raised for exceptions in ACTS utils."""
@@ -558,6 +561,7 @@
Raises:
TimeoutError is raised when time out happens.
"""
+
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
@@ -970,6 +974,22 @@
return False
+def zip_directory(zip_name, src_dir):
+ """Compress a directory to a .zip file.
+
+ This implementation is thread-safe.
+
+ Args:
+ zip_name: str, name of the generated archive
+ src_dir: str, path to the source directory
+ """
+ with zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) as zip:
+ for root, dirs, files in os.walk(src_dir):
+ for file in files:
+ path = os.path.join(root, file)
+ zip.write(path, os.path.relpath(path, src_dir))
+
+
def unzip_maintain_permissions(zip_path, extract_location):
"""Unzip a .zip file while maintaining permissions.
@@ -1286,6 +1306,7 @@
"""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
@@ -1318,6 +1339,7 @@
"""Context manager used to block until a specified amount of time has
elapsed.
"""
+
def __init__(self, secs):
"""Initializes a BlockingTimer
@@ -1418,7 +1440,6 @@
ifconfig_output = comm_channel.run('ifconfig %s' % interface).stdout
elif type(comm_channel) is FuchsiaDevice:
all_interfaces_and_addresses = []
- comm_channel.netstack_lib.init()
interfaces = comm_channel.netstack_lib.netstackListInterfaces()
if interfaces.get('error') is not None:
raise ActsUtilsError('Failed with {}'.format(
@@ -1497,14 +1518,6 @@
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]
@@ -1551,7 +1564,7 @@
if os_type == 'Darwin':
if is_valid_ipv6_address(dest_ip):
# ping6 on MacOS doesn't support timeout
- logging.warn(
+ logging.debug(
'Ignoring timeout, as ping6 on MacOS does not support it.')
timeout_flag = []
else:
@@ -1681,7 +1694,7 @@
def can_ping(comm_channel,
dest_ip,
- count=1,
+ count=3,
interval=1000,
timeout=1000,
size=56,
@@ -1749,48 +1762,104 @@
def get_fuchsia_mdns_ipv6_address(device_mdns_name):
- """Gets the ipv6 link local address from a fuchsia device over mdns
+ """Finds the IPv6 link-local address of a Fuchsia device matching a mDNS
+ name.
Args:
- device_mdns_name: name of fuchsia device, ie gig-clone-sugar-slash
+ device_mdns_name: name of Fuchsia device (e.g. gig-clone-sugar-slash)
Returns:
- string, ipv6 link local address
+ string, IPv6 link-local address
"""
if not device_mdns_name:
return None
- mdns_type = '_fuchsia._udp.local.'
- interface_list = psutil.net_if_addrs()
- for interface in interface_list:
- interface_ipv6_link_local = \
- get_interface_ip_addresses(job, interface)['ipv6_link_local']
- if 'fe80::1' in interface_ipv6_link_local:
- logging.info('Removing IPv6 loopback IP from %s interface list.'
- ' Not modifying actual system IP addresses.' %
- interface)
- # This is needed as the Zeroconf library crashes if you try to
- # instantiate it on a IPv6 loopback IP address.
- interface_ipv6_link_local.remove('fe80::1')
- if interface_ipv6_link_local:
- zeroconf = Zeroconf(ip_version=IPVersion.V6Only,
- interfaces=interface_ipv6_link_local)
- device_records = (zeroconf.get_service_info(
- mdns_type, device_mdns_name + '.' + mdns_type))
- if device_records:
- for device_ip_address in device_records.parsed_addresses():
- device_ip_address = ipaddress.ip_address(device_ip_address)
- if (device_ip_address.version == 6
- and device_ip_address.is_link_local):
- if ping(job,
- dest_ip='%s%%%s' %
- (str(device_ip_address),
- interface))['exit_status'] == 0:
+ interfaces = psutil.net_if_addrs()
+ for interface in interfaces:
+ for addr in interfaces[interface]:
+ address = addr.address.split('%')[0]
+ if addr.family == socket.AF_INET6 and ipaddress.ip_address(
+ address).is_link_local and address != 'fe80::1':
+ logging.info('Sending mDNS query for device "%s" using "%s"' %
+ (device_mdns_name, addr.address))
+ try:
+ zeroconf = Zeroconf(ip_version=IPVersion.V6Only,
+ interfaces=[address])
+ except RuntimeError as e:
+ if 'No adapter found for IP address' in e.args[0]:
+ # Most likely, a device went offline and its control
+ # interface was deleted. This is acceptable since the
+ # device that went offline isn't guaranteed to be the
+ # device we're searching for.
+ logging.warning('No adapter found for "%s"' % address)
+ continue
+ raise
+
+ device_records = zeroconf.get_service_info(
+ FUCHSIA_MDNS_TYPE,
+ device_mdns_name + '.' + FUCHSIA_MDNS_TYPE)
+
+ if device_records:
+ for device_address in device_records.parsed_addresses():
+ device_ip_address = ipaddress.ip_address(
+ device_address)
+ scoped_address = '%s%%%s' % (device_address, interface)
+ if (device_ip_address.version == 6
+ and device_ip_address.is_link_local
+ and can_ping(job, dest_ip=scoped_address)):
+ logging.info('Found device "%s" at "%s"' %
+ (device_mdns_name, scoped_address))
zeroconf.close()
del zeroconf
- return ('%s%%%s' %
- (str(device_ip_address), interface))
- zeroconf.close()
- del zeroconf
- logging.error('Unable to get ip address for %s' % device_mdns_name)
+ return scoped_address
+
+ zeroconf.close()
+ del zeroconf
+
+ logging.error('Unable to find IP address for device "%s"' %
+ device_mdns_name)
return None
+
+
+def get_device(devices, device_type):
+ """Finds a unique device with the specified "device_type" attribute from a
+ list. If none is found, defaults to the first device in the list.
+
+ Example:
+ get_device(android_devices, device_type="DUT")
+ get_device(fuchsia_devices, device_type="DUT")
+ get_device(android_devices + fuchsia_devices, device_type="DUT")
+
+ Args:
+ devices: A list of device controller objects.
+ device_type: (string) Type of device to find, specified by the
+ "device_type" attribute.
+
+ Returns:
+ The matching device controller object, or the first device in the list
+ if not found.
+
+ Raises:
+ ValueError is raised if none or more than one device is
+ matched.
+ """
+ if not devices:
+ raise ValueError('No devices available')
+
+ matches = [
+ d for d in devices
+ if hasattr(d, 'device_type') and d.device_type == device_type
+ ]
+
+ if len(matches) == 0:
+ # No matches for the specified "device_type", use the first device
+ # declared.
+ return devices[0]
+ if len(matches) > 1:
+ # Specifing multiple devices with the same "device_type" is a
+ # configuration error.
+ raise ValueError(
+ 'More than one device matching "device_type" == "{}"'.format(
+ device_type))
+
+ return matches[0]
\ No newline at end of file
diff --git a/acts/framework/setup.py b/acts/framework/setup.py
index 6846b78..98a8fb0 100755
--- a/acts/framework/setup.py
+++ b/acts/framework/setup.py
@@ -31,6 +31,7 @@
'mock==3.0.5',
'pyserial',
'pyyaml>=5.1',
+ 'pynacl==1.4.0',
'protobuf>=3.14.0',
'retry',
'requests',
@@ -44,6 +45,7 @@
# ed25519 ssh keys, which is what Fuchsia uses.
'paramiko-ng',
'dlipower',
+ 'usbinfo',
'zeroconf'
]
@@ -57,9 +59,13 @@
elif sys.version_info < (3, 7):
# Python 3.6 uses scipy up to 1.5 and numpy up to 1.19.x
install_requires.append('scipy<1.6')
- install_requires.append('numpy==1.18.1')
+ install_requires.append('numpy<1.20')
+elif sys.version_info < (3, 8):
+ # Python 3.7 uses latest scipy up to 1.7.x and numpy up to 1.21.x
+ install_requires.append('scipy<1.8')
+ install_requires.append('numpy<1.22')
else:
- # Python 3.7+ is supported by latest scipy and numpy
+ # Python 3.8+ is supported by latest scipy and numpy
install_requires.append('scipy')
install_requires.append('numpy')
diff --git a/acts/framework/tests/acts_android_device_test.py b/acts/framework/tests/acts_android_device_test.py
index c30cacc..374a472 100755
--- a/acts/framework/tests/acts_android_device_test.py
+++ b/acts/framework/tests/acts_android_device_test.py
@@ -684,6 +684,34 @@
ret = ad.push_system_file('asdf', 'jkl')
self.assertFalse(ret)
+ @mock.patch(
+ 'acts.controllers.adb.AdbProxy',
+ return_value=MockAdbProxy(MOCK_SERIAL))
+ @mock.patch(
+ 'acts.controllers.fastboot.FastbootProxy',
+ return_value=MockFastbootProxy(MOCK_SERIAL))
+ def test_get_my_current_focus_window_return_empty_string(self, *_):
+ ad = android_device.AndroidDevice(serial=MOCK_SERIAL)
+ ad.adb.return_value = ''
+
+ ret = ad.get_my_current_focus_window()
+
+ self.assertEqual('', ret)
+
+ @mock.patch(
+ 'acts.controllers.adb.AdbProxy',
+ return_value=MockAdbProxy(MOCK_SERIAL))
+ @mock.patch(
+ 'acts.controllers.fastboot.FastbootProxy',
+ return_value=MockFastbootProxy(MOCK_SERIAL))
+ def test_get_my_current_focus_window_return_current_window(self, *_):
+ ad = android_device.AndroidDevice(serial=MOCK_SERIAL)
+ ad.adb.return_value = 'mCurrentFocus=Window{a247ded u0 NotificationShade}'
+
+ ret = ad.get_my_current_focus_window()
+
+ self.assertEqual('NotificationShade', ret)
+
if __name__ == "__main__":
unittest.main()
diff --git a/acts/framework/tests/acts_import_unit_test.py b/acts/framework/tests/acts_import_unit_test.py
index 9823bfc..925a272 100755
--- a/acts/framework/tests/acts_import_unit_test.py
+++ b/acts/framework/tests/acts_import_unit_test.py
@@ -68,6 +68,8 @@
acts = import_acts()
self.assertIsNotNone(acts)
+ # TODO(b/190659975): Re-enable once permission issue is resolved.
+ @unittest.skip("Permission error: b/190659975")
def test_import_framework_successful(self):
"""Dynamically test all imports from the framework."""
acts = import_acts()
diff --git a/acts/framework/tests/acts_utils_test.py b/acts/framework/tests/acts_utils_test.py
index e1dbe05..601dc45 100755
--- a/acts/framework/tests/acts_utils_test.py
+++ b/acts/framework/tests/acts_utils_test.py
@@ -72,74 +72,68 @@
FUCHSIA_INTERFACES = {
'id':
'1',
- 'result': [{
- 'features':
- 4,
- 'filepath':
- '[none]',
- 'id':
- 1,
- 'ipv4_addresses': [[127, 0, 0, 1]],
- 'ipv6_addresses': [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]],
- 'is_administrative_status_enabled':
- True,
- 'is_physical_status_up':
- True,
- 'mac': [0, 0, 0, 0, 0, 0],
- 'mtu':
- 65536,
- 'name':
- 'lo',
- 'topopath':
- 'loopback'
- }, {
- 'features':
- 0,
- 'filepath':
- '/dev/class/ethernet/000',
- 'id':
- 2,
- 'ipv4_addresses': [[100, 127, 110, 79]],
- 'ipv6_addresses':
- [[254, 128, 0, 0, 0, 0, 0, 0, 198, 109, 60, 117, 44, 236, 29, 114],
- [36, 1, 250, 0, 4, 128, 122, 0, 141, 79, 133, 255, 204, 92, 120, 126],
- [36, 1, 250, 0, 4, 128, 122, 0, 4, 89, 185, 147, 252, 191, 20, 25]],
- 'is_administrative_status_enabled':
- True,
- 'is_physical_status_up':
- True,
- 'mac': [0, 224, 76, 5, 76, 229],
- 'mtu':
- 1514,
- 'name':
- 'eno1',
- 'topopath':
- '@/dev/xhci/xhci/usb-bus/001/001/ifc-000/usb-cdc-ecm/ethernet'
- }, {
- 'features':
- 1,
- 'filepath':
- '/dev/class/ethernet/001',
- 'id':
- 3,
- 'ipv4_addresses': [],
- 'ipv6_addresses':
- [[254, 128, 0, 0, 0, 0, 0, 0, 96, 255, 93, 96, 52, 253, 253, 243],
- [254, 128, 0, 0, 0, 0, 0, 0, 70, 7, 11, 255, 254, 118, 126, 192]],
- 'is_administrative_status_enabled':
- False,
- 'is_physical_status_up':
- False,
- 'mac': [68, 7, 11, 118, 126, 192],
- 'mtu':
- 1500,
- 'name':
- 'wlanxc0',
- 'topopath':
- '@/dev/wifi/wlanphy/wlanif-client/wlan-ethernet/ethernet'
- }],
+ 'result': [
+ {
+ 'id': 1,
+ 'name': 'lo',
+ 'ipv4_addresses': [
+ [127, 0, 0, 1],
+ ],
+ 'ipv6_addresses': [
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+ ],
+ 'online': True,
+ 'mac': [0, 0, 0, 0, 0, 0],
+ },
+ {
+ 'id':
+ 2,
+ 'name':
+ 'eno1',
+ 'ipv4_addresses': [
+ [100, 127, 110, 79],
+ ],
+ 'ipv6_addresses': [
+ [
+ 254, 128, 0, 0, 0, 0, 0, 0, 198, 109, 60, 117, 44, 236, 29,
+ 114
+ ],
+ [
+ 36, 1, 250, 0, 4, 128, 122, 0, 141, 79, 133, 255, 204, 92,
+ 120, 126
+ ],
+ [
+ 36, 1, 250, 0, 4, 128, 122, 0, 4, 89, 185, 147, 252, 191,
+ 20, 25
+ ],
+ ],
+ 'online':
+ True,
+ 'mac': [0, 224, 76, 5, 76, 229],
+ },
+ {
+ 'id':
+ 3,
+ 'name':
+ 'wlanxc0',
+ 'ipv4_addresses': [],
+ 'ipv6_addresses': [
+ [
+ 254, 128, 0, 0, 0, 0, 0, 0, 96, 255, 93, 96, 52, 253, 253,
+ 243
+ ],
+ [
+ 254, 128, 0, 0, 0, 0, 0, 0, 70, 7, 11, 255, 254, 118, 126,
+ 192
+ ],
+ ],
+ 'online':
+ False,
+ 'mac': [68, 7, 11, 118, 126, 192],
+ },
+ ],
'error':
- None
+ None,
}
CORRECT_FULL_IP_LIST = {
@@ -162,7 +156,9 @@
}
FUCHSIA_INIT_SERVER = ('acts.controllers.fuchsia_device.FuchsiaDevice.'
- 'init_server_connection')
+ 'init_sl4f_connection')
+FUCHSIA_INIT_FFX = ('acts.controllers.fuchsia_device.FuchsiaDevice.'
+ 'init_ffx_connection')
FUCHSIA_SET_CONTROL_PATH_CONFIG = ('acts.controllers.fuchsia_device.'
'FuchsiaDevice._set_control_path_config')
FUCHSIA_START_SERVICES = ('acts.controllers.fuchsia_device.FuchsiaDevice.'
@@ -171,12 +167,11 @@
'acts.controllers.'
'fuchsia_lib.netstack.netstack_lib.'
'FuchsiaNetstackLib.netstackListInterfaces')
-FUCHSIA_INIT_NETSTACK = ('acts.controllers.fuchsia_lib.netstack.'
- 'netstack_lib.FuchsiaNetstackLib.init')
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'):
@@ -310,6 +305,7 @@
class ConcurrentActionsTest(unittest.TestCase):
"""Tests acts.utils.run_concurrent_actions and related functions."""
+
@staticmethod
def function_returns_passed_in_arg(arg):
return arg
@@ -319,15 +315,15 @@
raise exception_type
def test_run_concurrent_actions_no_raise_returns_proper_return_values(
- self):
+ self):
"""Tests run_concurrent_actions_no_raise returns in the correct order.
Each function passed into run_concurrent_actions_no_raise returns the
values returned from each individual callable in the order passed in.
"""
ret_values = utils.run_concurrent_actions_no_raise(
- lambda: self.function_returns_passed_in_arg('ARG1'),
- lambda: self.function_returns_passed_in_arg('ARG2'),
+ lambda: self.function_returns_passed_in_arg(
+ 'ARG1'), lambda: self.function_returns_passed_in_arg('ARG2'),
lambda: self.function_returns_passed_in_arg('ARG3'))
self.assertEqual(len(ret_values), 3)
@@ -358,8 +354,8 @@
"""
ret_values = utils.run_concurrent_actions(
- lambda: self.function_returns_passed_in_arg('ARG1'),
- lambda: self.function_returns_passed_in_arg('ARG2'),
+ lambda: self.function_returns_passed_in_arg(
+ 'ARG1'), lambda: self.function_returns_passed_in_arg('ARG2'),
lambda: self.function_returns_passed_in_arg('ARG3'))
self.assertEqual(len(ret_values), 3)
@@ -393,6 +389,7 @@
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.
@@ -528,16 +525,16 @@
CORRECT_EMPTY_IP_LIST)
@mock.patch(FUCHSIA_INIT_SERVER)
+ @mock.patch(FUCHSIA_INIT_FFX)
@mock.patch(FUCHSIA_SET_CONTROL_PATH_CONFIG)
@mock.patch(FUCHSIA_START_SERVICES)
@mock.patch(FUCHSIA_NETSTACK_LIST_INTERFACES)
- @mock.patch(FUCHSIA_INIT_NETSTACK)
- def test_fuchsia_get_interface_ip_addresses_full(self, init_mock,
- list_interfaces_mock,
- start_services_mock,
- control_path_mock,
- fuchsia_device_mock):
- init_mock.return_value = None
+ def test_fuchsia_get_interface_ip_addresses_full(
+ self, list_interfaces_mock, start_services_mock, control_path_mock,
+ ffx_mock, fuchsia_device_mock):
+ # Will never actually be created/used.
+ logging.log_path = '/tmp/unit_test_garbage'
+
list_interfaces_mock.return_value = FUCHSIA_INTERFACES
fuchsia_device_mock.return_value = None
self.assertEqual(
@@ -546,16 +543,16 @@
CORRECT_FULL_IP_LIST)
@mock.patch(FUCHSIA_INIT_SERVER)
+ @mock.patch(FUCHSIA_INIT_FFX)
@mock.patch(FUCHSIA_SET_CONTROL_PATH_CONFIG)
@mock.patch(FUCHSIA_START_SERVICES)
@mock.patch(FUCHSIA_NETSTACK_LIST_INTERFACES)
- @mock.patch(FUCHSIA_INIT_NETSTACK)
- def test_fuchsia_get_interface_ip_addresses_empty(self, init_mock,
- list_interfaces_mock,
- start_services_mock,
- control_path_mock,
- fuchsia_device_mock):
- init_mock.return_value = None
+ def test_fuchsia_get_interface_ip_addresses_empty(
+ self, list_interfaces_mock, start_services_mock, control_path_mock,
+ ffx_mock, fuchsia_device_mock):
+ # Will never actually be created/used.
+ logging.log_path = '/tmp/unit_test_garbage'
+
list_interfaces_mock.return_value = FUCHSIA_INTERFACES
fuchsia_device_mock.return_value = None
self.assertEqual(
@@ -564,5 +561,33 @@
CORRECT_EMPTY_IP_LIST)
+class GetDeviceTest(unittest.TestCase):
+ class TestDevice:
+ def __init__(self, id, device_type=None) -> None:
+ self.id = id
+ if device_type:
+ self.device_type = device_type
+
+ def test_get_device_none(self):
+ devices = []
+ self.assertRaises(ValueError, utils.get_device, devices, 'DUT')
+
+ def test_get_device_default_one(self):
+ devices = [self.TestDevice(0)]
+ self.assertEqual(utils.get_device(devices, 'DUT').id, 0)
+
+ def test_get_device_default_many(self):
+ devices = [self.TestDevice(0), self.TestDevice(1)]
+ self.assertEqual(utils.get_device(devices, 'DUT').id, 0)
+
+ def test_get_device_specified_one(self):
+ devices = [self.TestDevice(0), self.TestDevice(1, 'DUT')]
+ self.assertEqual(utils.get_device(devices, 'DUT').id, 1)
+
+ def test_get_device_specified_many(self):
+ devices = [self.TestDevice(0, 'DUT'), self.TestDevice(1, 'DUT')]
+ self.assertRaises(ValueError, utils.get_device, devices, 'DUT')
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/acts/framework/tests/controllers/ap_lib/dhcp_config_test.py b/acts/framework/tests/controllers/ap_lib/dhcp_config_test.py
new file mode 100644
index 0000000..754655f
--- /dev/null
+++ b/acts/framework/tests/controllers/ap_lib/dhcp_config_test.py
@@ -0,0 +1,138 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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 ipaddress
+import unittest
+from unittest.mock import patch
+
+from acts.controllers.ap_lib.dhcp_config import DhcpConfig, Subnet, StaticMapping
+
+
+class DhcpConfigTest(unittest.TestCase):
+ def setUp(self):
+ super().setUp()
+ # These config files may have long diffs, modify this setting to
+ # ensure they're printed.
+ self.maxDiff = None
+
+ def test_basic_dhcp_config(self):
+ dhcp_conf = DhcpConfig()
+
+ expected_config = ('default-lease-time 600;\n' 'max-lease-time 7200;')
+
+ self.assertEqual(expected_config, dhcp_conf.render_config_file())
+
+ def test_dhcp_config_with_lease_times(self):
+ default_lease_time = 350
+ max_lease_time = 5000
+ dhcp_conf = DhcpConfig(default_lease_time=default_lease_time,
+ max_lease_time=max_lease_time)
+
+ expected_config = (f'default-lease-time {default_lease_time};\n'
+ f'max-lease-time {max_lease_time};')
+
+ self.assertEqual(expected_config, dhcp_conf.render_config_file())
+
+ def test_dhcp_config_with_subnets(self):
+ default_lease_time = 150
+ max_lease_time = 3000
+ subnets = [
+ # addresses from 10.10.1.0 - 10.10.1.255
+ Subnet(ipaddress.ip_network('10.10.1.0/24')),
+ # 4 addresses from 10.10.3.0 - 10.10.3.3
+ Subnet(ipaddress.ip_network('10.10.3.0/30')),
+ # 6 addresses from 10.10.5.20 - 10.10.5.25
+ Subnet(ipaddress.ip_network('10.10.5.0/24'),
+ start=ipaddress.ip_address('10.10.5.20'),
+ end=ipaddress.ip_address('10.10.5.25'),
+ router=ipaddress.ip_address('10.10.5.255'),
+ lease_time=60)
+ ]
+ dhcp_conf = DhcpConfig(subnets=subnets,
+ default_lease_time=default_lease_time,
+ max_lease_time=max_lease_time)
+
+ # Unless an explicit start/end address is provided, the second
+ # address in the range is used for "start", and the second to
+ # last address is used for "end".
+ expected_config = (f'default-lease-time {default_lease_time};\n'
+ f'max-lease-time {max_lease_time};\n'
+ 'subnet 10.10.1.0 netmask 255.255.255.0 {\n'
+ '\tpool {\n'
+ '\t\toption subnet-mask 255.255.255.0;\n'
+ '\t\toption routers 10.10.1.1;\n'
+ '\t\trange 10.10.1.2 10.10.1.254;\n'
+ '\t\toption domain-name-servers 8.8.8.8, 4.4.4.4;\n'
+ '\t}\n'
+ '}\n'
+ 'subnet 10.10.3.0 netmask 255.255.255.252 {\n'
+ '\tpool {\n'
+ '\t\toption subnet-mask 255.255.255.252;\n'
+ '\t\toption routers 10.10.3.1;\n'
+ '\t\trange 10.10.3.2 10.10.3.2;\n'
+ '\t\toption domain-name-servers 8.8.8.8, 4.4.4.4;\n'
+ '\t}\n'
+ '}\n'
+ 'subnet 10.10.5.0 netmask 255.255.255.0 {\n'
+ '\tpool {\n'
+ '\t\toption subnet-mask 255.255.255.0;\n'
+ '\t\toption routers 10.10.5.255;\n'
+ '\t\trange 10.10.5.20 10.10.5.25;\n'
+ '\t\tdefault-lease-time 60;\n'
+ '\t\tmax-lease-time 60;\n'
+ '\t\toption domain-name-servers 8.8.8.8, 4.4.4.4;\n'
+ '\t}\n'
+ '}')
+
+ self.assertEqual(expected_config, dhcp_conf.render_config_file())
+
+ def test_additional_subnet_parameters_and_options(self):
+ default_lease_time = 150
+ max_lease_time = 3000
+ subnets = [
+ Subnet(ipaddress.ip_network('10.10.1.0/24'),
+ additional_parameters={
+ 'allow': 'unknown-clients',
+ 'foo': 'bar'
+ },
+ additional_options={'my-option': 'some-value'}),
+ ]
+ dhcp_conf = DhcpConfig(subnets=subnets,
+ default_lease_time=default_lease_time,
+ max_lease_time=max_lease_time)
+
+ # Unless an explicit start/end address is provided, the second
+ # address in the range is used for "start", and the second to
+ # last address is used for "end".
+ expected_config = (f'default-lease-time {default_lease_time};\n'
+ f'max-lease-time {max_lease_time};\n'
+ 'subnet 10.10.1.0 netmask 255.255.255.0 {\n'
+ '\tpool {\n'
+ '\t\toption subnet-mask 255.255.255.0;\n'
+ '\t\toption routers 10.10.1.1;\n'
+ '\t\trange 10.10.1.2 10.10.1.254;\n'
+ '\t\tallow unknown-clients;\n'
+ '\t\tfoo bar;\n'
+ '\t\toption my-option some-value;\n'
+ '\t\toption domain-name-servers 8.8.8.8, 4.4.4.4;\n'
+ '\t}\n'
+ '}')
+
+ self.assertEqual(expected_config, dhcp_conf.render_config_file())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/acts/framework/tests/controllers/ap_lib/radvd_test.py b/acts/framework/tests/controllers/ap_lib/radvd_test.py
index 452bd65..4f23b20 100644
--- a/acts/framework/tests/controllers/ap_lib/radvd_test.py
+++ b/acts/framework/tests/controllers/ap_lib/radvd_test.py
@@ -224,3 +224,7 @@
with open(radvd_config, 'r') as radvd_config_fileId:
config_data = radvd_config_fileId.read()
self.assertTrue(CORRECT_COMPLEX_RADVD_CONFIG == config_data)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/acts/framework/tests/controllers/pdu_lib/synaccess/np02b_test.py b/acts/framework/tests/controllers/pdu_lib/synaccess/np02b_test.py
index b5e7bda..c0af8c8 100644
--- a/acts/framework/tests/controllers/pdu_lib/synaccess/np02b_test.py
+++ b/acts/framework/tests/controllers/pdu_lib/synaccess/np02b_test.py
@@ -43,6 +43,7 @@
class _TNHelperNP02BTest(unittest.TestCase):
"""Unit tests for _TNHelperNP02B."""
+
@patch('acts.controllers.pdu_lib.synaccess.np02b.time.sleep')
@patch('acts.controllers.pdu_lib.synaccess.np02b.telnetlib')
def test_cmd_is_properly_written(self, telnetlib_mock, sleep_mock):
@@ -92,6 +93,7 @@
class NP02BPduDeviceTest(unittest.TestCase):
"""Unit tests for NP02B PduDevice implementation."""
+
@patch('acts.controllers.pdu_lib.synaccess.np02b._TNHelperNP02B.cmd')
def test_status_parses_output_to_valid_dictionary(self, tnhelper_cmd_mock):
"""status should parse helper response correctly into dict."""
@@ -116,4 +118,8 @@
np02b = PduDevice(HOST, None, None)
tnhelper_cmd_mock.return_value = STATUS_RESPONSE_STR
with self.assertRaises(PduError):
- self.assertTrue(np02b._verify_state(INVALID_STATUS_DICT))
\ No newline at end of file
+ self.assertTrue(np02b._verify_state(INVALID_STATUS_DICT))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/acts/framework/tests/controllers/rohdeschwarz_lib/contest_test.py b/acts/framework/tests/controllers/rohdeschwarz_lib/contest_test.py
index d7bbc89..2139a76 100644
--- a/acts/framework/tests/controllers/rohdeschwarz_lib/contest_test.py
+++ b/acts/framework/tests/controllers/rohdeschwarz_lib/contest_test.py
@@ -14,11 +14,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from acts import base_test
+from acts import logger
from acts import asserts
+import unittest
from unittest import mock
import socket
import time
+from contextlib import closing
# TODO(markdr): Remove this hack after adding zeep to setup.py.
import sys
@@ -27,17 +29,31 @@
from acts.controllers.rohdeschwarz_lib import contest
-class ContestTest(base_test.BaseTestClass):
+def find_free_port():
+ """ Helper function to find a free port.
+ https://stackoverflow.com/a/45690594
+ """
+ with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
+ s.bind(('', 0))
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ return s.getsockname()[1]
+
+
+class ContestTest(unittest.TestCase):
""" Unit tests for the contest controller."""
LOCAL_HOST_IP = '127.0.0.1'
+ @classmethod
+ def setUpClass(self):
+ self.log = logger.create_tagged_trace_logger('contest_test')
+
def test_automation_server_end_to_end(self):
""" End to end test for the Contest object's ability to start an
Automation Server and respond to the commands sent through the
socket interface. """
- automation_port = 5555
+ automation_port = find_free_port()
# Instantiate the mock Contest object. This will start a thread in the
# background running the Automation server.
@@ -65,6 +81,7 @@
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((self.LOCAL_HOST_IP, automation_port))
s.sendall(b'AtTestcaseStart')
+ s.settimeout(1.0)
data = s.recv(1024)
asserts.assert_true(data == b'OK\n', "Received OK response.")
@@ -138,7 +155,7 @@
# immediately, rather than sleeping.
@mock.patch('time.sleep')
# Prevents the controller to try to download the results from the FTP server
- @mock.patch('acts.controllers.gnssinst_lib.rohdeschwarz.contest'
+ @mock.patch('acts.controllers.rohdeschwarz_lib.contest'
'.Contest.pull_test_results')
def test_execute_testplan_stops_reading_output_on_exit_line(
self, time_mock, results_func_mock):
@@ -162,16 +179,15 @@
with mock.patch('zeep.client.Client') as zeep_client:
zeep_client.return_value.service.DoGetOutput = service_output
- controller = contest.Contest(
- logger=self.log,
- remote_ip=None,
- remote_port=None,
- automation_listen_ip=None,
- automation_port=None,
- dut_on_func=None,
- dut_off_func=None,
- ftp_usr=None,
- ftp_pwd=None)
+ controller = contest.Contest(logger=self.log,
+ remote_ip=None,
+ remote_port=None,
+ automation_listen_ip=None,
+ automation_port=None,
+ dut_on_func=None,
+ dut_off_func=None,
+ ftp_usr=None,
+ ftp_pwd=None)
controller.execute_testplan('TestPlan')
controller.destroy()
@@ -197,22 +213,22 @@
# An array of what return values. If a value is an Exception, the
# Exception is raised instead.
service_output.side_effect = [
- 'Testplan Directory: {}{}\\ \n'.format(
- contest.Contest.FTP_ROOT, results_directory), 'Exit code: 0\n'
+ 'Testplan Directory: {}{}\\ \n'.format(contest.Contest.FTP_ROOT,
+ results_directory),
+ 'Exit code: 0\n'
]
with mock.patch('zeep.client.Client') as zeep_client:
zeep_client.return_value.service.DoGetOutput = service_output
- controller = contest.Contest(
- logger=self.log,
- remote_ip=None,
- remote_port=None,
- automation_listen_ip=None,
- automation_port=None,
- dut_on_func=None,
- dut_off_func=None,
- ftp_usr=None,
- ftp_pwd=None)
+ controller = contest.Contest(logger=self.log,
+ remote_ip=None,
+ remote_port=None,
+ automation_listen_ip=None,
+ automation_port=None,
+ dut_on_func=None,
+ dut_off_func=None,
+ ftp_usr=None,
+ ftp_pwd=None)
controller.execute_testplan('TestPlan')
@@ -245,16 +261,15 @@
with mock.patch('zeep.client.Client') as zeep_client:
zeep_client.return_value.service.DoGetOutput = service_output
- controller = contest.Contest(
- logger=self.log,
- remote_ip=None,
- remote_port=None,
- automation_listen_ip=None,
- automation_port=None,
- dut_on_func=None,
- dut_off_func=None,
- ftp_usr=None,
- ftp_pwd=None)
+ controller = contest.Contest(logger=self.log,
+ remote_ip=None,
+ remote_port=None,
+ automation_listen_ip=None,
+ automation_port=None,
+ dut_on_func=None,
+ dut_off_func=None,
+ ftp_usr=None,
+ ftp_pwd=None)
try:
controller.execute_testplan('TestPlan')
@@ -262,3 +277,7 @@
pass
controller.destroy()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/acts/framework/tests/libs/ota/ota_runners/ota_runner_factory_test.py b/acts/framework/tests/libs/ota/ota_runners/ota_runner_factory_test.py
index 042f226..5481f32 100644
--- a/acts/framework/tests/libs/ota/ota_runners/ota_runner_factory_test.py
+++ b/acts/framework/tests/libs/ota/ota_runners/ota_runner_factory_test.py
@@ -107,9 +107,8 @@
def test_create_raise_on_ota_package_not_a_list_or_string(self):
with mock.patch('acts.libs.ota.ota_tools.ota_tool_factory.create'):
with self.assertRaises(TypeError):
- ota_runner_factory.create({
- 'ota': 'pkg'
- }, {'ota': 'sl4a'}, self.device)
+ ota_runner_factory.create({'ota': 'pkg'}, {'ota': 'sl4a'},
+ self.device)
def test_create_returns_single_ota_runner_on_ota_package_being_a_str(self):
with mock.patch('acts.libs.ota.ota_tools.ota_tool_factory.create'):
@@ -131,8 +130,14 @@
def test_create_returns_different_ota_runner_on_second_request(self):
with mock.patch('acts.libs.ota.ota_tools.ota_tool_factory.create'):
- first_return = ota_runner_factory.create(
- [], [], self.device, use_cached_runners=False)
- second_return = ota_runner_factory.create(
- [], [], self.device, use_cached_runners=False)
+ first_return = ota_runner_factory.create([], [],
+ self.device,
+ use_cached_runners=False)
+ second_return = ota_runner_factory.create([], [],
+ self.device,
+ use_cached_runners=False)
self.assertNotEqual(first_return, second_return)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/acts/framework/tests/libs/ota/ota_tools/adb_sideload_ota_tool_test.py b/acts/framework/tests/libs/ota/ota_tools/adb_sideload_ota_tool_test.py
index 536fd75..21659bf 100644
--- a/acts/framework/tests/libs/ota/ota_tools/adb_sideload_ota_tool_test.py
+++ b/acts/framework/tests/libs/ota/ota_tools/adb_sideload_ota_tool_test.py
@@ -31,8 +31,8 @@
mock.patch('acts.controllers.fastboot.FastbootProxy')) as fb_proxy:
fb_proxy.return_value.devices.return_value = ""
ret = mock.Mock(
- android_device.AndroidDevice(
- serial=serial, ssh_connection=ssh_connection))
+ android_device.AndroidDevice(serial=serial,
+ ssh_connection=ssh_connection))
fb_proxy.reset_mock()
return ret
@@ -65,3 +65,7 @@
'')
runner.android_device.adb.getprop = mock.Mock(side_effect=['a', 'b'])
runner.update()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/acts/framework/tests/libs/ota/ota_tools/ota_tool_factory_test.py b/acts/framework/tests/libs/ota/ota_tools/ota_tool_factory_test.py
index 9e15177..1e38f97 100644
--- a/acts/framework/tests/libs/ota/ota_tools/ota_tool_factory_test.py
+++ b/acts/framework/tests/libs/ota/ota_tools/ota_tool_factory_test.py
@@ -47,3 +47,7 @@
ret_a = ota_tool_factory.create(MockOtaTool.__name__, 'command')
ret_b = ota_tool_factory.create(MockOtaTool.__name__, 'command')
self.assertEqual(ret_a, ret_b)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/acts/framework/tests/libs/ota/ota_tools/ota_tool_test.py b/acts/framework/tests/libs/ota/ota_tools/ota_tool_test.py
index 73ee599..3589009 100644
--- a/acts/framework/tests/libs/ota/ota_tools/ota_tool_test.py
+++ b/acts/framework/tests/libs/ota/ota_tools/ota_tool_test.py
@@ -37,3 +37,7 @@
ota_tool.OtaTool('').cleanup(obj)
except:
self.fail('End is not required and should be a virtual function.')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/acts/framework/tests/libs/ota/ota_tools/update_device_ota_tool_test.py b/acts/framework/tests/libs/ota/ota_tools/update_device_ota_tool_test.py
index a07719c..505b34f 100644
--- a/acts/framework/tests/libs/ota/ota_tools/update_device_ota_tool_test.py
+++ b/acts/framework/tests/libs/ota/ota_tools/update_device_ota_tool_test.py
@@ -30,8 +30,8 @@
mock.patch('acts.controllers.fastboot.FastbootProxy')) as fb_proxy:
fb_proxy.return_value.devices.return_value = ""
ret = mock.Mock(
- android_device.AndroidDevice(
- serial=serial, ssh_connection=ssh_connection))
+ android_device.AndroidDevice(serial=serial,
+ ssh_connection=ssh_connection))
fb_proxy.reset_mock()
return ret
@@ -77,3 +77,7 @@
del tool
self.assertTrue(mkdtemp.called)
self.assertTrue(rmtree.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/acts_tests/acts_contrib/test_utils/abstract_devices/wlan_device.py b/acts_tests/acts_contrib/test_utils/abstract_devices/wlan_device.py
index e6dcc4e..ee4c240 100644
--- a/acts_tests/acts_contrib/test_utils/abstract_devices/wlan_device.py
+++ b/acts_tests/acts_contrib/test_utils/abstract_devices/wlan_device.py
@@ -439,7 +439,7 @@
def get_default_wlan_test_interface(self):
"""Returns name of the WLAN client interface"""
- return self.device.wlan_controller.get_wlan_interface_name()
+ return self.device.wlan_client_test_interface_name
def destroy_wlan_interface(self, iface_id):
"""Function to associate a Fuchsia WLAN device.
@@ -483,14 +483,23 @@
if response.get('error'):
raise ConnectionError(
'Failed to get client network connection status')
+ result = response.get('result')
+ if isinstance(result, dict):
+ connected_to = result.get('Connected')
+ # TODO(https://fxbug.dev/85938): Remove backwards compatibility once
+ # ACTS is versioned with Fuchsia.
+ if not connected_to:
+ connected_to = result.get('connected_to')
+ if not connected_to:
+ return False
- status = response.get('result')
- if status and status.get('connected_to'):
if ssid:
- connected_ssid = ''.join(
- chr(i) for i in status['connected_to']['ssid'])
- if ssid != connected_ssid:
- return False
+ # Replace encoding errors instead of raising an exception.
+ # Since `ssid` is a string, this will not affect the test
+ # for equality.
+ connected_ssid = bytearray(connected_to['ssid']).decode(
+ encoding='utf-8', errors='replace')
+ return ssid == connected_ssid
return True
return False
diff --git a/acts_tests/acts_contrib/test_utils/abstract_devices/wlan_device_lib/AbstractDeviceWlanDeviceBaseTest.py b/acts_tests/acts_contrib/test_utils/abstract_devices/wlan_device_lib/AbstractDeviceWlanDeviceBaseTest.py
index 239accf..ba05a53 100644
--- a/acts_tests/acts_contrib/test_utils/abstract_devices/wlan_device_lib/AbstractDeviceWlanDeviceBaseTest.py
+++ b/acts_tests/acts_contrib/test_utils/abstract_devices/wlan_device_lib/AbstractDeviceWlanDeviceBaseTest.py
@@ -13,26 +13,68 @@
# 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
+
+from acts import context
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
+from mobly import utils
+from mobly.base_test import STAGE_NAME_TEARDOWN_CLASS
+
class AbstractDeviceWlanDeviceBaseTest(WifiBaseTest):
def setup_class(self):
super().setup_class()
- def on_fail(self, test_name, begin_time):
- try:
- self.dut.get_log(test_name, begin_time)
- if (not hasattr(self.dut.device, "take_bug_report_on_fail")
- or self.dut.device.take_bug_report_on_fail):
- # Take a bug report if device does not have a take bug report flag,
- # or if the flag is true
- self.dut.take_bug_report(test_name, begin_time)
- except Exception:
- pass
+ def teardown_class(self):
+ begin_time = utils.get_current_epoch_time()
+ super().teardown_class()
+ for device in getattr(self, "android_devices", []):
+ device.take_bug_report(STAGE_NAME_TEARDOWN_CLASS, begin_time)
+ for device in getattr(self, "fuchsia_devices", []):
+ device.take_bug_report(STAGE_NAME_TEARDOWN_CLASS, begin_time)
- try:
- if self.dut.device.hard_reboot_on_fail:
- self.dut.hard_power_cycle(self.pdu_devices)
- except AttributeError:
- pass
+ def on_fail(self, test_name, begin_time):
+ """Gets a wlan_device log and calls the generic device fail on DUT."""
+ self.dut.get_log(test_name, begin_time)
+ self.on_device_fail(self.dut.device, test_name, begin_time)
+
+ def on_device_fail(self, device, test_name, begin_time):
+ """Gets a generic device DUT bug report.
+
+ This method takes a bug report if the generic device does not have a
+ 'take_bug_report_on_fail', or if the flag is true. This method also
+ power cycles if 'hard_reboot_on_fail' is True.
+
+ Args:
+ device: Generic device to gather logs from.
+ test_name: Name of the test that triggered this function.
+ begin_time: Logline format timestamp taken when the test started.
+ """
+ if (not hasattr(device, "take_bug_report_on_fail")
+ or device.take_bug_report_on_fail):
+ device.take_bug_report(test_name, begin_time)
+
+ if device.hard_reboot_on_fail:
+ device.reboot(reboot_type='hard', testbed_pdus=self.pdu_devices)
+
+ def download_ap_logs(self):
+ """Downloads the DHCP and hostapad logs from the access_point.
+
+ Using the current TestClassContext and TestCaseContext this method pulls
+ the DHCP and hostapd logs and outputs them to the correct path.
+ """
+ current_path = context.get_current_context().get_full_output_path()
+ dhcp_full_out_path = os.path.join(current_path, "dhcp_log.txt")
+
+ dhcp_log_file = open(dhcp_full_out_path, 'w')
+ dhcp_log_file.write(self.access_point.get_dhcp_logs())
+ dhcp_log_file.close()
+
+ hostapd_logs = self.access_point.get_hostapd_logs()
+ for interface in hostapd_logs:
+ out_name = interface + "_hostapd_log.txt"
+ hostapd_full_out_path = os.path.join(current_path, out_name)
+ hostapd_log_file = open(hostapd_full_out_path, 'w')
+ hostapd_log_file.write(hostapd_logs[interface])
+ hostapd_log_file.close()
diff --git a/acts_tests/acts_contrib/test_utils/bt/BluetoothCarHfpBaseTest.py b/acts_tests/acts_contrib/test_utils/bt/BluetoothCarHfpBaseTest.py
index 303b961..1c20301 100644
--- a/acts_tests/acts_contrib/test_utils/bt/BluetoothCarHfpBaseTest.py
+++ b/acts_tests/acts_contrib/test_utils/bt/BluetoothCarHfpBaseTest.py
@@ -25,7 +25,7 @@
from acts.keys import Config
from acts_contrib.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
from acts_contrib.test_utils.bt.bt_test_utils import pair_pri_to_sec
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_default_state
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_default_state
from acts_contrib.test_utils.tel.tel_test_utils import get_phone_number
from acts_contrib.test_utils.tel.tel_test_utils import setup_droid_properties
diff --git a/acts_tests/acts_contrib/test_utils/bt/bt_carkit_lib.py b/acts_tests/acts_contrib/test_utils/bt/bt_carkit_lib.py
index 14a42b0..ce206da 100644
--- a/acts_tests/acts_contrib/test_utils/bt/bt_carkit_lib.py
+++ b/acts_tests/acts_contrib/test_utils/bt/bt_carkit_lib.py
@@ -26,17 +26,17 @@
from acts_contrib.test_utils.tel.tel_defines import AUDIO_ROUTE_EARPIECE
from acts_contrib.test_utils.tel.tel_defines import AUDIO_ROUTE_SPEAKER
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify
from acts_contrib.test_utils.tel.tel_test_utils import get_phone_number
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls
-from acts_contrib.test_utils.tel.tel_test_utils import sms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import wait_and_answer_call
from acts_contrib.test_utils.tel.tel_voice_utils import get_audio_route
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
from acts_contrib.test_utils.tel.tel_voice_utils import set_audio_route
from acts_contrib.test_utils.tel.tel_voice_utils import swap_calls
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
from acts.utils import exe_cmd
from acts.utils import get_current_epoch_time
diff --git a/acts_tests/acts_contrib/test_utils/bt/bt_constants.py b/acts_tests/acts_contrib/test_utils/bt/bt_constants.py
index f7bc93f..71cebd7 100644
--- a/acts_tests/acts_contrib/test_utils/bt/bt_constants.py
+++ b/acts_tests/acts_contrib/test_utils/bt/bt_constants.py
@@ -282,6 +282,12 @@
"high": 3
}
+# Bluetooth Low Energy advertise settings own address type
+ble_advertise_settings_own_address_types = {
+ "public": 0,
+ "random": 1
+}
+
# Bluetooth Low Energy service uuids for specific devices
ble_uuids = {
"p_service": "0000feef-0000-1000-8000-00805f9b34fb",
diff --git a/acts_tests/acts_contrib/test_utils/bt/bt_test_utils.py b/acts_tests/acts_contrib/test_utils/bt/bt_test_utils.py
index 9f9a518..eeb72d3 100644
--- a/acts_tests/acts_contrib/test_utils/bt/bt_test_utils.py
+++ b/acts_tests/acts_contrib/test_utils/bt/bt_test_utils.py
@@ -219,7 +219,7 @@
method. False otherwise.
"""
headset_mac_address = headset.mac_address
- connected = is_a2dp_src_device_connected(android, headset_mac_address)
+ connected = android.droid.audioIsBluetoothA2dpOn()
log.info('Devices connected before pair attempt: %s' % connected)
if not connected:
# Turn on headset and initiate pairing mode.
@@ -247,7 +247,7 @@
log.info('Waiting for connection...')
time.sleep(connection_check_period)
# Check for connection.
- connected = is_a2dp_src_device_connected(android, headset_mac_address)
+ connected = android.droid.audioIsBluetoothA2dpOn()
log.info('Devices connected after pair attempt: %s' % connected)
return connected
@@ -763,21 +763,19 @@
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]
]
metrics_dict["pwlv"][ad.serial] = [
- int(x, 16) for x in metrics_dict["pwlv"][ad.serial]
+ int(x, 16) if '0x' in x else int(x, 10) for x in metrics_dict["pwlv"][ad.serial]
]
# Processing formatted data if processing is required
if processed:
+ metrics_dict["rssi"][ad.serial] = [
+ x for x in metrics_dict["rssi"][ad.serial] if x !=0 and x != -127
+ ]
# Computes the average RSSI
metrics_dict["rssi"][ad.serial] = round(
sum(metrics_dict["rssi"][ad.serial]) /
diff --git a/acts_tests/acts_contrib/test_utils/cellular/cellular_base_test.py b/acts_tests/acts_contrib/test_utils/cellular/cellular_base_test.py
index 485b25f..87f04fd 100644
--- a/acts_tests/acts_contrib/test_utils/cellular/cellular_base_test.py
+++ b/acts_tests/acts_contrib/test_utils/cellular/cellular_base_test.py
@@ -23,12 +23,13 @@
from acts.controllers.rohdeschwarz_lib import cmw500_cellular_simulator as cmw
from acts.controllers.rohdeschwarz_lib import cmx500_cellular_simulator as cmx
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.controllers.cellular_lib import BaseSimulation as base_sim
+from acts.controllers.cellular_lib import GsmSimulation as gsm_sim
+from acts.controllers.cellular_lib import LteSimulation as lte_sim
+from acts.controllers.cellular_lib import UmtsSimulation as umts_sim
+from acts.controllers.cellular_lib import LteImsSimulation as lteims_sim
+from acts_contrib.test_utils.tel import tel_logging_utils
from acts_contrib.test_utils.tel import tel_test_utils as telutils
@@ -45,6 +46,7 @@
# Custom files
FILENAME_CALIBRATION_TABLE_UNFORMATTED = 'calibration_table_{}.json'
+ FILENAME_TEST_CONFIGS = 'cellular_test_config.json'
# Name of the files in the logs directory that will contain test results
# and other information in csv format.
@@ -62,6 +64,7 @@
self.simulation = None
self.cellular_simulator = None
self.calibration_table = {}
+ self.test_configs = {}
def setup_class(self):
""" Executed before any test case is started.
@@ -96,7 +99,8 @@
for file in self.custom_files:
if filename_calibration_table in file:
- self.calibration_table = self.unpack_custom_file(file, False)
+ with open(file, 'r') as f:
+ self.calibration_table = json.load(f)
self.log.info('Loading calibration table from ' + file)
self.log.debug(self.calibration_table)
break
@@ -104,6 +108,20 @@
# Ensure the calibration table only contains non-negative values
self.ensure_valid_calibration_table(self.calibration_table)
+ # Load test configs from json file
+ for file in self.custom_files:
+ if self.FILENAME_TEST_CONFIGS in file:
+ self.log.info('Loading test configs from ' + file)
+ with open(file, 'r') as f:
+ config_file = json.load(f)
+ self.test_configs = config_file.get(self.TAG)
+ if not self.test_configs:
+ self.log.debug(config_file)
+ raise RuntimeError('Test config file does not include '
+ 'class %s'.format(self.TAG))
+ self.log.debug(self.test_configs)
+ break
+
# Turn on airplane mode for all devices, as some might
# be unused during the test
for ad in self.android_devices:
@@ -214,23 +232,23 @@
# Changing cell parameters requires the phone to be detached
self.simulation.detach()
- # Parse simulation parameters.
- # This may throw a ValueError exception if incorrect values are passed
- # or if required arguments are omitted.
- try:
- self.simulation.parse_parameters(self.parameters)
- except ValueError as error:
- self.log.error(str(error))
- return False
-
- # Wait for new params to settle
- time.sleep(5)
+ # Configure simulation with parameters loaded from json file
+ sim_params = self.test_configs.get(self.test_name)
+ if not sim_params:
+ raise KeyError('Test config file does not contain '
+ 'settings for ' + self.test_name)
+ # Get class parameters and apply if not overwritten by test parameters
+ for key, val in self.test_configs.items():
+ if not key.startswith('test_') and key not in sim_params:
+ sim_params[key] = val
+ self.log.info('Simulation parameters: ' + str(sim_params))
+ self.simulation.configure(sim_params)
# Enable QXDM logger if required
if self.qxdm_logs:
self.log.info('Enabling the QXDM logger.')
- telutils.set_qxdm_logger_command(self.dut)
- telutils.start_qxdm_logger(self.dut)
+ tel_logging_utils.set_qxdm_logger_command(self.dut)
+ tel_logging_utils.start_qxdm_logger(self.dut)
# Start the simulation. This method will raise an exception if
# the phone is unable to attach.
@@ -250,7 +268,7 @@
# If QXDM logging was enabled pull the results
if self.qxdm_logs:
self.log.info('Stopping the QXDM logger and pulling results.')
- telutils.stop_qxdm_logger(self.dut)
+ tel_logging_utils.stop_qxdm_logger(self.dut)
self.dut.get_qxdm_logs()
def consume_parameter(self, parameter_name, num_values=0):
@@ -313,11 +331,11 @@
"""
simulation_dictionary = {
- 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
+ self.PARAM_SIM_TYPE_LTE: lte_sim.LteSimulation,
+ self.PARAM_SIM_TYPE_LTE_CA: lte_sim.LteSimulation,
+ self.PARAM_SIM_TYPE_UMTS: umts_sim.UmtsSimulation,
+ self.PARAM_SIM_TYPE_GSM: gsm_sim.GsmSimulation,
+ self.PARAM_SIM_TYPE_LTE_IMS: lteims_sim.LteImsSimulation
}
if not sim_type in simulation_dictionary:
@@ -362,21 +380,3 @@
raise TypeError('Calibration table value must be a number')
elif val < 0.0:
raise ValueError('Calibration table contains negative values')
-
- def unpack_custom_file(self, file, test_specific=True):
- """Loads a json file.
-
- Args:
- file: the common file containing pass fail threshold.
- test_specific: if True, returns the JSON element within the file
- that starts with the test class name.
- """
- with open(file, 'r') as f:
- params = json.load(f)
- if test_specific:
- try:
- return params[self.TAG]
- except KeyError:
- pass
- else:
- return params
diff --git a/acts_tests/acts_contrib/test_utils/coex/coex_test_utils.py b/acts_tests/acts_contrib/test_utils/coex/coex_test_utils.py
index 62e12af..a335f09 100644
--- a/acts_tests/acts_contrib/test_utils/coex/coex_test_utils.py
+++ b/acts_tests/acts_contrib/test_utils/coex/coex_test_utils.py
@@ -50,17 +50,17 @@
from acts_contrib.test_utils.car.car_telecom_utils import wait_for_not_in_call
from acts_contrib.test_utils.car.car_telecom_utils import wait_for_ringing
from acts_contrib.test_utils.tel.tel_test_utils import get_phone_number
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import run_multithread_func
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
from acts_contrib.test_utils.tel.tel_test_utils import setup_droid_properties
-from acts_contrib.test_utils.tel.tel_test_utils import wait_and_answer_call
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call
from acts_contrib.test_utils.wifi.wifi_power_test_utils import get_phone_ip
from acts_contrib.test_utils.wifi.wifi_test_utils import reset_wifi
from acts_contrib.test_utils.wifi.wifi_test_utils import wifi_connect
from acts_contrib.test_utils.wifi.wifi_test_utils import wifi_test_device_init
from acts_contrib.test_utils.wifi.wifi_test_utils import wifi_toggle_state
from acts.utils import exe_cmd
+from acts.libs.utils.multithread import run_multithread_func
from bokeh.layouts import column
from bokeh.models import tools as bokeh_tools
from bokeh.plotting import figure, output_file, save
diff --git a/acts_tests/acts_contrib/test_utils/gnss/gnss_test_utils.py b/acts_tests/acts_contrib/test_utils/gnss/gnss_test_utils.py
index 565f014..7b5c841 100644
--- a/acts_tests/acts_contrib/test_utils/gnss/gnss_test_utils.py
+++ b/acts_tests/acts_contrib/test_utils/gnss/gnss_test_utils.py
@@ -33,6 +33,7 @@
from acts.controllers.android_device import DEFAULT_QXDM_LOG_PATH
from acts.controllers.android_device import SL4A_APK_NAME
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
+from acts_contrib.test_utils.tel import tel_logging_utils as tlutils
from acts_contrib.test_utils.tel import tel_test_utils as tutils
from acts_contrib.test_utils.instrumentation.device.command.instrumentation_command_builder import InstrumentationCommandBuilder
from acts_contrib.test_utils.instrumentation.device.command.instrumentation_command_builder import InstrumentationTestCommandBuilder
@@ -1247,9 +1248,9 @@
"""
try:
for mask in masks:
- if not tutils.find_qxdm_log_mask(ad, mask):
+ if not tlutils.find_qxdm_log_mask(ad, mask):
continue
- tutils.set_qxdm_logger_command(ad, mask)
+ tlutils.set_qxdm_logger_command(ad, mask)
break
except Exception as e:
ad.log.error(e)
diff --git a/acts_tests/acts_contrib/test_utils/net/connectivity_test_utils.py b/acts_tests/acts_contrib/test_utils/net/connectivity_test_utils.py
index d35fe04..1b547e3 100644
--- a/acts_tests/acts_contrib/test_utils/net/connectivity_test_utils.py
+++ b/acts_tests/acts_contrib/test_utils/net/connectivity_test_utils.py
@@ -104,7 +104,14 @@
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 and DNS server hostname on DUT
+
+ :param ad: Device under test (DUT)
+ :param dns_mode: DNS mode, including OFF, OPPORTUNISTIC, STRICT
+ :param hostname: DNS server hostname
+ """
""" Set private DNS mode on dut """
if dns_mode == cconst.PRIVATE_DNS_MODE_OFF:
ad.droid.setPrivateDnsMode(False)
@@ -114,6 +121,3 @@
mode = ad.droid.getPrivateDnsMode()
host = ad.droid.getPrivateDnsSpecifier()
ad.log.info("DNS mode is %s and DNS server is %s" % (mode, host))
- asserts.assert_true(dns_mode == mode and host == hostname,
- "Failed to set DNS mode to %s and DNS to %s" % \
- (dns_mode, hostname))
diff --git a/acts_tests/acts_contrib/test_utils/net/net_test_utils.py b/acts_tests/acts_contrib/test_utils/net/net_test_utils.py
index ba1f513d..b281bd7 100644
--- a/acts_tests/acts_contrib/test_utils/net/net_test_utils.py
+++ b/acts_tests/acts_contrib/test_utils/net/net_test_utils.py
@@ -24,15 +24,18 @@
from acts import utils
from acts.controllers import adb
from acts.controllers.adb_lib.error import AdbError
+from acts.libs.proc import job
from acts.utils import start_standing_subprocess
from acts.utils import stop_standing_subprocess
from acts_contrib.test_utils.net import connectivity_const as cconst
+from acts_contrib.test_utils.tel import tel_defines
from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
-from scapy.all import get_if_list
+from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
+from scapy.config import conf
+from scapy.compat import plain_str
VPN_CONST = cconst.VpnProfile
VPN_TYPE = cconst.VpnProfileType
@@ -40,6 +43,8 @@
TCPDUMP_PATH = "/data/local/tmp/"
USB_CHARGE_MODE = "svc usb setFunctions"
USB_TETHERING_MODE = "svc usb setFunctions rndis"
+ENABLE_HARDWARE_OFFLOAD = "settings put global tether_offload_disabled 0"
+DISABLE_HARDWARE_OFFLOAD = "settings put global tether_offload_disabled 1"
DEVICE_IP_ADDRESS = "ip address"
LOCALHOST = "192.168.1.1"
@@ -287,7 +292,7 @@
return vpn_profile
-def start_tcpdump(ad, test_name):
+def start_tcpdump(ad, test_name, interface="any"):
"""Start tcpdump on all interfaces.
Args:
@@ -301,8 +306,8 @@
file_name = "%s/tcpdump_%s_%s.pcap" % (TCPDUMP_PATH, ad.serial, test_name)
ad.log.info("tcpdump file is %s", file_name)
- cmd = "adb -s {} shell tcpdump -i any -s0 -w {}".format(ad.serial,
- file_name)
+ cmd = "adb -s {} shell tcpdump -i {} -s0 -w {}".format(ad.serial,
+ interface, file_name)
try:
return start_standing_subprocess(cmd, 5)
except Exception:
@@ -462,6 +467,34 @@
return operator in carrier_supports_ipv6
+def is_carrier_supports_entitlement(dut):
+ """Verify if carrier supports entitlement
+
+ Args:
+ dut: Android device
+
+ Return:
+ True if carrier supports entitlement, otherwise false
+ """
+
+ carriers_supports_entitlement = [
+ tel_defines.CARRIER_VZW,
+ tel_defines.CARRIER_ATT,
+ tel_defines.CARRIER_TMO,
+ tel_defines.CARRIER_SBM]
+ operator = get_operator_name("log", dut)
+ return operator in carriers_supports_entitlement
+
+
+def set_cap_net_raw_capability():
+ """Set the CAP_NET_RAW capability
+
+ To send the Scapy packets, we need to get the CAP_NET_RAW capability first.
+ """
+ cap_net_raw = "sudo setcap cap_net_raw=eip $(readlink -f $(which act.py))"
+ utils.exe_cmd(cap_net_raw)
+
+
def supports_ipv6_tethering(self, dut):
"""Check if provider supports IPv6 tethering.
@@ -478,19 +511,15 @@
def start_usb_tethering(ad):
- """Start USB tethering.
+ """Start USB tethering using #startTethering API.
+
+ Enable USB tethering by #startTethering API will break the RPC session,
+ Make sure you call #ad.recreate_services after call this API - b/149116235
Args:
- ad: android device object
+ ad: AndroidDevice object
"""
- # TODO: test USB tethering by #startTethering API - b/149116235
- ad.log.info("Starting USB Tethering")
- ad.stop_services()
- ad.adb.shell(USB_TETHERING_MODE, ignore_status=True)
- ad.adb.wait_for_device()
- ad.start_services()
- if "rndis" not in ad.adb.shell(DEVICE_IP_ADDRESS):
- raise signals.TestFailure("Unable to enable USB tethering.")
+ ad.droid.connectivityStartTethering(tel_defines.TETHERING_USB, False)
def stop_usb_tethering(ad):
@@ -524,3 +553,54 @@
return new_ifaces.pop()
time.sleep(1)
asserts.fail("Timeout waiting for tethering interface on host")
+
+
+def get_if_list():
+ """Returns a list containing all network interfaces.
+
+ The newest version of Scapy.get_if_list() returns the cached interfaces,
+ which might be out-dated, and unable to perceive the interface changes.
+ Use this method when need to monitoring the network interfaces changes.
+ Reference: https://github.com/secdev/scapy/pull/2707
+
+ Returns:
+ A list of the latest network interfaces. For example:
+ ['cvd-ebr', ..., 'eno1', 'enx4afa19a8dde1', 'lo', 'wlxd03745d68d88']
+ """
+
+ # Get ifconfig output
+ result = job.run([conf.prog.ifconfig])
+ if result.exit_status:
+ raise asserts.fail(
+ "Failed to execute ifconfig: {}".format(plain_str(result.stderr)))
+
+ interfaces = [
+ line[:line.find(':')] for line in plain_str(result.stdout).splitlines()
+ if ": flags" in line.lower()
+ ]
+ return interfaces
+
+
+def enable_hardware_offload(ad):
+ """Enable hardware offload using adb shell command.
+
+ Args:
+ ad: Android device object
+ """
+ ad.log.info("Enabling hardware offload.")
+ ad.adb.shell(ENABLE_HARDWARE_OFFLOAD, ignore_status=True)
+ ad.reboot()
+ time.sleep(tel_defines.WAIT_TIME_AFTER_REBOOT)
+
+
+def disable_hardware_offload(ad):
+ """Disable hardware offload using adb shell command.
+
+ Args:
+ ad: Android device object
+ """
+ ad.log.info("Disabling hardware offload.")
+ ad.adb.shell(DISABLE_HARDWARE_OFFLOAD, ignore_status=True)
+ ad.reboot()
+ time.sleep(tel_defines.WAIT_TIME_AFTER_REBOOT)
+
diff --git a/acts_tests/acts_contrib/test_utils/net/ui_utils.py b/acts_tests/acts_contrib/test_utils/net/ui_utils.py
index 4dadda1..143719e 100644
--- a/acts_tests/acts_contrib/test_utils/net/ui_utils.py
+++ b/acts_tests/acts_contrib/test_utils/net/ui_utils.py
@@ -129,16 +129,23 @@
long_clickable
password
selected
+ A special key/value: matching_node key is used to identify If more than one nodes have the same key/value,
+ the matching_node stands for which matching node should be fetched.
Returns:
XML node of the UI element or None if not found.
"""
nodes = screen_dump_xml.getElementsByTagName('node')
+ matching_node = kwargs.pop('matching_node', 1)
+ count = 1
for node in nodes:
if match_node(node, **kwargs):
- logging.debug('Found a node matching conditions: %s',
- get_key_value_pair_strings(kwargs))
- return node
+ if count == matching_node:
+ logging.debug('Found a node matching conditions: %s',
+ get_key_value_pair_strings(kwargs))
+ return node
+ count += 1
+ return None
def wait_and_get_xml_node(device, timeout, child=None, sibling=None, **kwargs):
diff --git a/acts_tests/acts_contrib/test_utils/power/PowerBTBaseTest.py b/acts_tests/acts_contrib/test_utils/power/PowerBTBaseTest.py
index 056787c..8f19606 100644
--- a/acts_tests/acts_contrib/test_utils/power/PowerBTBaseTest.py
+++ b/acts_tests/acts_contrib/test_utils/power/PowerBTBaseTest.py
@@ -49,6 +49,7 @@
time.sleep(time_wait_in_between)
attenuation_delta = obj_atten.get_atten() - attenuation_target
obj_atten.set_atten(attenuation_target)
+ time.sleep(time_wait_in_between)
class PowerBTBaseTest(PBT.PowerBaseTest):
diff --git a/acts_tests/acts_contrib/test_utils/power/PowerBaseTest.py b/acts_tests/acts_contrib/test_utils/power/PowerBaseTest.py
index 1481e95..bf653af 100644
--- a/acts_tests/acts_contrib/test_utils/power/PowerBaseTest.py
+++ b/acts_tests/acts_contrib/test_utils/power/PowerBaseTest.py
@@ -28,7 +28,6 @@
from acts.metrics.loggers.blackbox import BlackboxMetricLogger
from acts_contrib.test_utils.power.loggers.power_metric_logger import PowerMetricLogger
from acts_contrib.test_utils.power import plot_utils
-from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
RESET_BATTERY_STATS = 'dumpsys batterystats --reset'
IPERF_TIMEOUT = 180
@@ -185,7 +184,6 @@
# Sync device time, timezone and country code
utils.require_sl4a((self.dut, ))
utils.sync_device_time(self.dut)
- wutils.set_wifi_country_code(self.dut, 'US')
screen_on_img = self.user_params.get('screen_on_img', [])
if screen_on_img:
@@ -208,8 +206,6 @@
# Set the device into rockbottom state
self.dut_rockbottom()
- wutils.reset_wifi(self.dut)
- wutils.wifi_toggle_state(self.dut, False)
# Wait for extra time if needed for the first test
if self.extra_wait:
@@ -464,6 +460,7 @@
measure_after_seconds=self.mon_info.offset,
hz=self.mon_info.freq)
self.power_monitor.measure(measurement_args=measurement_args,
+ measurement_name=self.test_name,
start_time=device_to_host_offset,
monsoon_output_path=data_path)
self.power_monitor.release_resources()
diff --git a/acts_tests/acts_contrib/test_utils/power/PowerWiFiBaseTest.py b/acts_tests/acts_contrib/test_utils/power/PowerWiFiBaseTest.py
index 7ca573e..b57a06e 100644
--- a/acts_tests/acts_contrib/test_utils/power/PowerWiFiBaseTest.py
+++ b/acts_tests/acts_contrib/test_utils/power/PowerWiFiBaseTest.py
@@ -51,6 +51,8 @@
self.mon_duration = self.iperf_duration - self.mon_offset - IPERF_TAIL
self.create_monsoon_info()
+ wutils.set_wifi_country_code(self.dut, 'US')
+
def teardown_test(self):
"""Tear down necessary objects after test case is finished.
@@ -159,3 +161,13 @@
self.mon_info.data_path,
plot_title)
return samples
+
+ def setup_test(self):
+ """Set up test specific parameters or configs.
+
+ """
+ super().setup_test()
+
+ wutils.reset_wifi(self.dut)
+ wutils.wifi_toggle_state(self.dut, False)
+
diff --git a/acts_tests/acts_contrib/test_utils/power/cellular/cellular_hotspot_traffic_power_test.py b/acts_tests/acts_contrib/test_utils/power/cellular/cellular_hotspot_traffic_power_test.py
index a4c2df6..755f511 100644
--- a/acts_tests/acts_contrib/test_utils/power/cellular/cellular_hotspot_traffic_power_test.py
+++ b/acts_tests/acts_contrib/test_utils/power/cellular/cellular_hotspot_traffic_power_test.py
@@ -15,8 +15,8 @@
# limitations under the License.
import time
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
import acts_contrib.test_utils.power.cellular.cellular_traffic_power_test as ctpt
diff --git a/acts_tests/acts_contrib/test_utils/power/cellular/cellular_traffic_power_test.py b/acts_tests/acts_contrib/test_utils/power/cellular/cellular_traffic_power_test.py
index 21e3dcf..67dc214 100644
--- a/acts_tests/acts_contrib/test_utils/power/cellular/cellular_traffic_power_test.py
+++ b/acts_tests/acts_contrib/test_utils/power/cellular/cellular_traffic_power_test.py
@@ -24,8 +24,9 @@
from acts_contrib.test_utils.power import IperfHelper as IPH
from acts_contrib.test_utils.power import plot_utils
import acts_contrib.test_utils.power.cellular.cellular_power_base_test as PWCEL
-from acts_contrib.test_utils.tel import tel_test_utils as telutils
-
+from acts_contrib.test_utils.tel.tel_logging_utils import start_adb_tcpdump
+from acts_contrib.test_utils.tel.tel_logging_utils import stop_adb_tcpdump
+from acts_contrib.test_utils.tel.tel_logging_utils import get_tcpdump_log
class PowerTelTrafficTest(PWCEL.PowerCellularLabBaseTest):
""" Cellular traffic power test.
@@ -204,8 +205,8 @@
# Pull TCP logs if enabled
if self.tcp_dumps:
self.log.info('Pulling TCP dumps.')
- telutils.stop_adb_tcpdump(self.dut)
- telutils.get_tcpdump_log(self.dut)
+ stop_adb_tcpdump(self.dut)
+ get_tcpdump_log(self.dut)
throughput = {}
@@ -333,7 +334,7 @@
# Enable TCP logger.
if self.tcp_dumps:
self.log.info('Enabling TCP logger.')
- telutils.start_adb_tcpdump(self.dut)
+ start_adb_tcpdump(self.dut)
return iperf_helpers
diff --git a/acts_tests/acts_contrib/test_utils/power/cellular/cellular_voice_call_power_test.py b/acts_tests/acts_contrib/test_utils/power/cellular/cellular_voice_call_power_test.py
index 802d8cc..f64a1e4 100644
--- a/acts_tests/acts_contrib/test_utils/power/cellular/cellular_voice_call_power_test.py
+++ b/acts_tests/acts_contrib/test_utils/power/cellular/cellular_voice_call_power_test.py
@@ -19,7 +19,8 @@
from acts.controllers.anritsu_lib.md8475a import VirtualPhoneAutoAnswer
import acts_contrib.test_utils.power.cellular.cellular_power_base_test as PWCEL
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call, hangup_call, set_phone_silent_mode
+from acts_contrib.test_utils.tel.tel_test_utils import set_phone_silent_mode
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call, hangup_call
class PowerTelVoiceCallTest(PWCEL.PowerCellularLabBaseTest):
diff --git a/acts_tests/acts_contrib/test_utils/power/cellular/cellular_volte_power_test.py b/acts_tests/acts_contrib/test_utils/power/cellular/cellular_volte_power_test.py
index 986878d..e3b9531 100644
--- a/acts_tests/acts_contrib/test_utils/power/cellular/cellular_volte_power_test.py
+++ b/acts_tests/acts_contrib/test_utils/power/cellular/cellular_volte_power_test.py
@@ -20,7 +20,8 @@
import acts.controllers.anritsu_lib.md8475a as md8475a
import acts_contrib.test_utils.power.cellular.cellular_power_base_test as PWCEL
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call, hangup_call, set_phone_silent_mode
+from acts_contrib.test_utils.tel.tel_test_utils import set_phone_silent_mode
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call, hangup_call
class PowerTelVoLTECallTest(PWCEL.PowerCellularLabBaseTest):
diff --git a/acts_tests/acts_contrib/test_utils/tel/GFTInOutBaseTest.py b/acts_tests/acts_contrib/test_utils/tel/GFTInOutBaseTest.py
index a55959a..7e28139 100644
--- a/acts_tests/acts_contrib/test_utils/tel/GFTInOutBaseTest.py
+++ b/acts_tests/acts_contrib/test_utils/tel/GFTInOutBaseTest.py
@@ -14,42 +14,25 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
-
-import sys
-import collections
-import random
import time
-import datetime
-import os
-import logging
-import subprocess
-import math
-import re
-
from acts import asserts
from acts.test_decorators import test_info
from acts.test_decorators import test_tracker_info
from acts.logger import epoch_to_log_line_timestamp
from acts.utils import get_current_epoch_time
-
+from acts.libs.utils.multithread import multithread_func
from acts.base_test import BaseTestClass
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import run_multithread_func
+from acts_contrib.test_utils.tel.tel_logging_utils import get_screen_shot_log
+from acts_contrib.test_utils.tel.tel_logging_utils import get_screen_shot_logs
+from acts_contrib.test_utils.tel.tel_logging_utils import log_screen_shot
from acts_contrib.test_utils.tel.tel_test_utils import get_service_state_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import get_screen_shot_log
-from acts_contrib.test_utils.tel.tel_test_utils import get_screen_shot_logs
-from acts_contrib.test_utils.tel.tel_test_utils import log_screen_shot
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call
-
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call
from acts_contrib.test_utils.tel.gft_inout_utils import mo_voice_call
from acts_contrib.test_utils.tel.gft_inout_utils import get_voice_call_type
from acts_contrib.test_utils.tel.gft_inout_utils import verify_data_connection
from acts_contrib.test_utils.tel.gft_inout_utils import check_network_service
-
from acts_contrib.test_utils.tel.gft_inout_defines import NO_SERVICE_POWER_LEVEL
from acts_contrib.test_utils.tel.gft_inout_defines import IN_SERVICE_POWER_LEVEL
from acts_contrib.test_utils.tel.gft_inout_defines import NO_SERVICE_AREA
@@ -58,24 +41,27 @@
from acts_contrib.test_utils.tel.gft_inout_defines import NO_WIFI_AREA
from acts_contrib.test_utils.tel.gft_inout_defines import NO_SERVICE_TIME
from acts_contrib.test_utils.tel.gft_inout_defines import WAIT_FOR_SERVICE_TIME
+from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
CELLULAR_PORT = 0
WIFI_PORT = 1
UNKNOWN = "UNKNOWN"
+
class GFTInOutBaseTest(TelephonyBaseTest):
def __init__(self, controllers):
TelephonyBaseTest.__init__(self, controllers)
self.my_error_msg = ""
+ self.tel_logger = TelephonyMetricLogger.for_test_case()
def setup_test(self):
TelephonyBaseTest.setup_test(self)
+ self.user_params["telephony_auto_rerun"] = 0
self.my_error_msg = ""
def teardown_test(self):
TelephonyBaseTest.teardown_test(self)
begin_time = get_current_epoch_time()
- self._take_bug_report(self.test_name, begin_time)
for ad in self.android_devices:
hangup_call(self.log, ad)
get_screen_shot_logs(self.android_devices)
@@ -84,20 +70,24 @@
def check_network(self):
"""check service state of network
-
Returns:
return True if android_devices are in service else return false
"""
for ad in self.android_devices:
network_type_voice = ad.droid.telephonyGetCurrentVoiceNetworkType()
network_type_data = ad.droid.telephonyGetCurrentDataNetworkType()
+ data_state = ad.droid.telephonyGetDataConnectionState()
service_state = get_service_state_by_adb(ad.log,ad)
- sim_state = ad.droid.telephonyGetSimState()
wifi_info = ad.droid.wifiGetConnectionInfo()
- if wifi_info["supplicant_state"] == "completed":
- ad.log.info("Wifi is connected to %s" %(wifi_info["SSID"]))
+ sim_state = ad.droid.telephonyGetSimState()
+ if ad.droid.wifiCheckState():
+ if wifi_info["supplicant_state"] == "completed":
+ ad.log.info("Wifi is connected=%s" %(wifi_info["SSID"]))
+ else:
+ ad.log.info("wifi_info =%s" %(wifi_info))
else:
- ad.log.info("wifi_info =%s" %(wifi_info))
+ ad.log.info("Wifi state is down.")
+ ad.log.info("data_state=%s" %(data_state))
ad.log.info("sim_state=%s" %(sim_state))
ad.log.info("networkType_voice=%s" %(network_type_voice))
ad.log.info("network_type_data=%s" %(network_type_data))
@@ -106,38 +96,41 @@
return False
return True
-
- def adjust_cellular_signal(self, power):
+ def adjust_cellular_signal(self, power, adjust_gradually=False):
"""Sets the attenuation value of cellular port
-
Args:
power: power level for attenuator to be set
-
Returns:
return True if ceullular port is set
"""
if self.user_params.get("Attenuator"):
- self.log.info("adjust cellular signal set mini-circuits to %s" %(power))
- self.attenuators[CELLULAR_PORT].set_atten(power)
+ if adjust_gradually:
+ self.log.info("adjust cellular signal gradually to mini-circuits to %s" %(power))
+ self.adjust_atten_slowly(10, NO_SERVICE_AREA)
+ else:
+ self.log.info("adjust cellular signal set mini-circuits to %s" %(power))
+ self.attenuators[CELLULAR_PORT].set_atten(power)
return True
else:
self.log.info("Attenuator is set to False in config file")
return False
- def adjust_wifi_signal(self, power):
+ def adjust_wifi_signal(self, power, adjust_gradually=False):
"""Sets the attenuation value of wifi port
-
Args:
power: power level for attenuator to be set
-
Returns:
return True if wifi port is set
"""
if self.user_params.get("Attenuator"):
- self.log.info("adjust wifi signal set mini-circuits to %s" %(power))
- self.attenuators[WIFI_PORT].set_atten(power)
- self.attenuators[2].set_atten(power)
- self.attenuators[3].set_atten(power)
+ if adjust_gradually:
+ self.log.info("adjust wifi signal set mini-circuits to %s" %(power))
+ self.adjust_atten_slowly(10, NO_WIFI_AREA)
+ else:
+ self.log.info("adjust wifi signal and set mini-circuits to %s" %(power))
+ self.attenuators[WIFI_PORT].set_atten(power)
+ self.attenuators[2].set_atten(power)
+ self.attenuators[3].set_atten(power)
else:
self.log.info("Attenuator is set to False in config file")
return False
@@ -145,10 +138,8 @@
def adjust_attens(self, power):
"""Sets the attenuation value of all attenuators in the group
-
Args:
power: power level for attenuator to be set
-
Returns:
return True if all ports are set
"""
@@ -165,11 +156,9 @@
def adjust_atten(self, port , power):
"""Sets the attenuation value of given port
-
Args:
port: port of attenuator
power: power level for attenuator to be set
-
Returns:
return True if given port is set
"""
@@ -183,11 +172,11 @@
def adjust_atten_slowly(self, adjust_level, move_to, step=9 , step_time=5):
"""adjust attenuator slowly
-
Args:
- port: port of attenuator
- power: power level for attenuator to be set
-
+ adjust_level: adjust power level for each cycle
+ move_to: NO_SERVICE_AREA, IN_SERVICE_AREA , WIFI_AREA, NO_WIFI_AREA
+ step: adjust attenuator how many time
+ step_time: wait for how many sec for each loop
Returns:
return True if given port is set
"""
@@ -234,28 +223,62 @@
self.check_network()
return True
- def verify_device_status(self, ad, call_type=None, end_call=True, talk_time=30):
+ def verify_device_status(self, ad, call_type=None, end_call=True,
+ talk_time=30, verify_data=True, verify_voice=True, data_retries=2, voice_retries=2):
"""verfiy device status includes network service, data connection and voice call
-
Args:
ad: android device
call_type: WFC call, VOLTE call. CSFB call, voice call
end_call: hangup call after voice call flag
talk_time: in call duration in sec
-
+ verify_data: flag to check data connection
+ verify_voice: flag to check voice
+ data_retries: retry times for data verification
+ voice_retris:retry times for voice call
Returns:
- return True if given port is set
+ return True if pass
"""
- test_result = True
tasks = [(check_network_service, (ad, )) for ad in self.android_devices]
if not multithread_func(self.log, tasks):
- test_result = False
- tasks = [(verify_data_connection, (ad, )) for ad in self.android_devices]
- if not multithread_func(self.log, tasks):
- test_result = False
- if call_type != None:
- tasks = [(mo_voice_call, (self.log, ad, call_type, end_call, talk_time))
+ log_screen_shot(ad, "check_network_service_fail")
+ ad.log.info("check_network_service fail")
+ return False
+ else:
+ self.log.info("check_network_service pass")
+ if verify_data:
+ tasks = [(verify_data_connection, (ad, data_retries ))
for ad in self.android_devices]
- if not multithread_func(self.log, tasks):
- test_result = False
- return test_result
+ if not multithread_func(self.log, tasks):
+ log_screen_shot(ad, "verify_data_connection_fail")
+ ad.log.info("verify_data_connection_fail")
+ return False
+ else:
+ self.log.info("verify_data_connection pass")
+ if verify_voice:
+ if call_type:
+ tasks = [(mo_voice_call, (self.log, ad, call_type, end_call,
+ talk_time, voice_retries)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ log_screen_shot(ad, "verify_voice_call_fail")
+ ad.log.info("verify_voice_call_fail")
+ return False
+ else:
+ self.log.info("verify_voice_call pass")
+ return True
+ return True
+
+
+ def _on_failure(self, error_msg="", assert_on_fail=True, test_result=False):
+ """ operation on fail
+
+ Args:
+ error_msg: error message to be written to log
+
+ """
+ if assert_on_fail:
+ asserts.assert_true(False, "assert_on_fail: %s."
+ %(error_msg),extras={"failure_cause": error_msg})
+ for ad in self.android_devices:
+ log_screen_shot(ad, error_msg)
+ self.log.info(error_msg)
+
diff --git a/acts_tests/acts_contrib/test_utils/tel/TelephonyBaseTest.py b/acts_tests/acts_contrib/test_utils/tel/TelephonyBaseTest.py
index 0eed808..c7cb108 100644
--- a/acts_tests/acts_contrib/test_utils/tel/TelephonyBaseTest.py
+++ b/acts_tests/acts_contrib/test_utils/tel/TelephonyBaseTest.py
@@ -24,73 +24,67 @@
import time
from acts import asserts
-from acts import logger as acts_logger
from acts import signals
from acts.base_test import BaseTestClass
from acts.controllers.android_device import DEFAULT_QXDM_LOG_PATH
-from acts.controllers.android_device import DEFAULT_SDM_LOG_PATH
from acts.keys import Config
from acts import records
from acts import utils
-
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- initial_set_up_for_subid_infomation
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- set_default_sub_for_all_services
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
-from acts_contrib.test_utils.tel.tel_test_utils import build_id_override
-from acts_contrib.test_utils.tel.tel_test_utils import disable_qxdm_logger
-from acts_contrib.test_utils.tel.tel_test_utils import enable_connectivity_metrics
-from acts_contrib.test_utils.tel.tel_test_utils import enable_radio_log_on
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_default_state
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_idle
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import force_connectivity_metrics_upload
-from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
-from acts_contrib.test_utils.tel.tel_test_utils import get_screen_shot_log
-from acts_contrib.test_utils.tel.tel_test_utils import get_sim_state
-from acts_contrib.test_utils.tel.tel_test_utils import get_tcpdump_log
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import print_radio_info
-from acts_contrib.test_utils.tel.tel_test_utils import reboot_device
-from acts_contrib.test_utils.tel.tel_test_utils import recover_build_id
-from acts_contrib.test_utils.tel.tel_test_utils import run_multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import setup_droid_properties
-from acts_contrib.test_utils.tel.tel_test_utils import set_phone_screen_on
-from acts_contrib.test_utils.tel.tel_test_utils import set_phone_silent_mode
-from acts_contrib.test_utils.tel.tel_test_utils import set_qxdm_logger_command
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_logger
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
-from acts_contrib.test_utils.tel.tel_test_utils import start_sdm_loggers
-from acts_contrib.test_utils.tel.tel_test_utils import start_sdm_logger
-from acts_contrib.test_utils.tel.tel_test_utils import start_tcpdumps
-from acts_contrib.test_utils.tel.tel_test_utils import stop_qxdm_logger
-from acts_contrib.test_utils.tel.tel_test_utils import stop_sdm_loggers
-from acts_contrib.test_utils.tel.tel_test_utils import stop_sdm_logger
-from acts_contrib.test_utils.tel.tel_test_utils import stop_tcpdumps
-from acts_contrib.test_utils.tel.tel_test_utils import synchronize_device_time
-from acts_contrib.test_utils.tel.tel_test_utils import unlock_sim
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_sim_ready_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_sims_ready_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import activate_wfc_on_device
-from acts_contrib.test_utils.tel.tel_test_utils import install_googleaccountutil_apk
-from acts_contrib.test_utils.tel.tel_test_utils import add_google_account
-from acts_contrib.test_utils.tel.tel_test_utils import install_googlefi_apk
-from acts_contrib.test_utils.tel.tel_test_utils import activate_google_fi_account
-from acts_contrib.test_utils.tel.tel_test_utils import check_google_fi_activated
-from acts_contrib.test_utils.tel.tel_test_utils import check_fi_apk_installed
-from acts_contrib.test_utils.tel.tel_test_utils import phone_switch_to_msim_mode
-from acts_contrib.test_utils.tel.tel_test_utils import activate_esim_using_suw
+from acts.libs.utils.multithread import multithread_func
+from acts.libs.utils.multithread import run_multithread_func
from acts_contrib.test_utils.tel.tel_defines import PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND
from acts_contrib.test_utils.tel.tel_defines import SINGLE_SIM_CONFIG, MULTI_SIM_CONFIG
from acts_contrib.test_utils.tel.tel_defines import PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND
from acts_contrib.test_utils.tel.tel_defines import PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING
from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_ABSENT
from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_UNKNOWN
-from acts_contrib.test_utils.tel.tel_defines import WIFI_VERBOSE_LOGGING_ENABLED
from acts_contrib.test_utils.tel.tel_defines import WIFI_VERBOSE_LOGGING_DISABLED
from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
from acts_contrib.test_utils.tel.tel_defines import CHIPSET_MODELS_LIST
+from acts_contrib.test_utils.tel.tel_bootloader_utils import flash_radio
+from acts_contrib.test_utils.tel.tel_ims_utils import activate_wfc_on_device
+from acts_contrib.test_utils.tel.tel_logging_utils import disable_qxdm_logger
+from acts_contrib.test_utils.tel.tel_logging_utils import get_screen_shot_log
+from acts_contrib.test_utils.tel.tel_logging_utils import set_qxdm_logger_command
+from acts_contrib.test_utils.tel.tel_logging_utils import start_dsp_logger_p21
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_logger
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_logging_utils import stop_qxdm_logger
+from acts_contrib.test_utils.tel.tel_logging_utils import start_sdm_loggers
+from acts_contrib.test_utils.tel.tel_logging_utils import start_sdm_logger
+from acts_contrib.test_utils.tel.tel_logging_utils import stop_sdm_logger
+from acts_contrib.test_utils.tel.tel_logging_utils import start_tcpdumps
+from acts_contrib.test_utils.tel.tel_logging_utils import stop_tcpdumps
+from acts_contrib.test_utils.tel.tel_logging_utils import get_tcpdump_log
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_default_state
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_idle
+from acts_contrib.test_utils.tel.tel_subscription_utils import initial_set_up_for_subid_information
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_default_sub_for_all_services
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
+from acts_contrib.test_utils.tel.tel_test_utils import build_id_override
+from acts_contrib.test_utils.tel.tel_test_utils import enable_connectivity_metrics
+from acts_contrib.test_utils.tel.tel_test_utils import enable_radio_log_on
+from acts_contrib.test_utils.tel.tel_test_utils import force_connectivity_metrics_upload
+from acts_contrib.test_utils.tel.tel_test_utils import get_sim_state
+from acts_contrib.test_utils.tel.tel_test_utils import install_apk
+from acts_contrib.test_utils.tel.tel_test_utils import print_radio_info
+from acts_contrib.test_utils.tel.tel_test_utils import reboot_device
+from acts_contrib.test_utils.tel.tel_test_utils import recover_build_id
+from acts_contrib.test_utils.tel.tel_test_utils import setup_droid_properties
+from acts_contrib.test_utils.tel.tel_test_utils import set_phone_screen_on
+from acts_contrib.test_utils.tel.tel_test_utils import set_phone_silent_mode
+from acts_contrib.test_utils.tel.tel_test_utils import synchronize_device_time
+from acts_contrib.test_utils.tel.tel_test_utils import unlock_sim
+from acts_contrib.test_utils.tel.tel_test_utils import wait_for_sim_ready_by_adb
+from acts_contrib.test_utils.tel.tel_test_utils import wait_for_sims_ready_by_adb
+from acts_contrib.test_utils.tel.tel_test_utils import install_googleaccountutil_apk
+from acts_contrib.test_utils.tel.tel_test_utils import add_google_account
+from acts_contrib.test_utils.tel.tel_test_utils import install_googlefi_apk
+from acts_contrib.test_utils.tel.tel_test_utils import activate_google_fi_account
+from acts_contrib.test_utils.tel.tel_test_utils import check_google_fi_activated
+from acts_contrib.test_utils.tel.tel_test_utils import phone_switch_to_msim_mode
+from acts_contrib.test_utils.tel.tel_test_utils import activate_esim_using_suw
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
class TelephonyBaseTest(BaseTestClass):
@@ -164,6 +158,7 @@
self.log_path = getattr(logging, "log_path", None)
self.qxdm_log = self.user_params.get("qxdm_log", True)
self.sdm_log = self.user_params.get("sdm_log", False)
+ self.dsp_log_p21 = self.user_params.get("dsp_log_p21", False)
self.enable_radio_log_on = self.user_params.get(
"enable_radio_log_on", False)
self.cbrs_esim = self.user_params.get("cbrs_esim", False)
@@ -174,6 +169,32 @@
self.fi_util = self.user_params.get("fi_util", None)
if isinstance(self.fi_util, list):
self.fi_util = self.fi_util[0]
+ self.radio_img = self.user_params.get("radio_img", None)
+ if isinstance(self.radio_img, list):
+ self.radio_img = self.radio_img[0]
+ self.modem_bin = self.user_params.get("modem_bin", None)
+ if isinstance(self.modem_bin, list):
+ self.modem_bin = self.modem_bin[0]
+ self.extra_apk = self.user_params.get("extra_apk", None)
+ if isinstance(self.extra_apk, list):
+ self.extra_apk = self.extra_apk[0]
+ self.extra_package = self.user_params.get("extra_package", None)
+
+ if self.radio_img or self.modem_bin:
+ sideload_img = True
+ if self.radio_img:
+ file_path = self.radio_img
+ elif self.modem_bin:
+ file_path = self.modem_bin
+ sideload_img = False
+ tasks = [(flash_radio, [ad, file_path, True, sideload_img])
+ for ad in self.android_devices]
+ multithread_func(self.log, tasks)
+ if self.extra_apk and self.extra_package:
+ tasks = [(install_apk, [ad, self.extra_apk, self.extra_package])
+ for ad in self.android_devices]
+ multithread_func(self.log, tasks)
+
tasks = [(self._init_device, [ad]) for ad in self.android_devices]
multithread_func(self.log, tasks)
self.skip_reset_between_cases = self.user_params.get(
@@ -237,6 +258,7 @@
def _setup_device(self, ad, sim_conf_file, qxdm_log_mask_cfg=None):
ad.qxdm_log = getattr(ad, "qxdm_log", self.qxdm_log)
ad.sdm_log = getattr(ad, "sdm_log", self.sdm_log)
+ ad.dsp_log_p21 = getattr(ad, "dsp_log_p21", self.dsp_log_p21)
if self.user_params.get("enable_connectivity_metrics", False):
enable_connectivity_metrics(ad)
if self.user_params.get("build_id_override", False):
@@ -259,6 +281,8 @@
% phone_mode)
reboot_device(ad)
+ if ad.dsp_log_p21:
+ start_dsp_logger_p21(ad)
stop_qxdm_logger(ad)
if ad.qxdm_log:
qxdm_log_mask = getattr(ad, "qxdm_log_mask", None)
@@ -337,7 +361,7 @@
activate_wfc_on_device(self.log, ad)
# Sub ID setup
- initial_set_up_for_subid_infomation(self.log, ad)
+ initial_set_up_for_subid_information(self.log, ad)
#try:
@@ -456,7 +480,8 @@
start_qxdm_loggers(self.log, self.android_devices, self.begin_time)
if getattr(self, "sdm_log", False):
start_sdm_loggers(self.log, self.android_devices)
- if getattr(self, "tcpdump_log", False) or "wfc" in self.test_name:
+ if getattr(self, "tcpdump_log", False) or "wfc" in self.test_name or (
+ "iwlan" in self.test_name):
mask = getattr(self, "tcpdump_mask", "all")
interface = getattr(self, "tcpdump_interface", "wlan0")
start_tcpdumps(
@@ -483,6 +508,11 @@
stop_tcpdumps(self.android_devices)
def on_fail(self, test_name, begin_time):
+ for ad in self.android_devices:
+ # open Phone information page
+ ad.adb.shell("am start -n com.android.phone/.settings.RadioInfo")
+ time.sleep(3)
+ ad.screenshot(f"{ad.serial}_last_screen")
self._take_bug_report(test_name, begin_time)
def on_pass(self, test_name, begin_time):
diff --git a/acts_tests/acts_contrib/test_utils/tel/amarisoft_sim_utils.py b/acts_tests/acts_contrib/test_utils/tel/amarisoft_sim_utils.py
new file mode 100644
index 0000000..5acd6d9
--- /dev/null
+++ b/acts_tests/acts_contrib/test_utils/tel/amarisoft_sim_utils.py
@@ -0,0 +1,429 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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 dataclasses
+import re
+import time
+from typing import List
+
+from acts import asserts
+from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_PIN_REQUIRED
+from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_PUK_REQUIRED
+from acts_contrib.test_utils.tel.tel_test_utils import is_sim_ready
+from acts_contrib.test_utils.tel.tel_test_utils import power_off_sim
+from acts_contrib.test_utils.tel.tel_test_utils import power_on_sim
+
+AT_COMMAND_INSTRUMENTATION = 'com.google.mdstest/com.google.mdstest.instrument.ModemATCommandInstrumentation'
+AT_COMMAND_FAILURE = 'INSTRUMENTATION_RESULT: result=FAILURE'
+LAB_PSIM_ADM_PW = '3131313131313131'
+LAB_ESIM_ADM_PW = '35363738FFFFFFFF'
+LAB_SIM_DEFAULT_PIN1 = '1234'
+LAB_SIM_DEFAULT_PUK1 = '12345678'
+UI_ELEMENT_TEXT_SECURITY_SIM_CARD_LOCK = 'SIM card lock'
+UI_ELEMENT_TEXT_LOCK_SIM_SET = 'Lock SIM card'
+UI_ELEMENT_TEXT_OK = 'OK'
+SHORT_MNC_LENGTH = 2
+
+
+@dataclasses.dataclass
+class SimInfo:
+ sub_id: int
+ slot_index: int
+ imsi: str
+ mcc_mnc: str
+ msin: str
+ display_name: str
+
+
+def get_sim_info(ad) -> List[SimInfo]:
+ """Get Lab SIM subscription information.
+
+ Args:
+ ad: Android device obj.
+
+ Returns:
+ List[SimInfo]: A list of sim information dataclass
+ """
+ sim_info = []
+ sub_info_list = ad.droid.subscriptionGetActiveSubInfoList()
+ if not sub_info_list:
+ asserts.skip('No Valid SIM in device')
+ for sub_info in sub_info_list:
+ sub_id = sub_info['subscriptionId']
+ imsi = get_sim_imsi(ad, sub_id)
+ mcc_mnc = get_sim_mcc_mnc(ad, sub_id)
+ msin = get_sim_msin(imsi, mcc_mnc)
+ sim_info.append(
+ SimInfo(
+ sub_id=sub_id,
+ slot_index=sub_info['simSlotIndex'],
+ imsi=imsi,
+ mcc_mnc=mcc_mnc,
+ msin=msin,
+ display_name=sub_info['displayName']))
+ ad.log.info(sim_info)
+ return sim_info
+
+
+def get_sim_msin(imsi, mcc_mnc):
+ """Split IMSI to get msin value."""
+ msin = imsi.split(mcc_mnc)[1]
+ return msin
+
+
+def get_sim_mcc_mnc(ad, sub_id):
+ """Get SIM MCC+MNC value by sub id."""
+ return ad.droid.telephonyGetSimOperatorForSubscription(sub_id)
+
+
+def get_sim_imsi(ad, sub_id):
+ """Get SIM IMSI value by sub id."""
+ return ad.droid.telephonyGetSubscriberIdForSubscription(sub_id)
+
+
+def unlock_sim_dsds(ad,
+ dsds=False,
+ pin=LAB_SIM_DEFAULT_PIN1,
+ puk=LAB_SIM_DEFAULT_PUK1) -> bool:
+ """Unlock SIM pin1/puk1 on single or dual sim mode.
+
+ Args:
+ ad: Android device obj.
+ dsds: True is dual sim mode, use adb command to unlock.
+ pin: pin1 code, use LAB_DEFAULT_PIN1 for default value.
+ puk: puk1 code, use LAB_DEFAULT_PUK1 for default value.
+
+ Returns:
+ True if unlock sim success. False otherwise.
+ """
+ ad.unlock_screen()
+ ad.log.info('[Dual_sim=%s] Unlock SIM', dsds)
+ if not dsds:
+ if is_sim_pin_locked(ad):
+ ad.log.info('Unlock SIM pin')
+ ad.droid.telephonySupplyPin(pin)
+ elif is_sim_puk_locked(ad):
+ ad.log.info('Unlock SIM puk')
+ ad.droid.telephonySupplyPuk(puk, pin)
+ time.sleep(1)
+ return is_sim_ready(ad.log, ad)
+ else:
+ # Checks both pSIM and eSIM states.
+ for slot_index in range(2):
+ if is_sim_pin_locked(ad, slot_index):
+ ad.log.info('[Slot index=%s] Unlock SIM PIN', slot_index)
+ if not unlock_pin_by_mds(ad, slot_index, pin):
+ ad.log.info('[Slot index=%s] AT+CPIN unlock error', slot_index)
+ elif is_sim_puk_locked(ad, slot_index):
+ ad.log.info('[Slot index=%s] Unlock SIM PUK', slot_index)
+ unlock_puk_by_adb(ad, pin, puk)
+ time.sleep(1)
+ if not is_sim_ready(ad.log, ad, slot_index):
+ return False
+ return True
+
+
+def unlock_puk_by_mds(ad, slot_index, pin, puk) -> bool:
+ """Runs AT command to disable SIM PUK1 locked.
+
+ Args:
+ ad: Android device obj.
+ slot_index: sim slot id.
+ pin: pin1 code.
+ puk: puk1 code.
+
+ Returns:
+ True if response 'OK'. False otherwise.
+ """
+ set_at_command_channel(ad, slot_index)
+ command = r'AT+CPIN=\"' + puk + r'\",\"' + pin + r'\"'
+ cmd = (f'am instrument -w -e request "{command}" '
+ f'-e response wait {AT_COMMAND_INSTRUMENTATION}')
+ ad.log.info('Unlock sim pin by AT command')
+ output = ad.adb.shell(cmd)
+ if grep(AT_COMMAND_FAILURE, output):
+ asserts.skip('Failed to run MDS test command')
+ if grep('OK', output):
+ return True
+ else:
+ return False
+
+
+def unlock_pin_by_mds(ad, slot_index, pin) -> bool:
+ """Runs AT command to disable SIM PIN1 locked.
+
+ Args:
+ ad: Android device obj.
+ slot_index: sim slot id.
+ pin: pin1 code, use LAB_DEFAULT_PIN1 for default value.
+
+ Returns:
+ True if response 'OK'. False otherwise.
+ """
+ set_at_command_channel(ad, slot_index)
+ command = r'AT+CPIN=\"' + pin + r'\"'
+ cmd = (f'am instrument -w -e request "{command}" '
+ f'-e response wait {AT_COMMAND_INSTRUMENTATION}')
+ ad.log.info('Unlock sim pin by AT command')
+ output = ad.adb.shell(cmd)
+ if grep(AT_COMMAND_FAILURE, output):
+ asserts.skip('Failed to run MDS test command')
+ if grep('OK', output):
+ return True
+ else:
+ return False
+
+
+def unlock_puk_by_adb(ad, pin, puk) -> None:
+ """Unlock puk1 by adb keycode.
+
+ Args:
+ ad: Android device obj.
+ pin: pin1 code.
+ puk: puk1 code.
+
+ """
+ for key_code in puk:
+ ad.send_keycode(key_code)
+ time.sleep(1)
+ ad.send_keycode('ENTER')
+ time.sleep(1)
+ # PIN required 2 times
+ for _ in range(2):
+ for key_code in pin:
+ ad.send_keycode(key_code)
+ time.sleep(1)
+ ad.send_keycode('ENTER')
+ time.sleep(1)
+
+
+def lock_puk_by_mds(ad, slot_index) -> bool:
+ """Inputs wrong PIN1 code 3 times to make PUK1 locked.
+
+ Args:
+ ad: Android device obj.
+ slot_index: Sim slot id.
+
+ Returns:
+ True if SIM puk1 locked. False otherwise.
+ """
+ ad.unlock_screen()
+ wrong_pin = '1111'
+ for count in range(3):
+ if not unlock_pin_by_mds(ad, slot_index, wrong_pin):
+ ad.log.info('Error input pin:%d', count+1)
+ time.sleep(1)
+ ad.reboot()
+ return is_sim_puk_locked(ad, slot_index)
+
+
+def is_sim_puk_locked(ad, slot_index=None) -> bool:
+ """Checks whether SIM puk1 is locked on single or dual sim mode.
+
+ Args:
+ ad: Android device obj.
+ slot_index: Check the SIM status for slot_index.
+ This is optional. If this is None, check default SIM.
+
+ Returns:
+ True if SIM puk1 locked. False otherwise.
+ """
+ if slot_index is None:
+ status = ad.droid.telephonyGetSimState()
+ else:
+ status = ad.droid.telephonyGetSimStateForSlotId(slot_index)
+ if status != SIM_STATE_PUK_REQUIRED:
+ ad.log.info('Sim state is %s', status)
+ return False
+ return True
+
+
+def is_sim_pin_locked(ad, slot_index=None) -> bool:
+ """Checks whether SIM pin is locked on single or dual sim mode.
+
+ Args:
+ ad: Android device obj.
+ slot_index: Check the SIM status for slot_index. This is optional. If this
+ is None, check default SIM.
+
+ Returns:
+ True if SIM pin1 locked. False otherwise.
+ """
+ if slot_index is None:
+ status = ad.droid.telephonyGetSimState()
+ else:
+ status = ad.droid.telephonyGetSimStateForSlotId(slot_index)
+ if status != SIM_STATE_PIN_REQUIRED:
+ ad.log.info('Sim state is %s', status)
+ return False
+ return True
+
+
+def set_at_command_channel(ad, slot_index: int) -> bool:
+ """Runs AT command to set AT command channel by MDS tool(pSIM=1,eSIM=2).
+
+ Args:
+ ad: Android device obj.
+ slot_index: Sim slot id.
+
+ Returns:
+ True if response 'OK'. False otherwise.
+ """
+ channel = slot_index + 1
+ command = f'AT+CSUS={channel}'
+ cmd = (f'am instrument -w -e request "{command}" '
+ f'-e response wait {AT_COMMAND_INSTRUMENTATION}')
+ ad.log.info('Set AT command channel')
+ output = ad.adb.shell(cmd)
+ if grep(AT_COMMAND_FAILURE, output):
+ asserts.skip('Failed to run MDS test command')
+ if grep('OK', output):
+ return True
+ else:
+ return False
+
+
+def sim_enable_pin_by_mds(ad, pin) -> bool:
+ """Runs AT command to enable SIM PIN1 locked by MDS tool.
+
+ Args:
+ ad: Android device obj.
+ pin: PIN1 code.
+
+ Returns:
+ True if response 'OK'. False otherwise.
+ """
+ command = r'AT+CLCK=\"SC\",1,\"' + pin + r'\"'
+ cmd = (f'am instrument -w -e request "{command}" '
+ f'-e response wait {AT_COMMAND_INSTRUMENTATION}')
+ ad.log.info('Enable sim pin by AT command')
+ output = ad.adb.shell(cmd)
+ if grep(AT_COMMAND_FAILURE, output):
+ asserts.skip('Failed to run MDS test command')
+ if grep('OK', output):
+ return True
+ else:
+ return False
+
+
+def sim_disable_pin_by_mds(ad, pin) -> bool:
+ """Runs AT command to disable SIM PIN1 locked by MDS tool.
+
+ Args:
+ ad: Android device obj.
+ pin: PIN1 code.
+
+ Returns:
+ True if response 'OK'. False otherwise.
+ """
+ command = r'AT+CLCK=\"SC\",0,\"' + pin + r'\"'
+ cmd = (f'am instrument -w -e request "{command}" '
+ f'-e response wait {AT_COMMAND_INSTRUMENTATION}')
+ ad.log.info('Disable sim pin by AT command')
+ output = ad.adb.shell(cmd)
+ if grep(AT_COMMAND_FAILURE, output):
+ asserts.skip('Failed to run MDS test command')
+ if grep('OK', output):
+ return True
+ else:
+ return False
+
+
+def set_sim_lock(ad, enable, slot_index, pin=LAB_SIM_DEFAULT_PIN1) -> bool:
+ """Enable/disable SIM card lock.
+
+ Args:
+ ad: Android device obj.
+ enable: True is to enable sim lock. False is to disable.
+ slot_index: Sim slot id.
+ pin: Pin1 code.
+
+ Returns:
+ True if enable/disable SIM lock successfully.False otherwise.
+ """
+ if enable:
+ ad.log.info('[Slot:%d]Enable SIM pin1 locked by mds', slot_index)
+ if not set_at_command_channel(ad, slot_index):
+ ad.log.info('[Slot:%d] set AT command on MDS tool not OK', slot_index)
+ if sim_enable_pin_by_mds(ad, pin):
+ ad.reboot()
+ return is_sim_pin_locked(ad, slot_index)
+ else:
+ ad.log.info('[Slot:%d]Disable SIM pin1 locked by mds', slot_index)
+ if not set_at_command_channel(ad, slot_index):
+ ad.log.info('[Slot:%d] set AT command on MDS tool not OK', slot_index)
+ if sim_disable_pin_by_mds(ad, pin):
+ ad.reboot()
+ return is_sim_ready(ad.log, ad, slot_index)
+
+
+def activate_sim(ad,
+ slot_index=None,
+ dsds=False,
+ pin=LAB_SIM_DEFAULT_PIN1,
+ puk=LAB_SIM_DEFAULT_PUK1) -> bool:
+ """Activate sim state with slot id. Check sim lock state after activating.
+
+ Args:
+ ad: Android_device obj.
+ slot_index: Sim slot id.
+ dsds: True is dual sim mode, False is single mode.
+ pin: pin1 code, use LAB_DEFAULT_PIN1 for default value.
+ puk: puk1 code, use LAB_DEFAULT_PUK1 for default value.
+ Returns:
+ True if activate SIM lock successfully.False otherwise.
+ """
+ ad.log.info('Disable SIM slot')
+ if not power_off_sim(ad, slot_index):
+ return False
+ time.sleep(2)
+ ad.log.info('Enable SIM slot')
+ if not power_on_sim(ad, slot_index):
+ return False
+ unlock_sim_dsds(ad, dsds, pin, puk)
+ return True
+
+
+def grep(regex, output):
+ """Returns the line in an output stream that matches a given regex pattern."""
+ lines = output.strip().splitlines()
+ results = []
+ for line in lines:
+ if re.search(regex, line):
+ results.append(line.strip())
+ return results
+
+
+def modify_sim_imsi(ad,
+ new_imsi,
+ sim_info,
+ sim_adm=LAB_PSIM_ADM_PW):
+ """Uses ADB Content Provider Command to Read/Update EF (go/pmw-see-adb).
+
+ Args:
+ ad: Android_device obj.
+ new_imsi: New IMSI string to be set.
+ sim_info: SimInfo dataclass log.
+ sim_adm: SIM slot adm password.
+ """
+ cmd = (f"content update --uri content://com.google.android.wsdsimeditor.EF/EFIMSI "
+ f"--bind data:s:'{new_imsi}' --bind format:s:'raw' "
+ f"--bind adm:s:'{sim_adm}' --where slot={sim_info.slot_index}")
+ ad.log.info('Update IMSI cmd = %s', cmd)
+ ad.adb.shell(cmd)
+ time.sleep(5)
+ modified_imsi = get_sim_imsi(ad, sim_info.sub_id)
+ asserts.assert_equal(new_imsi, modified_imsi)
diff --git a/acts_tests/acts_contrib/test_utils/tel/anritsu_utils.py b/acts_tests/acts_contrib/test_utils/tel/anritsu_utils.py
index 04a9e35..2e04dac 100644
--- a/acts_tests/acts_contrib/test_utils/tel/anritsu_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/anritsu_utils.py
@@ -47,11 +47,11 @@
from acts_contrib.test_utils.tel.tel_defines import EventSmsDeliverSuccess
from acts_contrib.test_utils.tel.tel_defines import EventSmsSentSuccess
from acts_contrib.test_utils.tel.tel_defines import EventSmsReceived
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_idle
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import wait_and_answer_call
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_droid_not_in_call
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_droid_not_in_call
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call
# Timers
# Time to wait after registration before sending a command to Anritsu
@@ -480,7 +480,7 @@
None
"""
# Setting IP address for internet connection sharing
- # Google Fi _init_PDN
+ # Google Fi _init_PDN
if sim_card == FiTMO or sim_card == FiSPR or sim_card == FiUSCC:
pdn.ue_address_ipv4 = ipv4
pdn.ue_address_ipv6 = ipv6
@@ -498,9 +498,9 @@
pdn.secondary_dns_address_ipv4 = Fi_DNS_IPV4_ADDR_Sec
pdn.dns_address_ipv6 = Fi_DNS_IPV6_ADDR
pdn.cscf_address_ipv4 = Fi_CSCF_IPV4_ADDR_Data
- pdn.cscf_address_ipv6 = Fi_CSCF_IPV6_ADDR_Data
+ pdn.cscf_address_ipv6 = Fi_CSCF_IPV6_ADDR_Data
# Pixel Lab _init_PDN_
- else:
+ else:
anritsu_handle.gateway_ipv4addr = GATEWAY_IPV4_ADDR
pdn.ue_address_ipv4 = ipv4
pdn.ue_address_ipv6 = ipv6
@@ -550,7 +550,7 @@
vnid.cscf_monitoring_ua = CSCF_Monitoring_UA_URI
vnid.psap = Switch.ENABLE
vnid.psap_auto_answer = Switch.ENABLE
- else:
+ else:
vnid.cscf_address_ipv4 = CSCF_IPV4_ADDR
vnid.cscf_address_ipv6 = ipv6_address
vnid.imscscf_iptype = ip_type
diff --git a/acts_tests/acts_contrib/test_utils/tel/gft_inout_defines.py b/acts_tests/acts_contrib/test_utils/tel/gft_inout_defines.py
index 2ec1d21..536b13f 100644
--- a/acts_tests/acts_contrib/test_utils/tel/gft_inout_defines.py
+++ b/acts_tests/acts_contrib/test_utils/tel/gft_inout_defines.py
@@ -36,4 +36,5 @@
VOLTE_CALL = "volte"
CSFB_CALL = "csfb"
WFC_CALL = "wfc_call"
+NO_VOICE_CALL = "no voice call"
diff --git a/acts_tests/acts_contrib/test_utils/tel/gft_inout_utils.py b/acts_tests/acts_contrib/test_utils/tel/gft_inout_utils.py
index 8cfaa21..2e4cfd4 100644
--- a/acts_tests/acts_contrib/test_utils/tel/gft_inout_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/gft_inout_utils.py
@@ -14,60 +14,28 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
-import json
-import logging
-import re
-import os
-import urllib.parse
import time
-from acts.controllers import android_device
-
-from acts_contrib.test_utils.tel.tel_test_utils import get_telephony_signal_strength
-from acts_contrib.test_utils.tel.tel_test_utils import get_sim_state
-from acts_contrib.test_utils.tel.tel_test_utils import get_service_state_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.tel.tel_test_utils import start_youtube_video
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_ringing_call
-from acts_contrib.test_utils.tel.tel_test_utils import wait_and_answer_call
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call_active
-from acts_contrib.test_utils.tel.tel_test_utils import get_screen_shot_log
-from acts_contrib.test_utils.tel.tel_test_utils import get_screen_shot_logs
-from acts_contrib.test_utils.tel.tel_test_utils import log_screen_shot
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_not_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_1x
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
-
-from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_CONNECTED
-from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_DISCONNECTED
-from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_EMERGENCY_ONLY
-from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_IN_SERVICE
-from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_UNKNOWN
-from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_OUT_OF_SERVICE
-from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_POWER_OFF
-from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_ABSENT
-from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_LOADED
-from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_NOT_READY
-from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_PIN_REQUIRED
-from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_READY
-from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_UNKNOWN
-
-from acts_contrib.test_utils.tel.gft_inout_defines import VOICE_CALL
from acts_contrib.test_utils.tel.gft_inout_defines import VOLTE_CALL
from acts_contrib.test_utils.tel.gft_inout_defines import CSFB_CALL
from acts_contrib.test_utils.tel.gft_inout_defines import WFC_CALL
+from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_CONNECTED
+from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_IN_SERVICE
+from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_OUT_OF_SERVICE
+from acts_contrib.test_utils.tel.tel_logging_utils import log_screen_shot
+from acts_contrib.test_utils.tel.tel_ims_utils import is_ims_registered
+from acts_contrib.test_utils.tel.tel_test_utils import get_telephony_signal_strength
+from acts_contrib.test_utils.tel.tel_test_utils import get_service_state_by_adb
+from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
+from acts_contrib.test_utils.tel.tel_data_utils import browsing_test
-
-def check_no_service_time(ad, timeout=30):
+def check_no_service_time(ad, timeout=120):
""" check device is no service or not
Args:
@@ -77,19 +45,23 @@
Returns:
True if pass; False if fail.
"""
+
for i in range (timeout):
service_state = get_service_state_by_adb(ad.log,ad)
if service_state != SERVICE_STATE_IN_SERVICE:
- ad.log.info("device becomes no/limited service in %s sec and service_state=%s" %(i+1, service_state))
+ ad.log.info("device becomes no/limited service in %s sec and service_state=%s"
+ %(i+1, service_state))
get_telephony_signal_strength(ad)
return True
time.sleep(1)
get_telephony_signal_strength(ad)
check_network_service(ad)
- ad.log.info("device does not become no/limited service in %s sec and service_state=%s" %(timeout, service_state))
+ ad.log.info("device does not become no/limited service in %s sec and service_state=%s"
+ %(timeout, service_state))
return False
-def check_back_to_service_time(ad, timeout=30):
+
+def check_back_to_service_time(ad, timeout=120):
""" check device is back to service or not
Args:
@@ -104,17 +76,21 @@
if service_state == SERVICE_STATE_IN_SERVICE:
if i==0:
check_network_service(ad)
- ad.log.info("Skip check_back_to_service_time. Device is in-service and service_state=%s" %(service_state))
+ ad.log.info("Skip check_back_to_service_time. Service_state=%s"
+ %(service_state))
return True
else:
- ad.log.info("device is back to service in %s sec and service_state=%s" %(i+1, service_state))
+ ad.log.info("device is back to service in %s sec and service_state=%s"
+ %(i+1, service_state))
get_telephony_signal_strength(ad)
return True
time.sleep(1)
get_telephony_signal_strength(ad)
- ad.log.info("device is not back in service in %s sec and service_state=%s" %(timeout, service_state))
+ ad.log.info("device is not back in service in %s sec and service_state=%s"
+ %(timeout, service_state))
return False
+
def check_network_service(ad):
""" check network service
@@ -133,10 +109,13 @@
ad.log.info("networkType_data=%s" %(network_type_data))
ad.log.info("service_state=%s" %(service_state))
if service_state == SERVICE_STATE_OUT_OF_SERVICE:
+ log_screen_shot(ad, "device_out_of_service")
return False
return True
-def mo_voice_call(log, ad, call_type, end_call=True, talk_time=15):
+
+def mo_voice_call(log, ad, call_type, end_call=True, talk_time=15,
+ retries=1, retry_time=30):
""" MO voice call and check call type.
End call if necessary.
@@ -146,35 +125,48 @@
call_type: WFC call, VOLTE call. CSFB call, voice call
end_call: hangup call after voice call flag
talk_time: in call duration in sec
+ retries: retry times
+ retry_time: wait for how many sec before next retry
Returns:
True if pass; False if fail.
"""
callee_number = ad.mt_phone_number
- ad.log.info("MO voice call")
+ ad.log.info("MO voice call. call_type=%s" %(call_type))
if is_phone_in_call(log, ad):
ad.log.info("%s is in call. hangup_call before initiate call" %(callee_number))
hangup_call(log, ad)
time.sleep(1)
- if initiate_call(log, ad, callee_number):
- time.sleep(5)
- check_voice_call_type(ad,call_type)
- get_voice_call_type(ad)
- else:
- ad.log.error("initiate_call fail")
- return False
+ for i in range(retries):
+ ad.log.info("mo_voice_call attempt %d", i + 1)
+ if initiate_call(log, ad, callee_number):
+ time.sleep(5)
+ check_voice_call_type(ad,call_type)
+ get_voice_call_type(ad)
+ break
+ else:
+ ad.log.error("initiate_call fail attempt %d", i + 1)
+ time.sleep(retry_time)
+ if i+1 == retries:
+ ad.log.error("mo_voice_call retry failure")
+ return False
- time.sleep(talk_time)
+ time.sleep(10)
if end_call:
+ time.sleep(talk_time)
if is_phone_in_call(log, ad):
ad.log.info("end voice call")
if not hangup_call(log, ad):
ad.log.error("end call fail")
+ ad.droid.telecomShowInCallScreen()
+ log_screen_shot(ad, "end_call_fail")
return False
else:
#Call drop is unexpected
ad.log.error("%s Unexpected call drop" %(call_type))
+ ad.droid.telecomShowInCallScreen()
+ log_screen_shot(ad, "call_drop")
return False
ad.log.info("%s successful" %(call_type))
return True
@@ -191,6 +183,7 @@
True if pass; False if fail.
"""
if is_phone_in_call(ad.log, ad):
+ ad.droid.telecomShowInCallScreen()
log_screen_shot(ad, "expected_call_type_%s" %call_type)
if call_type == CSFB_CALL:
if not is_phone_in_call_csfb(ad.log, ad):
@@ -239,16 +232,74 @@
ad.log.error("device is not in call")
return "UNKNOWN"
-def verify_data_connection(ad):
- data_state = ad.droid.telephonyGetDataConnectionState()
- if data_state != DATA_STATE_CONNECTED:
- ad.log.error("data is not connected. data_state=%s" %(data_state))
- return False
- else:
- #Verify internet connection by ping test and http connection
+
+def verify_data_connection(ad, retries=3, retry_time=30):
+ """ verify data connection
+
+ Args:
+ ad: android device
+ retries: retry times
+ retry_time: wait for how many sec before next retry
+
+ Returns:
+ True if pass; False if fail.
+ """
+ for i in range(retries):
+ data_state = ad.droid.telephonyGetDataConnectionState()
+ wifi_info = ad.droid.wifiGetConnectionInfo()
+ if wifi_info["supplicant_state"] == "completed":
+ ad.log.info("Wifi is connected=%s" %(wifi_info["SSID"]))
+ ad.log.info("verify_data_connection attempt %d", i + 1)
if not verify_internet_connection(ad.log, ad, retries=3):
data_state = ad.droid.telephonyGetDataConnectionState()
- ad.log.error("verify_internet_connection fail. data_state=%s" %(data_state))
+ network_type_data = ad.droid.telephonyGetCurrentDataNetworkType()
+ ad.log.error("verify_internet fail. data_state=%s, network_type_data=%s"
+ %(data_state, network_type_data))
+ ad.log.info("verify_data_connection fail attempt %d", i + 1)
+ log_screen_shot(ad, "verify_internet")
+ time.sleep(retry_time)
+ else:
+ ad.log.info("verify_data_connection pass")
+ return True
+ return False
+
+
+def check_ims_state(ad):
+ """ check current ism state
+
+ Args:
+ ad: android device
+
+ Returns:
+ ims state
+ """
+ r1 = is_ims_registered(ad.log, ad)
+ r2 = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform()
+ r3 = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser()
+ r4 = ad.droid.telephonyIsVolteAvailable()
+ ad.log.info("telephonyIsImsRegistered=%s" %(r1))
+ ad.log.info("imsIsEnhanced4gLteModeSettingEnabledByPlatform=%s" %(r2))
+ ad.log.info("imsIsEnhanced4gLteModeSettingEnabledByUser=%s" %(r3))
+ ad.log.info("telephonyIsVolteAvailable=%s" %(r4))
+ return r1
+
+
+def browsing_test_ping_retry(ad):
+ """ If browse test fails, use ping to test data connection
+
+ Args:
+ ad: android device
+
+ Returns:
+ True if pass; False if fail.
+ """
+ if not browsing_test(ad.log, ad):
+ ad.log.error("Failed to browse websites!")
+ if verify_data_connection(ad):
+ ad.log.info("Ping success!")
+ return True
+ else:
+ ad.log.info("Ping fail!")
return False
- ad.log.info("verify_data_connection pass")
- return True
+ else:
+ ad.log.info("Successful to browse websites!")
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_5g_test_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_5g_test_utils.py
index 91cdd38..5b81979 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_5g_test_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_5g_test_utils.py
@@ -15,61 +15,76 @@
# limitations under the License.
import time
-import random
-import re
-from queue import Empty
-from acts.utils import rand_ascii_str
-from acts_contrib.test_utils.tel.tel_defines import GEN_5G
+from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_NR_LTE_GSM_WCDMA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_NR_ONLY
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
-from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_network_mode_pref
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_defines import GEN_4G
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_WCDMA_ONLY
from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_nsa
from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_sa
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_network_generation
+from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_network_mode_pref
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_test_utils import get_current_override_network_type
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
-def provision_device_for_5g(log, ads, sa_5g=False, nsa_mmwave=False):
+def provision_device_for_5g(log, ads, nr_type = None, mmwave = None):
"""Provision Devices for 5G
Args:
log: Log object.
ads: android device object(s).
- sa_5g: Check for provision on sa_5G or not
- nsa_mmwave: If true, check the band of NSA network is mmWave. Default is to check sub-6.
+ nr_type: NR network type.
+ mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+ None to detect both.
Returns:
True: Device(s) are provisioned on 5G
False: Device(s) are not provisioned on 5G
"""
- if sa_5g:
- if not provision_device_for_5g_sa(log, ads):
+ if nr_type == 'sa':
+ if not provision_device_for_5g_sa(
+ log, ads, mmwave=mmwave):
+ return False
+ elif nr_type == 'nsa':
+ if not provision_device_for_5g_nsa(
+ log, ads, mmwave=mmwave):
+ return False
+ elif nr_type == 'mmwave':
+ if not provision_device_for_5g_nsa(
+ log, ads, mmwave=mmwave):
return False
else:
- if not provision_device_for_5g_nsa(log, ads, nsa_mmwave=nsa_mmwave):
+ if not provision_device_for_5g_nsa(
+ log, ads, mmwave=mmwave):
return False
return True
-def provision_device_for_5g_nsa(log, ads, nsa_mmwave=False):
+def provision_device_for_5g_nsa(log, ads, mmwave = None):
"""Provision Devices for 5G NSA
Args:
log: Log object.
ads: android device object(s).
- nsa_mmwave: If true, check the band of NSA network is mmWave. Default is to check sub-6.
+ mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+ None to detect both.
Returns:
True: Device(s) are provisioned on 5G NSA
False: Device(s) are not provisioned on 5G NSA
"""
+
if isinstance(ads, list):
# Mode Pref
tasks = [(set_preferred_mode_for_5g, [ad]) for ad in ads]
@@ -77,9 +92,9 @@
log.error("failed to set preferred network mode on 5g")
return False
# Attach
- tasks = [(is_current_network_5g_nsa, [ad, nsa_mmwave]) for ad in ads]
+ tasks = [(is_current_network_5g_nsa, [ad, None, mmwave]) for ad in ads]
if not multithread_func(log, tasks):
- log.error("phone not on 5g nsa")
+ log.error("phone not on 5g")
return False
return True
else:
@@ -87,8 +102,8 @@
set_preferred_mode_for_5g(ads)
# Attach nsa5g
- if not is_current_network_5g_nsa(ads, nsa_mmwave=nsa_mmwave):
- ads.log.error("Phone not attached on nsa 5g")
+ if not is_current_network_5g_nsa(ads, mmwave=mmwave):
+ ads.log.error("Phone not attached on 5g")
return False
return True
@@ -169,29 +184,32 @@
return True
-def verify_5g_attach_for_both_devices(log, ads, sa_5g=False, nsa_mmwave=False):
+def verify_5g_attach_for_both_devices(log, ads, nr_type = None, mmwave = None):
"""Verify the network is attached
Args:
log: Log object.
ads: android device object(s).
- sa_5g: Check for verify data network type is on 5G SA or not
- nsa_mmwave: If true, check the band of NSA network is mmWave. Default is to check sub-6.
+ nr_type: 'sa' for 5G standalone, 'nsa' for 5G non-standalone,
+ 'mmwave' for 5G millimeter wave.
+ mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+ None to detect both.
Returns:
True: Device(s) are attached on 5G
False: Device(s) are not attached on 5G NSA
"""
- if sa_5g:
+
+ if nr_type=='sa':
# Attach
- tasks = [(is_current_network_5g_sa, [ad]) for ad in ads]
+ tasks = [(is_current_network_5g_sa, [ad, None, mmwave]) for ad in ads]
if not multithread_func(log, tasks):
log.error("phone not on 5g sa")
return False
return True
else:
# Attach
- tasks = [(is_current_network_5g_nsa, [ad, nsa_mmwave]) for ad in ads]
+ tasks = [(is_current_network_5g_nsa, [ad, None, mmwave]) for ad in ads]
if not multithread_func(log, tasks):
log.error("phone not on 5g nsa")
return False
@@ -212,17 +230,20 @@
return set_preferred_network_mode_pref(ad.log, ad, sub_id, mode)
-def provision_device_for_5g_sa(log, ads):
+def provision_device_for_5g_sa(log, ads, mmwave = None):
"""Provision Devices for 5G SA
Args:
log: Log object.
ads: android device object(s).
+ mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+ None to detect both.
Returns:
True: Device(s) are provisioned on 5G SA
False: Device(s) are not provisioned on 5G SA
"""
+
if isinstance(ads, list):
# Mode Pref
tasks = [(set_preferred_mode_for_5g, [ad, None, NETWORK_MODE_NR_ONLY]) for ad in ads]
@@ -230,7 +251,7 @@
log.error("failed to set preferred network mode on 5g SA")
return False
- tasks = [(is_current_network_5g_sa, [ad]) for ad in ads]
+ tasks = [(is_current_network_5g_sa, [ad, None, mmwave]) for ad in ads]
if not multithread_func(log, tasks):
log.error("phone not on 5g SA")
return False
@@ -239,30 +260,91 @@
# Mode Pref
set_preferred_mode_for_5g(ads, None, NETWORK_MODE_NR_ONLY)
- if not is_current_network_5g_sa(ads):
+ if not is_current_network_5g_sa(ads, None, mmwave):
ads.log.error("Phone not attached on SA 5g")
return False
return True
-def check_current_network_5g(ad, timeout=30, sa_5g=False, nsa_mmwave=False):
+def check_current_network_5g(
+ ad, sub_id = None, nr_type = None, mmwave = None, timeout = 30):
"""Verifies data network type is on 5G
Args:
ad: android device object.
- timeout: max time to wait for event
- sa_5g: Check for verify data network type is on 5G SA or not
- nsa_mmwave: If true, check the band of NSA network is mmWave. Default is to check sub-6.
+ sub_id: The target SIM for querying.
+ nr_type: 'sa' for 5G standalone, 'nsa' for 5G non-standalone, 'mmwave' for 5G millimeter
+ wave.
+ mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+ None to detect both.
+ timeout: max time to wait for event.
Returns:
True: if data is on 5g
False: if data is not on 5g
"""
- if sa_5g:
- if not is_current_network_5g_sa(ad):
+ sub_id = sub_id if sub_id else ad.droid.subscriptionGetDefaultDataSubId()
+
+ if nr_type == 'sa':
+ if not is_current_network_5g_sa(ad, sub_id, mmwave=mmwave):
return False
else:
- if not is_current_network_5g_nsa(ad, nsa_mmwave=nsa_mmwave, timeout=timeout):
+ if not is_current_network_5g_nsa(ad, sub_id, mmwave=mmwave,
+ timeout=timeout):
return False
return True
+
+def test_activation_by_condition(ad, sub_id=None, from_3g=False, nr_type=None,
+ precond_func=None, mmwave=None):
+ """Test 5G activation based on various pre-conditions.
+
+ Args:
+ ad: android device object.
+ sub_id: The target SIM for querying.
+ from_3g: If true, test 5G activation from 3G attaching. Otherwise, starting from 5G attaching.
+ nr_type: check the band of NR network. Default is to check sub-6.
+ precond_func: A function to execute pre conditions before testing 5G activation.
+ mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+ None to detect both.
+
+ Returns:
+ If success, return true. Otherwise, return false.
+ """
+ sub_id = sub_id if sub_id else ad.droid.subscriptionGetDefaultDataSubId()
+
+ wifi_toggle_state(ad.log, ad, False)
+ toggle_airplane_mode(ad.log, ad, False)
+ if not from_3g:
+ set_preferred_mode_for_5g(ad)
+ for iteration in range(3):
+ ad.log.info("Attempt %d", iteration + 1)
+ sub_id=ad.droid.subscriptionGetDefaultSubId()
+ if from_3g:
+ # Set mode pref to 3G
+ set_preferred_network_mode_pref(ad.log,
+ ad,
+ sub_id,
+ NETWORK_MODE_WCDMA_ONLY)
+ time.sleep(15)
+ # Set mode pref to 5G
+ set_preferred_mode_for_5g(ad)
+
+ elif precond_func:
+ if not precond_func():
+ return False
+ # LTE attach
+ if not wait_for_network_generation(
+ ad.log, ad, GEN_4G, voice_or_data=NETWORK_SERVICE_DATA):
+ ad.log.error("Fail to ensure initial data in 4G")
+ # 5G attach
+ ad.log.info("Waiting for 5g NSA attach for 60 secs")
+ if is_current_network_5g_nsa(ad, sub_id, mmwave=mmwave, timeout=60):
+ ad.log.info("Success! attached on 5g NSA")
+ return True
+ else:
+ ad.log.error("Failure - expected NR_NSA, current %s",
+ get_current_override_network_type(ad))
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+ ad.log.info("nsa5g attach test FAIL for all 3 iterations")
+ return False
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_5g_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_5g_utils.py
index fd9d4b3..f35272e 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_5g_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_5g_utils.py
@@ -19,79 +19,121 @@
from acts_contrib.test_utils.tel.tel_defines import DisplayInfoContainer
from acts_contrib.test_utils.tel.tel_defines import EventDisplayInfoChanged
-def is_current_network_5g_nsa(ad, nsa_mmwave=False, timeout=30):
+def is_current_network_5g_nsa(ad, sub_id = None, mmwave = None, timeout=30):
"""Verifies 5G NSA override network type
Args:
ad: android device object.
- nsa_mmwave: If true, check the band of NSA network is mmWave. Default is to check sub-6.
+ sub_id: The target SIM for querying.
+ mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+ None to detect both.
timeout: max time to wait for event.
+
Returns:
True: if data is on nsa5g NSA
False: if data is not on nsa5g NSA
"""
- ad.ed.clear_events(EventDisplayInfoChanged)
- ad.droid.telephonyStartTrackingDisplayInfoChange()
- nsa_band = OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_NSA
- if nsa_mmwave:
- nsa_band = OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_MMWAVE
- try:
- event = ad.ed.wait_for_event(
- EventDisplayInfoChanged,
- ad.ed.is_event_match,
- timeout=timeout,
- field=DisplayInfoContainer.OVERRIDE,
- value=nsa_band)
- ad.log.info("Got expected event %s", event)
- return True
- except Empty:
- ad.log.info("No event for display info change")
- return False
- finally:
- ad.droid.telephonyStopTrackingDisplayInfoChange()
- return None
+ sub_id = sub_id if sub_id else ad.droid.subscriptionGetDefaultDataSubId()
+
+ def _nsa_display_monitor(ad, sub_id, mmwave, timeout):
+ ad.ed.clear_events(EventDisplayInfoChanged)
+ ad.droid.telephonyStartTrackingDisplayInfoChangeForSubscription(sub_id)
+ if mmwave:
+ nsa_band = OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_MMWAVE
+ else:
+ nsa_band = OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_NSA
+ try:
+ event = ad.ed.wait_for_event(
+ EventDisplayInfoChanged,
+ ad.ed.is_event_match,
+ timeout=timeout,
+ field=DisplayInfoContainer.OVERRIDE,
+ value=nsa_band)
+ ad.log.info("Got expected event %s", event)
+ return True
+ except Empty:
+ ad.log.info("No event for display info change with <%s>", nsa_band)
+ ad.screenshot("5g_nsa_icon_checking")
+ return False
+ finally:
+ ad.droid.telephonyStopTrackingServiceStateChangeForSubscription(
+ sub_id)
+
+ if mmwave is None:
+ return _nsa_display_monitor(
+ ad, sub_id, mmwave=False, timeout=timeout) or _nsa_display_monitor(
+ ad, sub_id, mmwave=True, timeout=timeout)
+ else:
+ return _nsa_display_monitor(ad, sub_id, mmwave, timeout)
-def is_current_network_5g_nsa_for_subscription(ad, nsa_mmwave=False, timeout=30, sub_id=None):
- """Verifies 5G NSA override network type for subscription id.
- Args:
- ad: android device object.
- nsa_mmwave: If true, check the band of NSA network is mmWave. Default is to check sub-6.
- timeout: max time to wait for event.
- sub_id: subscription id.
- Returns:
- True: if data is on nsa5g NSA
- False: if data is not on nsa5g NSA
- """
- if not sub_id:
- return is_current_network_5g_nsa(ad, nsa_mmwave=nsa_mmwave)
-
- voice_sub_id_changed = False
- current_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
- if current_sub_id != sub_id:
- ad.droid.subscriptionSetDefaultVoiceSubId(sub_id)
- voice_sub_id_changed = True
-
- result = is_current_network_5g_nsa(ad, nsa_mmwave=nsa_mmwave)
-
- if voice_sub_id_changed:
- ad.droid.subscriptionSetDefaultVoiceSubId(current_sub_id)
-
- return result
-
-def is_current_network_5g_sa(ad):
+def is_current_network_5g_sa(ad, sub_id = None, mmwave = None):
"""Verifies 5G SA override network type
Args:
ad: android device object.
+ sub_id: The target SIM for querying.
+ mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+ None to detect both.
Returns:
True: if data is on 5g SA
False: if data is not on 5g SA
"""
- network_connected = ad.droid.telephonyGetCurrentDataNetworkType()
- if network_connected == 'NR':
- ad.log.debug("Network is currently connected to %s", network_connected)
- return True
+ sub_id = sub_id if sub_id else ad.droid.subscriptionGetDefaultDataSubId()
+ current_rat = ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
+ sub_id)
+ # TODO(richardwychang): check SA MMWAVE when function ready.
+ sa_type = ['NR',]
+ if mmwave is None:
+ if current_rat in sa_type:
+ ad.log.debug("Network is currently connected to %s", current_rat)
+ return True
+ else:
+ ad.log.error(
+ "Network is currently connected to %s, Expected on %s",
+ current_rat, sa_type)
+ ad.screenshot("5g_sa_icon_checking")
+ return False
+ elif mmwave:
+ ad.log.error("SA MMWAVE currently not support.")
+ return False
else:
- ad.log.error("Network is currently connected to %s, Expected on NR", network_connected)
- return False
\ No newline at end of file
+ if current_rat == 'NR':
+ ad.log.debug("Network is currently connected to %s", current_rat)
+ return True
+ else:
+ ad.log.error(
+ "Network is currently connected to %s, Expected on NR",
+ current_rat)
+ ad.screenshot("5g_sa_icon_checking")
+ return False
+
+
+def is_current_network_5g(ad, sub_id = None, nr_type = None, mmwave = None,
+ timeout = 30):
+ """Verifies 5G override network type
+
+ Args:
+ ad: android device object
+ sub_id: The target SIM for querying.
+ nr_type: 'sa' for 5G standalone, 'nsa' for 5G non-standalone.
+ mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+ None to detect both.
+ timeout: max time to wait for event.
+
+ Returns:
+ True: if data is on 5G regardless of SA or NSA
+ False: if data is not on 5G refardless of SA or NSA
+ """
+ sub_id = sub_id if sub_id else ad.droid.subscriptionGetDefaultDataSubId()
+
+ if nr_type == 'nsa':
+ return is_current_network_5g_nsa(
+ ad, sub_id=sub_id, mmwave=mmwave, timeout=timeout)
+ elif nr_type == 'sa':
+ return is_current_network_5g_sa(ad, sub_id=sub_id, mmwave=mmwave)
+ else:
+ return is_current_network_5g_nsa(
+ ad, sub_id=sub_id, mmwave=mmwave,
+ timeout=timeout) or is_current_network_5g_sa(
+ ad, sub_id=sub_id, mmwave=mmwave)
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_atten_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_atten_utils.py
index 8e47a89..fdbbcc6 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_atten_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_atten_utils.py
@@ -31,7 +31,7 @@
Returns:
Current attenuation value.
"""
- return atten_obj.get_atten()
+ return atten_obj.get_atten(retry=True)
def set_atten(log, atten_obj, target_atten, step_size=0, time_per_step=0):
@@ -70,9 +70,9 @@
number_of_steps -= 1
current_atten += math.copysign(step_size,
(target_atten - current_atten))
- atten_obj.set_atten(current_atten)
+ atten_obj.set_atten(current_atten, retry=True)
time.sleep(time_per_step)
- atten_obj.set_atten(target_atten)
+ atten_obj.set_atten(target_atten, retry=True)
except Exception as e:
log.error("set_atten error happened: {}".format(e))
return False
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_bootloader_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_bootloader_utils.py
new file mode 100644
index 0000000..b503b19
--- /dev/null
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_bootloader_utils.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - Google
+#
+# 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 time
+
+from acts.controllers.android_device import SL4A_APK_NAME
+from acts.controllers.android_device import list_adb_devices
+from acts.controllers.android_device import list_fastboot_devices
+from acts_contrib.test_utils.tel.tel_ims_utils import activate_wfc_on_device
+from acts_contrib.test_utils.tel.tel_logging_utils import set_qxdm_logger_command
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_logger
+from acts_contrib.test_utils.tel.tel_test_utils import abort_all_tests
+from acts_contrib.test_utils.tel.tel_test_utils import bring_up_sl4a
+from acts_contrib.test_utils.tel.tel_test_utils import refresh_sl4a_session
+from acts_contrib.test_utils.tel.tel_test_utils import set_phone_silent_mode
+from acts_contrib.test_utils.tel.tel_test_utils import synchronize_device_time
+from acts_contrib.test_utils.tel.tel_test_utils import unlock_sim
+
+
+def fastboot_wipe(ad, skip_setup_wizard=True):
+ """Wipe the device in fastboot mode.
+
+ Pull sl4a apk from device. Terminate all sl4a sessions,
+ Reboot the device to bootloader, wipe the device by fastboot.
+ Reboot the device. wait for device to complete booting
+ Re-intall and start an sl4a session.
+ """
+ status = True
+ # Pull sl4a apk from device
+ out = ad.adb.shell("pm path %s" % SL4A_APK_NAME)
+ result = re.search(r"package:(.*)", out)
+ if not result:
+ ad.log.error("Couldn't find sl4a apk")
+ else:
+ sl4a_apk = result.group(1)
+ ad.log.info("Get sl4a apk from %s", sl4a_apk)
+ ad.pull_files([sl4a_apk], "/tmp/")
+ ad.stop_services()
+ attempts = 3
+ for i in range(1, attempts + 1):
+ try:
+ if ad.serial in list_adb_devices():
+ ad.log.info("Reboot to bootloader")
+ ad.adb.reboot("bootloader", ignore_status=True)
+ time.sleep(10)
+ if ad.serial in list_fastboot_devices():
+ ad.log.info("Wipe in fastboot")
+ ad.fastboot._w(timeout=300, ignore_status=True)
+ time.sleep(30)
+ ad.log.info("Reboot in fastboot")
+ ad.fastboot.reboot()
+ ad.wait_for_boot_completion()
+ ad.root_adb()
+ if ad.skip_sl4a:
+ break
+ if ad.is_sl4a_installed():
+ break
+ ad.log.info("Re-install sl4a")
+ ad.adb.shell("settings put global verifier_verify_adb_installs 0")
+ ad.adb.install("-r /tmp/base.apk")
+ time.sleep(10)
+ break
+ except Exception as e:
+ ad.log.warning(e)
+ if i == attempts:
+ abort_all_tests(ad.log, str(e))
+ time.sleep(5)
+ try:
+ ad.start_adb_logcat()
+ except:
+ ad.log.error("Failed to start adb logcat!")
+ if skip_setup_wizard:
+ ad.exit_setup_wizard()
+ if getattr(ad, "qxdm_log", True):
+ set_qxdm_logger_command(ad, mask=getattr(ad, "qxdm_log_mask", None))
+ start_qxdm_logger(ad)
+ if ad.skip_sl4a: return status
+ bring_up_sl4a(ad)
+ synchronize_device_time(ad)
+ set_phone_silent_mode(ad.log, ad)
+ # Activate WFC on Verizon, AT&T and Canada operators as per # b/33187374 &
+ # b/122327716
+ activate_wfc_on_device(ad.log, ad)
+ return status
+
+
+def flash_radio(ad, file_path, skip_setup_wizard=True, sideload_img=True):
+ """Flash radio image or modem binary.
+
+ Args:
+ file_path: The file path of test radio(radio.img)/binary(modem.bin).
+ skip_setup_wizard: Skip Setup Wizard if True.
+ sideload_img: True to flash radio, False to flash modem.
+ """
+ ad.stop_services()
+ ad.log.info("Reboot to bootloader")
+ ad.adb.reboot_bootloader(ignore_status=True)
+ ad.log.info("Sideload radio in fastboot")
+ try:
+ if sideload_img:
+ ad.fastboot.flash("radio %s" % file_path, timeout=300)
+ else:
+ ad.fastboot.flash("modem %s" % file_path, timeout=300)
+ except Exception as e:
+ ad.log.error(e)
+ ad.fastboot.reboot("bootloader")
+ time.sleep(5)
+ output = ad.fastboot.getvar("version-baseband")
+ result = re.search(r"version-baseband: (\S+)", output)
+ if not result:
+ ad.log.error("fastboot getvar version-baseband output = %s", output)
+ abort_all_tests(ad.log, "Radio version-baseband is not provided")
+ fastboot_radio_version_output = result.group(1)
+ for _ in range(2):
+ try:
+ ad.log.info("Reboot in fastboot")
+ ad.fastboot.reboot()
+ ad.wait_for_boot_completion()
+ break
+ except Exception as e:
+ ad.log.error("Exception error %s", e)
+ ad.root_adb()
+ adb_radio_version_output = ad.adb.getprop("gsm.version.baseband")
+ ad.log.info("adb getprop gsm.version.baseband = %s",
+ adb_radio_version_output)
+ if fastboot_radio_version_output not in adb_radio_version_output:
+ msg = ("fastboot radio version output %s does not match with adb"
+ " radio version output %s" % (fastboot_radio_version_output,
+ adb_radio_version_output))
+ abort_all_tests(ad.log, msg)
+ if not ad.ensure_screen_on():
+ ad.log.error("User window cannot come up")
+ ad.start_services(skip_setup_wizard=skip_setup_wizard)
+ unlock_sim(ad)
+
+
+def reset_device_password(ad, device_password=None):
+ # Enable or Disable Device Password per test bed config
+ unlock_sim(ad)
+ screen_lock = ad.is_screen_lock_enabled()
+ if device_password:
+ try:
+ refresh_sl4a_session(ad)
+ ad.droid.setDevicePassword(device_password)
+ except Exception as e:
+ ad.log.warning("setDevicePassword failed with %s", e)
+ try:
+ ad.droid.setDevicePassword(device_password, "1111")
+ except Exception as e:
+ ad.log.warning(
+ "setDevicePassword providing previous password error: %s",
+ e)
+ time.sleep(2)
+ if screen_lock:
+ # existing password changed
+ return
+ else:
+ # enable device password and log in for the first time
+ ad.log.info("Enable device password")
+ ad.adb.wait_for_device(timeout=180)
+ else:
+ if not screen_lock:
+ # no existing password, do not set password
+ return
+ else:
+ # password is enabled on the device
+ # need to disable the password and log in on the first time
+ # with unlocking with a swipe
+ ad.log.info("Disable device password")
+ ad.unlock_screen(password="1111")
+ refresh_sl4a_session(ad)
+ ad.ensure_screen_on()
+ try:
+ ad.droid.disableDevicePassword()
+ except Exception as e:
+ ad.log.warning("disableDevicePassword failed with %s", e)
+ fastboot_wipe(ad)
+ time.sleep(2)
+ ad.adb.wait_for_device(timeout=180)
+ refresh_sl4a_session(ad)
+ if not ad.is_adb_logcat_on:
+ ad.start_adb_logcat()
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_bt_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_bt_utils.py
new file mode 100644
index 0000000..8f754ed
--- /dev/null
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_bt_utils.py
@@ -0,0 +1,187 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - Google
+#
+# 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_contrib.test_utils.bt.bt_test_utils import bluetooth_enabled_check
+from acts_contrib.test_utils.bt.bt_test_utils import disable_bluetooth
+from acts_contrib.test_utils.bt.bt_test_utils import pair_pri_to_sec
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
+from acts_contrib.test_utils.tel.tel_data_utils import test_internet_connection
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation
+from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
+from acts_contrib.test_utils.tel.tel_test_utils import wait_for_state
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+
+
+def enable_bluetooth_tethering_connection(log, provider, clients):
+ for ad in [provider] + clients:
+ if not bluetooth_enabled_check(ad):
+ ad.log.info("Bluetooth is not enabled")
+ return False
+ else:
+ ad.log.info("Bluetooth is enabled")
+ time.sleep(5)
+ provider.log.info("Provider enabling bluetooth tethering")
+ try:
+ provider.droid.bluetoothPanSetBluetoothTethering(True)
+ except Exception as e:
+ provider.log.warning(
+ "Failed to enable provider Bluetooth tethering with %s", e)
+ provider.droid.bluetoothPanSetBluetoothTethering(True)
+
+ if wait_for_state(provider.droid.bluetoothPanIsTetheringOn, True):
+ provider.log.info("Provider Bluetooth tethering is enabled.")
+ else:
+ provider.log.error(
+ "Failed to enable provider Bluetooth tethering.")
+ provider.log.error("bluetoothPanIsTetheringOn = %s",
+ provider.droid.bluetoothPanIsTetheringOn())
+ return False
+ for client in clients:
+ if not (pair_pri_to_sec(provider, client)):
+ client.log.error("Client failed to pair with provider")
+ return False
+ else:
+ client.log.info("Client paired with provider")
+
+ time.sleep(5)
+ for client in clients:
+ client.droid.bluetoothConnectBonded(provider.droid.bluetoothGetLocalAddress())
+
+ time.sleep(20)
+ return True
+
+
+def verify_bluetooth_tethering_connection(log, provider, clients,
+ change_rat=None,
+ toggle_data=False,
+ toggle_tethering=False,
+ voice_call=False,
+ toggle_bluetooth=True):
+ """Setups up a bluetooth tethering connection between two android devices.
+
+ Returns:
+ True if PAN connection and verification is successful,
+ false if unsuccessful.
+ """
+
+
+ if not enable_bluetooth_tethering_connection(log, provider, clients):
+ return False
+
+ if not test_internet_connection(log, provider, clients):
+ log.error("Internet connection check failed")
+ return False
+ if voice_call:
+ log.info("====== Voice call test =====")
+ for caller, callee in [(provider, clients[0]),
+ (clients[0], provider)]:
+ if not call_setup_teardown(
+ log, caller, callee, ad_hangup=None):
+ log.error("Setup Call Failed.")
+ hangup_call(log, caller)
+ return False
+ log.info("Verify data.")
+ if not verify_internet_connection(
+ log, clients[0], retries=1):
+ clients[0].log.warning(
+ "client internet connection state is not on")
+ else:
+ clients[0].log.info(
+ "client internet connection state is on")
+ hangup_call(log, caller)
+ if not verify_internet_connection(
+ log, clients[0], retries=1):
+ clients[0].log.warning(
+ "client internet connection state is not on")
+ return False
+ else:
+ clients[0].log.info(
+ "client internet connection state is on")
+ if toggle_tethering:
+ log.info("====== Toggling provider bluetooth tethering =====")
+ provider.log.info("Disable bluetooth tethering")
+ provider.droid.bluetoothPanSetBluetoothTethering(False)
+ if not test_internet_connection(log, provider, clients, False, True):
+ log.error(
+ "Internet connection check failed after disable tethering")
+ return False
+ provider.log.info("Enable bluetooth tethering")
+ if not enable_bluetooth_tethering_connection(log,
+ provider, clients):
+ provider.log.error(
+ "Fail to re-enable bluetooth tethering")
+ return False
+ if not test_internet_connection(log, provider, clients, True, True):
+ log.error(
+ "Internet connection check failed after enable tethering")
+ return False
+ if toggle_bluetooth:
+ log.info("====== Toggling provider bluetooth =====")
+ provider.log.info("Disable provider bluetooth")
+ disable_bluetooth(provider.droid)
+ time.sleep(10)
+ if not test_internet_connection(log, provider, clients, False, True):
+ log.error(
+ "Internet connection check failed after disable bluetooth")
+ return False
+ if not enable_bluetooth_tethering_connection(log,
+ provider, clients):
+ provider.log.error(
+ "Fail to re-enable bluetooth tethering")
+ return False
+ if not test_internet_connection(log, provider, clients, True, True):
+ log.error(
+ "Internet connection check failed after enable bluetooth")
+ return False
+ if toggle_data:
+ log.info("===== Toggling provider data connection =====")
+ provider.log.info("Disable provider data connection")
+ provider.droid.telephonyToggleDataConnection(False)
+ time.sleep(10)
+ if not test_internet_connection(log, provider, clients, False, False):
+ return False
+ provider.log.info("Enable provider data connection")
+ provider.droid.telephonyToggleDataConnection(True)
+ if not wait_for_cell_data_connection(log, provider,
+ True):
+ provider.log.error(
+ "Provider failed to enable data connection.")
+ return False
+ if not test_internet_connection(log, provider, clients, True, True):
+ log.error(
+ "Internet connection check failed after enable data")
+ return False
+ if change_rat:
+ log.info("===== Change provider RAT to %s =====", change_rat)
+ if not ensure_network_generation(
+ log,
+ provider,
+ change_rat,
+ voice_or_data=NETWORK_SERVICE_DATA,
+ toggle_apm_after_setting=False):
+ provider.log.error("Provider failed to reselect to %s.",
+ change_rat)
+ return False
+ if not test_internet_connection(log, provider, clients, True, True):
+ log.error(
+ "Internet connection check failed after RAT change to %s",
+ change_rat)
+ return False
+ return True
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_data_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_data_utils.py
index ff75bc1..05808f9 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_data_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_data_utils.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2016 - Google
+# Copyright 2022 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,94 +14,102 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+
+import logging
+import os
import time
import random
-import re
from queue import Empty
+from acts.controllers.android_device import SL4A_APK_NAME
from acts.utils import adb_shell_ping
from acts.utils import rand_ascii_str
from acts.utils import disable_doze
from acts.utils import enable_doze
-from acts_contrib.test_utils.bt.bt_test_utils import bluetooth_enabled_check
-from acts_contrib.test_utils.bt.bt_test_utils import disable_bluetooth
-from acts_contrib.test_utils.bt.bt_test_utils import pair_pri_to_sec
+from acts.libs.utils.multithread import multithread_func
+from acts.libs.utils.multithread import run_multithread_func
from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_subid_from_slot_index
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_data
+from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_CONNECTED
+from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_DISCONNECTED
from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED
+from acts_contrib.test_utils.tel.tel_defines import EventConnectivityChanged
from acts_contrib.test_utils.tel.tel_defines import EventNetworkCallback
from acts_contrib.test_utils.tel.tel_defines import GEN_5G
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_FOR_STATE_CHANGE
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_TETHERING_ENTITLEMENT_CHECK
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_USER_PLANE_DATA
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WIFI_CONNECTION
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_CELL
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_WIFI
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
from acts_contrib.test_utils.tel.tel_defines import RAT_5G
-from acts_contrib.test_utils.tel.tel_defines import RAT_UNKNOWN
+from acts_contrib.test_utils.tel.tel_defines import TETHERING_MODE_WIFI
+from acts_contrib.test_utils.tel.tel_defines import TYPE_MOBILE
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_AFTER_REBOOT
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_REG_AND_CALL
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_DATA_STALL
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_NW_VALID_FAIL
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_DATA_STALL_RECOVERY
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL_FOR_IMS
-from acts_contrib.test_utils.tel.tel_defines import \
- WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING
-from acts_contrib.test_utils.tel.tel_defines import TETHERING_MODE_WIFI
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_TETHERING_ENTITLEMENT_CHECK
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_TETHERING_AFTER_REBOOT
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import check_is_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_generation
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_generation_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_idle
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import get_mobile_data_usage
+from acts_contrib.test_utils.tel.tel_defines import DataConnectionStateContainer
+from acts_contrib.test_utils.tel.tel_defines import EventDataConnectionStateChanged
+from acts_contrib.test_utils.tel.tel_5g_test_utils import check_current_network_5g
+from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from acts_contrib.test_utils.tel.tel_5g_test_utils import verify_5g_attach_for_both_devices
+from acts_contrib.test_utils.tel.tel_ims_utils import is_ims_registered
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_ims_registered
+from acts_contrib.test_utils.tel.tel_lookup_tables import connection_type_from_type_string
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_default_state
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_voice_attach_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import _check_file_existence
+from acts_contrib.test_utils.tel.tel_test_utils import _generate_file_directory_and_file_name
+from acts_contrib.test_utils.tel.tel_test_utils import _wait_for_droid_in_state
+from acts_contrib.test_utils.tel.tel_test_utils import get_internet_connection_type
from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat_for_subscription
from acts_contrib.test_utils.tel.tel_test_utils import get_service_state_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import get_wifi_usage
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
from acts_contrib.test_utils.tel.tel_test_utils import is_droid_in_network_generation_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import is_ims_registered
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
+from acts_contrib.test_utils.tel.tel_test_utils import is_event_match
from acts_contrib.test_utils.tel.tel_test_utils import rat_generation_from_rat
-from acts_contrib.test_utils.tel.tel_test_utils import set_wifi_to_default
-from acts_contrib.test_utils.tel.tel_test_utils import start_youtube_video
-from acts_contrib.test_utils.tel.tel_test_utils import start_wifi_tethering
-from acts_contrib.test_utils.tel.tel_test_utils import stop_wifi_tethering
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_cell_data_connection
from acts_contrib.test_utils.tel.tel_test_utils import wait_for_data_attach_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_service
from acts_contrib.test_utils.tel.tel_test_utils import wait_for_state
-from acts_contrib.test_utils.tel.tel_test_utils import \
- wait_for_voice_attach_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wifi_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_reset
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_toggle_state
-from acts_contrib.test_utils.tel.tel_test_utils import active_file_download_task
-from acts_contrib.test_utils.tel.tel_test_utils import run_multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_default_state
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_SSID_KEY
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call_active
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_nsa
-from acts_contrib.test_utils.tel.tel_5g_test_utils import check_current_network_5g
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
-from acts_contrib.test_utils.tel.tel_5g_test_utils import verify_5g_attach_for_both_devices
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_general
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_short_seq
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_iwlan
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_active
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
+from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_short_seq
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_SSID_KEY
+from acts_contrib.test_utils.tel.tel_wifi_utils import check_is_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import get_wifi_usage
+from acts_contrib.test_utils.tel.tel_wifi_utils import set_wifi_to_default
+from acts_contrib.test_utils.tel.tel_wifi_utils import start_wifi_tethering
+from acts_contrib.test_utils.tel.tel_wifi_utils import stop_wifi_tethering
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_reset
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
def wifi_tethering_cleanup(log, provider, client_list):
@@ -287,7 +295,12 @@
return False
-def wifi_cell_switching(log, ad, nw_gen, wifi_network_ssid=None, wifi_network_pass=None, sa_5g=False):
+def wifi_cell_switching(log,
+ ad,
+ nw_gen,
+ wifi_network_ssid=None,
+ wifi_network_pass=None,
+ nr_type=None):
"""Test data connection network switching when phone on <nw_gen>.
Ensure phone is on <nw_gen>
@@ -303,13 +316,14 @@
wifi_network_ssid: ssid for live wifi network.
wifi_network_pass: password for live wifi network.
nw_gen: network generation the phone should be camped on.
+ nr_type: check NR network.
Returns:
True if pass.
"""
try:
if nw_gen == GEN_5G:
- if not provision_device_for_5g(log, ad, sa_5g):
+ if not provision_device_for_5g(log, ad, nr_type):
return False
elif nw_gen:
if not ensure_network_generation_for_subscription(
@@ -443,7 +457,7 @@
toggle_airplane_mode(log, ad, False)
-def data_connectivity_single_bearer(log, ad, nw_gen=None, sa_5g=False):
+def data_connectivity_single_bearer(log, ad, nw_gen=None, nr_type=None):
"""Test data connection: single-bearer (no voice).
Turn off airplane mode, enable Cellular Data.
@@ -456,6 +470,7 @@
log: log object.
ad: android object.
nw_gen: network generation the phone should on.
+ nr_type: NR network type e.g. NSA, SA, MMWAVE
Returns:
True if success.
@@ -467,7 +482,7 @@
wait_time = 2 * wait_time
if nw_gen == GEN_5G:
- if not provision_device_for_5g(log, ad, sa_5g):
+ if not provision_device_for_5g(log, ad, nr_type):
return False
elif nw_gen:
if not ensure_network_generation_for_subscription(
@@ -512,7 +527,7 @@
return False
if nw_gen == GEN_5G:
- if not check_current_network_5g(ad, sa_5g):
+ if not check_current_network_5g(ad, nr_type=nr_type, timeout=60):
return False
else:
if not is_droid_in_network_generation_for_subscription(
@@ -835,7 +850,7 @@
nw_gen=None,
simultaneous_voice_data=True,
call_direction=DIRECTION_MOBILE_ORIGINATED,
- sa_5g=False):
+ nr_type=None):
"""Test data connection before call and in call.
Turn off airplane mode, disable WiFi, enable Cellular Data.
@@ -861,7 +876,7 @@
ensure_phones_idle(log, ad_list)
if nw_gen == GEN_5G:
- if not provision_device_for_5g(log, android_devices, sa_5g):
+ if not provision_device_for_5g(log, android_devices, nr_type=nr_type):
return False
elif nw_gen:
if not ensure_network_generation_for_subscription(
@@ -995,13 +1010,18 @@
return True
-def test_setup_tethering(log, provider, clients, network_generation=None, sa_5g=False):
+def test_setup_tethering(log,
+ provider,
+ clients,
+ network_generation=None,
+ nr_type=None):
"""Pre setup steps for WiFi tethering test.
Ensure all ads are idle.
Ensure tethering provider:
turn off APM, turn off WiFI, turn on Data.
have Internet connection, no active ongoing WiFi tethering.
+ nr_type: NR network type.
Returns:
True if success.
@@ -1012,7 +1032,7 @@
ensure_phones_idle(log, clients)
wifi_toggle_state(log, provider, False)
if network_generation == RAT_5G:
- if not provision_device_for_5g(log, provider, sa_5g):
+ if not provision_device_for_5g(log, provider, nr_type=nr_type):
return False
elif network_generation:
if not ensure_network_generation(
@@ -1036,7 +1056,7 @@
provider.log.info("Disable provider wifi tethering")
stop_wifi_tethering(log, provider)
provider.log.info("Provider disable bluetooth")
- disable_bluetooth(provider.droid)
+ provider.droid.bluetoothToggleState(False)
time.sleep(10)
for ad in clients:
@@ -1046,7 +1066,7 @@
ad.log.info("Client disable data")
ad.droid.telephonyToggleDataConnection(False)
ad.log.info("Client disable bluetooth")
- disable_bluetooth(ad.droid)
+ ad.droid.bluetoothToggleState(False)
ad.log.info("Client disable wifi")
wifi_toggle_state(log, ad, False)
@@ -1065,169 +1085,11 @@
return True
-def enable_bluetooth_tethering_connection(log, provider, clients):
- for ad in [provider] + clients:
- if not bluetooth_enabled_check(ad):
- ad.log.info("Bluetooth is not enabled")
- return False
- else:
- ad.log.info("Bluetooth is enabled")
- time.sleep(5)
- provider.log.info("Provider enabling bluetooth tethering")
- try:
- provider.droid.bluetoothPanSetBluetoothTethering(True)
- except Exception as e:
- provider.log.warning(
- "Failed to enable provider Bluetooth tethering with %s", e)
- provider.droid.bluetoothPanSetBluetoothTethering(True)
-
- if wait_for_state(provider.droid.bluetoothPanIsTetheringOn, True):
- provider.log.info("Provider Bluetooth tethering is enabled.")
- else:
- provider.log.error(
- "Failed to enable provider Bluetooth tethering.")
- provider.log.error("bluetoothPanIsTetheringOn = %s",
- provider.droid.bluetoothPanIsTetheringOn())
- return False
- for client in clients:
- if not (pair_pri_to_sec(provider, client)):
- client.log.error("Client failed to pair with provider")
- return False
- else:
- client.log.info("Client paired with provider")
-
- time.sleep(5)
- for client in clients:
- client.droid.bluetoothConnectBonded(provider.droid.bluetoothGetLocalAddress())
-
- time.sleep(20)
- return True
-
-
-def verify_bluetooth_tethering_connection(log, provider, clients,
- change_rat=None,
- toggle_data=False,
- toggle_tethering=False,
- voice_call=False,
- toggle_bluetooth=True):
- """Setups up a bluetooth tethering connection between two android devices.
-
- Returns:
- True if PAN connection and verification is successful,
- false if unsuccessful.
- """
-
-
- if not enable_bluetooth_tethering_connection(log, provider, clients):
- return False
-
- if not test_internet_connection(log, provider, clients):
- log.error("Internet connection check failed")
- return False
- if voice_call:
- log.info("====== Voice call test =====")
- for caller, callee in [(provider, clients[0]),
- (clients[0], provider)]:
- if not call_setup_teardown(
- log, caller, callee, ad_hangup=None):
- log.error("Setup Call Failed.")
- hangup_call(log, caller)
- return False
- log.info("Verify data.")
- if not verify_internet_connection(
- log, clients[0], retries=1):
- clients[0].log.warning(
- "client internet connection state is not on")
- else:
- clients[0].log.info(
- "client internet connection state is on")
- hangup_call(log, caller)
- if not verify_internet_connection(
- log, clients[0], retries=1):
- clients[0].log.warning(
- "client internet connection state is not on")
- return False
- else:
- clients[0].log.info(
- "client internet connection state is on")
- if toggle_tethering:
- log.info("====== Toggling provider bluetooth tethering =====")
- provider.log.info("Disable bluetooth tethering")
- provider.droid.bluetoothPanSetBluetoothTethering(False)
- if not test_internet_connection(log, provider, clients, False, True):
- log.error(
- "Internet connection check failed after disable tethering")
- return False
- provider.log.info("Enable bluetooth tethering")
- if not enable_bluetooth_tethering_connection(log,
- provider, clients):
- provider.log.error(
- "Fail to re-enable bluetooth tethering")
- return False
- if not test_internet_connection(log, provider, clients, True, True):
- log.error(
- "Internet connection check failed after enable tethering")
- return False
- if toggle_bluetooth:
- log.info("====== Toggling provider bluetooth =====")
- provider.log.info("Disable provider bluetooth")
- disable_bluetooth(provider.droid)
- time.sleep(10)
- if not test_internet_connection(log, provider, clients, False, True):
- log.error(
- "Internet connection check failed after disable bluetooth")
- return False
- if not enable_bluetooth_tethering_connection(log,
- provider, clients):
- provider.log.error(
- "Fail to re-enable bluetooth tethering")
- return False
- if not test_internet_connection(log, provider, clients, True, True):
- log.error(
- "Internet connection check failed after enable bluetooth")
- return False
- if toggle_data:
- log.info("===== Toggling provider data connection =====")
- provider.log.info("Disable provider data connection")
- provider.droid.telephonyToggleDataConnection(False)
- time.sleep(10)
- if not test_internet_connection(log, provider, clients, False, False):
- return False
- provider.log.info("Enable provider data connection")
- provider.droid.telephonyToggleDataConnection(True)
- if not wait_for_cell_data_connection(log, provider,
- True):
- provider.log.error(
- "Provider failed to enable data connection.")
- return False
- if not test_internet_connection(log, provider, clients, True, True):
- log.error(
- "Internet connection check failed after enable data")
- return False
- if change_rat:
- log.info("===== Change provider RAT to %s =====", change_rat)
- if not ensure_network_generation(
- log,
- provider,
- change_rat,
- voice_or_data=NETWORK_SERVICE_DATA,
- toggle_apm_after_setting=False):
- provider.log.error("Provider failed to reselect to %s.",
- change_rat)
- return False
- if not test_internet_connection(log, provider, clients, True, True):
- log.error(
- "Internet connection check failed after RAT change to %s",
- change_rat)
- return False
- return True
-
-
def test_tethering_wifi_and_voice_call(log, provider, clients,
provider_data_rat,
provider_setup_func,
provider_in_call_check_func,
- sa_5g=False):
+ nr_type=None):
if not test_setup_tethering(log, provider, clients, provider_data_rat):
log.error("Verify 4G Internet access failed.")
@@ -1240,7 +1102,7 @@
return False
if provider_setup_func == RAT_5G:
- if not provision_device_for_5g(log, provider, sa_5g):
+ if not provision_device_for_5g(log, provider, nr_type=nr_type):
return False
try:
log.info("1. Setup WiFi Tethering.")
@@ -1314,36 +1176,38 @@
True, False, True, False, False, True, False, False, False, False,
True, False, False, False, False, False, False, False, False
]
+ try:
+ for toggle in wifi_toggles:
- for toggle in wifi_toggles:
+ wifi_reset(log, ad, toggle)
- wifi_reset(log, ad, toggle)
+ if not wait_for_cell_data_connection(
+ log, ad, True, MAX_WAIT_TIME_WIFI_CONNECTION):
+ log.error("Failed data connection, aborting!")
+ return False
- if not wait_for_cell_data_connection(
- log, ad, True, MAX_WAIT_TIME_WIFI_CONNECTION):
- log.error("Failed wifi connection, aborting!")
- return False
+ if not verify_internet_connection(log, ad):
+ log.error("Failed to get user-plane traffic, aborting!")
+ return False
- if not verify_internet_connection(log, ad):
- log.error("Failed to get user-plane traffic, aborting!")
- return False
+ if toggle:
+ wifi_toggle_state(log, ad, True)
- if toggle:
- wifi_toggle_state(log, ad, True)
+ ensure_wifi_connected(log, ad, wifi_network_ssid,
+ wifi_network_pass)
- ensure_wifi_connected(log, ad, wifi_network_ssid,
- wifi_network_pass)
+ if not wait_for_wifi_data_connection(
+ log, ad, True, MAX_WAIT_TIME_WIFI_CONNECTION):
+ log.error("Failed wifi connection, aborting!")
+ return False
- if not wait_for_wifi_data_connection(
- log, ad, True, MAX_WAIT_TIME_WIFI_CONNECTION):
- log.error("Failed wifi connection, aborting!")
- return False
-
- if not verify_http_connection(
- log, ad, 'http://www.google.com', 100, .1):
- log.error("Failed to get user-plane traffic, aborting!")
- return False
- return True
+ if not verify_http_connection(
+ log, ad, 'http://www.google.com', 100, .1):
+ log.error("Failed to get user-plane traffic, aborting!")
+ return False
+ return True
+ finally:
+ wifi_toggle_state(log, ad, False)
def test_call_setup_in_active_data_transfer(
@@ -1352,7 +1216,7 @@
nw_gen=None,
call_direction=DIRECTION_MOBILE_ORIGINATED,
allow_data_transfer_interruption=False,
- sa_5g=False):
+ nr_type=None):
"""Test call can be established during active data connection.
Turn off airplane mode, disable WiFi, enable Cellular Data.
@@ -1385,7 +1249,7 @@
wait_time_in_call)
if nw_gen == GEN_5G:
- if not provision_device_for_5g(log, ads[0], sa_5g):
+ if not provision_device_for_5g(log, ads[0], nr_type=nr_type):
return False
elif nw_gen:
if not ensure_network_generation(log, ads[0], nw_gen,
@@ -1440,7 +1304,8 @@
return False
# Disable airplane mode if test under apm on.
toggle_airplane_mode(log, ads[0], False)
- if nw_gen == GEN_5G and not check_current_network_5g(ads[0], sa_5g):
+ if nw_gen == GEN_5G and not check_current_network_5g(ads[0],
+ nr_type=nr_type):
ads[0].log.error("Phone not attached on 5G after call.")
return False
return True
@@ -1452,7 +1317,7 @@
nw_gen=None,
call_direction=DIRECTION_MOBILE_ORIGINATED,
allow_data_transfer_interruption=False,
- sa_5g=False):
+ nr_type=None):
"""Test call can be established during active data connection.
Turn off airplane mode, disable WiFi, enable Cellular Data.
@@ -1471,7 +1336,7 @@
False if failed.
"""
if nw_gen == GEN_5G:
- if not provision_device_for_5g(log, ads[0], sa_5g):
+ if not provision_device_for_5g(log, ads[0], nr_type=nr_type):
return False
elif nw_gen:
if not ensure_network_generation(log, ads[0], nw_gen,
@@ -1518,7 +1383,8 @@
ad_download.force_stop_apk("com.google.android.youtube")
# Disable airplane mode if test under apm on.
toggle_airplane_mode(log, ads[0], False)
- if nw_gen == GEN_5G and not check_current_network_5g(ads[0], sa_5g):
+ if nw_gen == GEN_5G and not check_current_network_5g(ads[0],
+ nr_type=nr_type):
ads[0].log.error("Phone not attached on 5G after call.")
result = False
return result
@@ -1531,7 +1397,7 @@
wifi_ssid,
wifi_pwd,
nw_gen=None,
- sa_5g=False):
+ nr_type=None):
""" Test epdg<->epdg call functionality.
Make Sure PhoneA is set to make epdg call.
@@ -1565,7 +1431,7 @@
if not multithread_func(log, tasks):
log.error("Failed to turn off airplane mode")
return False
- if not provision_device_for_5g(log, ad, sa_5g):
+ if not provision_device_for_5g(log, ads, nr_type):
return False
tasks = [(phone_setup_iwlan, (log, ads[0], apm_mode, wfc_mode,
@@ -1588,7 +1454,8 @@
time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- if nw_gen == GEN_5G and not verify_5g_attach_for_both_devices(log, ads, sa_5g):
+ if nw_gen == GEN_5G and not verify_5g_attach_for_both_devices(
+ log, ads, nr_type=nr_type):
log.error("Phone not attached on 5G after epdg call.")
return False
@@ -1688,7 +1555,8 @@
do_cleanup=True,
ssid=None,
password=None,
- pre_teardown_func=None):
+ pre_teardown_func=None,
+ nr_type=None):
"""WiFi Tethering test
Args:
log: log object.
@@ -1711,9 +1579,10 @@
This is optional. Default value is None.
If it's None, a random string will be generated.
pre_teardown_func: execute custom actions between tethering setup adn teardown.
+ nr_type: NR network type e.g. NSA, SA, MMWAVE.
"""
- if not test_setup_tethering(log, provider, clients, nw_gen):
+ if not test_setup_tethering(log, provider, clients, nw_gen, nr_type=nr_type):
log.error("Verify %s Internet access failed.", nw_gen)
return False
@@ -2013,13 +1882,16 @@
def verify_toggle_data_during_wifi_tethering(log,
provider,
clients,
- new_gen=None):
+ new_gen=None,
+ nr_type=None):
"""Verify toggle Data network during WiFi Tethering.
Args:
log: log object.
provider: android device object for provider.
clients: android device objects for clients.
new_gen: network generation.
+ nr_type: NR network type e.g. NSA, SA, MMWAVE.
+
Returns:
True if pass, otherwise False.
@@ -2035,7 +1907,8 @@
check_interval=10,
check_iteration=2,
do_cleanup=False,
- ssid=ssid):
+ ssid=ssid,
+ nr_type=nr_type):
log.error("WiFi Tethering failed.")
return False
if not provider.droid.wifiIsApEnabled():
@@ -2082,3 +1955,914 @@
clients):
return False
return True
+
+def deactivate_and_verify_cellular_data(log, ad):
+ """Toggle off cellular data and ensure there is no internet connection.
+
+ Args:
+ ad: Android object
+
+ Returns:
+ True if cellular data is deactivated successfully. Otherwise False.
+ """
+ ad.log.info('Deactivating cellular data......')
+ ad.droid.telephonyToggleDataConnection(False)
+
+ if not wait_for_cell_data_connection(log, ad, False):
+ ad.log.error("Failed to deactivate cell data connection.")
+ return False
+
+ if not verify_internet_connection(log, ad, expected_state=False):
+ ad.log.error("Internet connection is still available.")
+ return False
+
+ return True
+
+def activate_and_verify_cellular_data(log, ad):
+ """Toggle on cellular data and ensure there is internet connection.
+
+ Args:
+ ad: Android object
+
+ Returns:
+ True if cellular data is activated successfully. Otherwise False.
+ """
+ ad.log.info('Activating cellular data......')
+ ad.droid.telephonyToggleDataConnection(True)
+
+ if not wait_for_cell_data_connection(log, ad, True):
+ ad.log.error("Failed to activate data connection.")
+ return False
+
+ if not verify_internet_connection(log, ad, retries=3):
+ ad.log.error("Internet connection is NOT available.")
+ return False
+
+ return True
+
+
+def wait_for_network_service(
+ log,
+ ad,
+ wifi_connected=False,
+ wifi_ssid=None,
+ ims_reg=True,
+ recover=False,
+ retry=3):
+ """ Wait for multiple network services in sequence, including:
+ - service state
+ - network connection
+ - wifi connection
+ - cellular data
+ - internet connection
+ - IMS registration
+
+ The mechanism (cycling airplane mode) to recover network services is
+ also provided if any service is not available.
+
+ Args:
+ log: log object
+ ad: android device
+ wifi_connected: True if wifi should be connected. Otherwise False.
+ ims_reg: True if IMS should be registered. Otherwise False.
+ recover: True if the mechanism (cycling airplane mode) to recover
+ network services should be enabled (by default False).
+ retry: times of retry.
+ """
+ times = 1
+ while times <= retry:
+ while True:
+ 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 is not 'IN_SERVICE'.")
+ break
+
+ if not wait_for_state(
+ ad.droid.connectivityNetworkIsConnected,
+ True,
+ MAX_WAIT_TIME_FOR_STATE_CHANGE,
+ WAIT_TIME_BETWEEN_STATE_CHECK):
+ ad.log.error("Network is NOT connected!")
+ break
+
+ if wifi_connected and wifi_ssid:
+ if not wait_for_state(
+ check_is_wifi_connected,
+ True,
+ MAX_WAIT_TIME_FOR_STATE_CHANGE,
+ WAIT_TIME_BETWEEN_STATE_CHECK,
+ log,
+ ad,
+ wifi_ssid):
+ ad.log.error("Failed to connect Wi-Fi SSID '%s'.", wifi_ssid)
+ break
+ else:
+ if not wait_for_cell_data_connection(log, ad, True):
+ ad.log.error("Failed to enable data connection.")
+ break
+
+ if not wait_for_state(
+ verify_internet_connection,
+ True,
+ MAX_WAIT_TIME_FOR_STATE_CHANGE,
+ WAIT_TIME_BETWEEN_STATE_CHECK,
+ log,
+ ad):
+ ad.log.error("Data not available on cell.")
+ break
+
+ if ims_reg:
+ if not wait_for_ims_registered(log, ad):
+ ad.log.error("IMS is not registered.")
+ break
+ ad.log.info("IMS is registered.")
+ return True
+
+ if recover:
+ ad.log.warning("Trying to recover by cycling airplane mode...")
+ if not toggle_airplane_mode(log, ad, True):
+ ad.log.error("Failed to enable airplane mode")
+ break
+
+ time.sleep(5)
+
+ if not toggle_airplane_mode(log, ad, False):
+ ad.log.error("Failed to disable airplane mode")
+ break
+
+ times = times + 1
+
+ else:
+ return False
+ return False
+
+
+def wait_for_cell_data_connection(
+ log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
+ """Wait for data connection status to be expected value for default
+ data subscription.
+
+ Wait for the data connection status to be DATA_STATE_CONNECTED
+ or DATA_STATE_DISCONNECTED.
+
+ Args:
+ log: Log object.
+ ad: Android Device Object.
+ state: Expected status: True or False.
+ If True, it will wait for status to be DATA_STATE_CONNECTED.
+ If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
+ timeout_value: wait for cell data timeout value.
+ This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ sub_id = get_default_data_sub_id(ad)
+ return wait_for_cell_data_connection_for_subscription(
+ log, ad, sub_id, state, timeout_value)
+
+
+def _is_data_connection_state_match(log, ad, expected_data_connection_state):
+ return (expected_data_connection_state ==
+ ad.droid.telephonyGetDataConnectionState())
+
+
+def _is_network_connected_state_match(log, ad,
+ expected_network_connected_state):
+ return (expected_network_connected_state ==
+ ad.droid.connectivityNetworkIsConnected())
+
+
+def wait_for_cell_data_connection_for_subscription(
+ log,
+ ad,
+ sub_id,
+ state,
+ timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
+ """Wait for data connection status to be expected value for specified
+ subscrption id.
+
+ Wait for the data connection status to be DATA_STATE_CONNECTED
+ or DATA_STATE_DISCONNECTED.
+
+ Args:
+ log: Log object.
+ ad: Android Device Object.
+ sub_id: subscription Id
+ state: Expected status: True or False.
+ If True, it will wait for status to be DATA_STATE_CONNECTED.
+ If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
+ timeout_value: wait for cell data timeout value.
+ This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ state_str = {
+ True: DATA_STATE_CONNECTED,
+ False: DATA_STATE_DISCONNECTED
+ }[state]
+
+ data_state = ad.droid.telephonyGetDataConnectionState()
+ if not state and ad.droid.telephonyGetDataConnectionState() == state_str:
+ return True
+
+ ad.ed.clear_events(EventDataConnectionStateChanged)
+ ad.droid.telephonyStartTrackingDataConnectionStateChangeForSubscription(
+ sub_id)
+ ad.droid.connectivityStartTrackingConnectivityStateChange()
+ try:
+ ad.log.info("User data enabled for sub_id %s: %s", sub_id,
+ ad.droid.telephonyIsDataEnabledForSubscription(sub_id))
+ data_state = ad.droid.telephonyGetDataConnectionState()
+ ad.log.info("Data connection state is %s", data_state)
+ ad.log.info("Network is connected: %s",
+ ad.droid.connectivityNetworkIsConnected())
+ if data_state == state_str:
+ return _wait_for_nw_data_connection(
+ log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
+
+ try:
+ ad.ed.wait_for_event(
+ EventDataConnectionStateChanged,
+ is_event_match,
+ timeout=timeout_value,
+ field=DataConnectionStateContainer.DATA_CONNECTION_STATE,
+ value=state_str)
+ except Empty:
+ ad.log.info("No expected event EventDataConnectionStateChanged %s",
+ state_str)
+
+ # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
+ # data connection state.
+ # Otherwise, the network state will not be correct.
+ # The bug is tracked here: b/20921915
+
+ # Previously we use _is_data_connection_state_match,
+ # but telephonyGetDataConnectionState sometimes return wrong value.
+ # The bug is tracked here: b/22612607
+ # So we use _is_network_connected_state_match.
+
+ if _wait_for_droid_in_state(log, ad, timeout_value,
+ _is_network_connected_state_match, state):
+ return _wait_for_nw_data_connection(
+ log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
+ else:
+ return False
+
+ finally:
+ ad.droid.telephonyStopTrackingDataConnectionStateChangeForSubscription(
+ sub_id)
+
+
+def wait_for_data_connection(
+ log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
+ """Wait for data connection status to be expected value.
+
+ Wait for the data connection status to be DATA_STATE_CONNECTED
+ or DATA_STATE_DISCONNECTED.
+
+ Args:
+ log: Log object.
+ ad: Android Device Object.
+ state: Expected status: True or False.
+ If True, it will wait for status to be DATA_STATE_CONNECTED.
+ If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
+ timeout_value: wait for network data timeout value.
+ This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return _wait_for_nw_data_connection(log, ad, state, None, timeout_value)
+
+
+def wait_for_wifi_data_connection(
+ log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
+ """Wait for data connection status to be expected value and connection is by WiFi.
+
+ Args:
+ log: Log object.
+ ad: Android Device Object.
+ state: Expected status: True or False.
+ If True, it will wait for status to be DATA_STATE_CONNECTED.
+ If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
+ timeout_value: wait for network data timeout value.
+ This is optional, default value is MAX_WAIT_TIME_NW_SELECTION
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ ad.log.info("wait_for_wifi_data_connection")
+ return _wait_for_nw_data_connection(
+ log, ad, state, NETWORK_CONNECTION_TYPE_WIFI, timeout_value)
+
+
+def _connection_state_change(_event, target_state, connection_type):
+ if connection_type:
+ if 'TypeName' not in _event['data']:
+ return False
+ connection_type_string_in_event = _event['data']['TypeName']
+ cur_type = connection_type_from_type_string(
+ connection_type_string_in_event)
+ if cur_type != connection_type:
+ logging.info(
+ "_connection_state_change expect: %s, received: %s <type %s>",
+ connection_type, connection_type_string_in_event, cur_type)
+ return False
+
+ if 'isConnected' in _event['data'] and _event['data']['isConnected'] == target_state:
+ return True
+ return False
+
+
+def _wait_for_nw_data_connection(
+ log,
+ ad,
+ is_connected,
+ connection_type=None,
+ timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
+ """Wait for data connection status to be expected value.
+
+ Wait for the data connection status to be DATA_STATE_CONNECTED
+ or DATA_STATE_DISCONNECTED.
+
+ Args:
+ log: Log object.
+ ad: Android Device Object.
+ is_connected: Expected connection status: True or False.
+ If True, it will wait for status to be DATA_STATE_CONNECTED.
+ If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
+ connection_type: expected connection type.
+ This is optional, if it is None, then any connection type will return True.
+ timeout_value: wait for network data timeout value.
+ This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ ad.ed.clear_events(EventConnectivityChanged)
+ ad.droid.connectivityStartTrackingConnectivityStateChange()
+ try:
+ cur_data_connection_state = ad.droid.connectivityNetworkIsConnected()
+ if is_connected == cur_data_connection_state:
+ current_type = get_internet_connection_type(log, ad)
+ ad.log.info("current data connection type: %s", current_type)
+ if not connection_type:
+ return True
+ else:
+ if not is_connected and current_type != connection_type:
+ ad.log.info("data connection not on %s!", connection_type)
+ return True
+ elif is_connected and current_type == connection_type:
+ ad.log.info("data connection on %s as expected",
+ connection_type)
+ return True
+ else:
+ ad.log.info("current data connection state: %s target: %s",
+ cur_data_connection_state, is_connected)
+
+ try:
+ event = ad.ed.wait_for_event(
+ EventConnectivityChanged, _connection_state_change,
+ timeout_value, is_connected, connection_type)
+ ad.log.info("Got event: %s", event)
+ except Empty:
+ pass
+
+ log.info(
+ "_wait_for_nw_data_connection: check connection after wait event.")
+ # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
+ # data connection state.
+ # Otherwise, the network state will not be correct.
+ # The bug is tracked here: b/20921915
+ if _wait_for_droid_in_state(log, ad, timeout_value,
+ _is_network_connected_state_match,
+ is_connected):
+ current_type = get_internet_connection_type(log, ad)
+ ad.log.info("current data connection type: %s", current_type)
+ if not connection_type:
+ return True
+ else:
+ if not is_connected and current_type != connection_type:
+ ad.log.info("data connection not on %s", connection_type)
+ return True
+ elif is_connected and current_type == connection_type:
+ ad.log.info("after event wait, data connection on %s",
+ connection_type)
+ return True
+ else:
+ return False
+ else:
+ return False
+ except Exception as e:
+ ad.log.error("Exception error %s", str(e))
+ return False
+ finally:
+ ad.droid.connectivityStopTrackingConnectivityStateChange()
+
+
+def check_curl_availability(ad):
+ if not hasattr(ad, "curl_capable"):
+ try:
+ out = ad.adb.shell("/data/curl --version")
+ if not out or "not found" in out:
+ setattr(ad, "curl_capable", False)
+ ad.log.info("curl is unavailable, use chrome to download file")
+ else:
+ setattr(ad, "curl_capable", True)
+ except Exception:
+ setattr(ad, "curl_capable", False)
+ ad.log.info("curl is unavailable, use chrome to download file")
+ return ad.curl_capable
+
+
+def start_youtube_video(ad, url="vnd.youtube:watch?v=pSJoP0LR8CQ"):
+ ad.log.info("Open an youtube video")
+ for _ in range(3):
+ ad.ensure_screen_on()
+ ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url)
+ if wait_for_state(ad.droid.audioIsMusicActive, True, 15, 1):
+ ad.log.info("Started a video in youtube, audio is in MUSIC state")
+ return True
+ ad.log.info("Audio is not in MUSIC state. Quit Youtube.")
+ for _ in range(3):
+ ad.send_keycode("BACK")
+ time.sleep(1)
+ time.sleep(3)
+ return False
+
+
+def http_file_download_by_sl4a(ad,
+ url,
+ out_path=None,
+ expected_file_size=None,
+ remove_file_after_check=True,
+ timeout=300):
+ """Download http file by sl4a RPC call.
+
+ Args:
+ ad: Android Device Object.
+ url: The url that file to be downloaded from".
+ out_path: Optional. Where to download file to.
+ out_path is /sdcard/Download/ by default.
+ expected_file_size: Optional. Provided if checking the download file meet
+ expected file size in unit of byte.
+ remove_file_after_check: Whether to remove the downloaded file after
+ check.
+ timeout: timeout for file download to complete.
+ """
+ file_folder, file_name = _generate_file_directory_and_file_name(
+ url, out_path)
+ file_path = os.path.join(file_folder, file_name)
+ ad.adb.shell("rm -f %s" % file_path)
+ accounting_apk = SL4A_APK_NAME
+ result = True
+ try:
+ if not getattr(ad, "data_droid", None):
+ ad.data_droid, ad.data_ed = ad.get_droid()
+ ad.data_ed.start()
+ else:
+ try:
+ if not ad.data_droid.is_live:
+ ad.data_droid, ad.data_ed = ad.get_droid()
+ ad.data_ed.start()
+ except Exception:
+ ad.log.info("Start new sl4a session for file download")
+ ad.data_droid, ad.data_ed = ad.get_droid()
+ ad.data_ed.start()
+ data_accounting = {
+ "mobile_rx_bytes":
+ ad.droid.getMobileRxBytes(),
+ "subscriber_mobile_data_usage":
+ get_mobile_data_usage(ad, None, None),
+ "sl4a_mobile_data_usage":
+ get_mobile_data_usage(ad, None, accounting_apk)
+ }
+ ad.log.debug("Before downloading: %s", data_accounting)
+ ad.log.info("Download file from %s to %s by sl4a RPC call", url,
+ file_path)
+ try:
+ ad.data_droid.httpDownloadFile(url, file_path, timeout=timeout)
+ except Exception as e:
+ ad.log.warning("SL4A file download error: %s", e)
+ ad.data_droid.terminate()
+ return False
+ if _check_file_existence(ad, file_path, expected_file_size):
+ ad.log.info("%s is downloaded successfully", url)
+ new_data_accounting = {
+ "mobile_rx_bytes":
+ ad.droid.getMobileRxBytes(),
+ "subscriber_mobile_data_usage":
+ get_mobile_data_usage(ad, None, None),
+ "sl4a_mobile_data_usage":
+ get_mobile_data_usage(ad, None, accounting_apk)
+ }
+ ad.log.debug("After downloading: %s", new_data_accounting)
+ accounting_diff = {
+ key: value - data_accounting[key]
+ for key, value in new_data_accounting.items()
+ }
+ ad.log.debug("Data accounting difference: %s", accounting_diff)
+ if getattr(ad, "on_mobile_data", False):
+ for key, value in accounting_diff.items():
+ if value < expected_file_size:
+ ad.log.debug("%s diff is %s less than %s", key,
+ value, expected_file_size)
+ ad.data_accounting["%s_failure"] += 1
+ else:
+ for key, value in accounting_diff.items():
+ if value >= expected_file_size:
+ ad.log.error("%s diff is %s. File download is "
+ "consuming mobile data", key, value)
+ result = False
+ return result
+ else:
+ ad.log.warning("Fail to download %s", url)
+ return False
+ except Exception as e:
+ ad.log.error("Download %s failed with exception %s", url, e)
+ raise
+ finally:
+ if remove_file_after_check:
+ ad.log.info("Remove the downloaded file %s", file_path)
+ ad.adb.shell("rm %s" % file_path, ignore_status=True)
+
+
+def http_file_download_by_curl(ad,
+ url,
+ out_path=None,
+ expected_file_size=None,
+ remove_file_after_check=True,
+ timeout=3600,
+ limit_rate=None,
+ retry=3):
+ """Download http file by adb curl.
+
+ Args:
+ ad: Android Device Object.
+ url: The url that file to be downloaded from".
+ out_path: Optional. Where to download file to.
+ out_path is /sdcard/Download/ by default.
+ expected_file_size: Optional. Provided if checking the download file meet
+ expected file size in unit of byte.
+ remove_file_after_check: Whether to remove the downloaded file after
+ check.
+ timeout: timeout for file download to complete.
+ limit_rate: download rate in bps. None, if do not apply rate limit.
+ retry: the retry request times provided in curl command.
+ """
+ file_directory, file_name = _generate_file_directory_and_file_name(
+ url, out_path)
+ file_path = os.path.join(file_directory, file_name)
+ curl_cmd = "/data/curl"
+ if limit_rate:
+ curl_cmd += " --limit-rate %s" % limit_rate
+ if retry:
+ curl_cmd += " --retry %s" % retry
+ curl_cmd += " --url %s > %s" % (url, file_path)
+ try:
+ ad.log.info("Download %s to %s by adb shell command %s", url,
+ file_path, curl_cmd)
+
+ ad.adb.shell(curl_cmd, timeout=timeout)
+ if _check_file_existence(ad, file_path, expected_file_size):
+ ad.log.info("%s is downloaded to %s successfully", url, file_path)
+ return True
+ else:
+ ad.log.warning("Fail to download %s", url)
+ return False
+ except Exception as e:
+ ad.log.warning("Download %s failed with exception %s", url, e)
+ return False
+ finally:
+ if remove_file_after_check:
+ ad.log.info("Remove the downloaded file %s", file_path)
+ ad.adb.shell("rm %s" % file_path, ignore_status=True)
+
+
+def open_url_by_adb(ad, url):
+ ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url)
+
+
+def http_file_download_by_chrome(ad,
+ url,
+ expected_file_size=None,
+ remove_file_after_check=True,
+ timeout=3600):
+ """Download http file by chrome.
+
+ Args:
+ ad: Android Device Object.
+ url: The url that file to be downloaded from".
+ expected_file_size: Optional. Provided if checking the download file meet
+ expected file size in unit of byte.
+ remove_file_after_check: Whether to remove the downloaded file after
+ check.
+ timeout: timeout for file download to complete.
+ """
+ chrome_apk = "com.android.chrome"
+ file_directory, file_name = _generate_file_directory_and_file_name(
+ url, "/sdcard/Download/")
+ file_path = os.path.join(file_directory, file_name)
+ # Remove pre-existing file
+ ad.force_stop_apk(chrome_apk)
+ file_to_be_delete = os.path.join(file_directory, "*%s*" % file_name)
+ ad.adb.shell("rm -f %s" % file_to_be_delete)
+ ad.adb.shell("rm -rf /sdcard/Download/.*")
+ ad.adb.shell("rm -f /sdcard/Download/.*")
+ data_accounting = {
+ "total_rx_bytes": ad.droid.getTotalRxBytes(),
+ "mobile_rx_bytes": ad.droid.getMobileRxBytes(),
+ "subscriber_mobile_data_usage": get_mobile_data_usage(ad, None, None),
+ "chrome_mobile_data_usage": get_mobile_data_usage(
+ ad, None, chrome_apk)
+ }
+ ad.log.debug("Before downloading: %s", data_accounting)
+ ad.log.info("Download %s with timeout %s", url, timeout)
+ ad.ensure_screen_on()
+ open_url_by_adb(ad, url)
+ elapse_time = 0
+ result = True
+ while elapse_time < timeout:
+ time.sleep(30)
+ if _check_file_existence(ad, file_path, expected_file_size):
+ ad.log.info("%s is downloaded successfully", url)
+ if remove_file_after_check:
+ ad.log.info("Remove the downloaded file %s", file_path)
+ ad.adb.shell("rm -f %s" % file_to_be_delete)
+ ad.adb.shell("rm -rf /sdcard/Download/.*")
+ ad.adb.shell("rm -f /sdcard/Download/.*")
+ #time.sleep(30)
+ new_data_accounting = {
+ "mobile_rx_bytes":
+ ad.droid.getMobileRxBytes(),
+ "subscriber_mobile_data_usage":
+ get_mobile_data_usage(ad, None, None),
+ "chrome_mobile_data_usage":
+ get_mobile_data_usage(ad, None, chrome_apk)
+ }
+ ad.log.info("After downloading: %s", new_data_accounting)
+ accounting_diff = {
+ key: value - data_accounting[key]
+ for key, value in new_data_accounting.items()
+ }
+ ad.log.debug("Data accounting difference: %s", accounting_diff)
+ if getattr(ad, "on_mobile_data", False):
+ for key, value in accounting_diff.items():
+ if value < expected_file_size:
+ ad.log.warning("%s diff is %s less than %s", key,
+ value, expected_file_size)
+ ad.data_accounting["%s_failure" % key] += 1
+ else:
+ for key, value in accounting_diff.items():
+ if value >= expected_file_size:
+ ad.log.error("%s diff is %s. File download is "
+ "consuming mobile data", key, value)
+ result = False
+ return result
+ elif _check_file_existence(ad, "%s.crdownload" % file_path):
+ ad.log.info("Chrome is downloading %s", url)
+ elif elapse_time < 60:
+ # download not started, retry download wit chrome again
+ open_url_by_adb(ad, url)
+ else:
+ ad.log.error("Unable to download file from %s", url)
+ break
+ elapse_time += 30
+ ad.log.warning("Fail to download file from %s", url)
+ ad.force_stop_apk("com.android.chrome")
+ ad.adb.shell("rm -f %s" % file_to_be_delete)
+ ad.adb.shell("rm -rf /sdcard/Download/.*")
+ ad.adb.shell("rm -f /sdcard/Download/.*")
+ return False
+
+
+def get_mobile_data_usage(ad, sid=None, apk=None):
+ if not sid:
+ sid = ad.droid.subscriptionGetDefaultDataSubId()
+ current_time = int(time.time() * 1000)
+ begin_time = current_time - 10 * 24 * 60 * 60 * 1000
+ end_time = current_time + 10 * 24 * 60 * 60 * 1000
+
+ if apk:
+ uid = ad.get_apk_uid(apk)
+ ad.log.debug("apk %s uid = %s", apk, uid)
+ try:
+ usage_info = ad.droid.getMobileDataUsageInfoForUid(uid, sid)
+ ad.log.debug("Mobile data usage info for uid %s = %s", uid,
+ usage_info)
+ return usage_info["UsageLevel"]
+ except:
+ try:
+ return ad.droid.connectivityQueryDetailsForUid(
+ TYPE_MOBILE,
+ ad.droid.telephonyGetSubscriberIdForSubscription(sid),
+ begin_time, end_time, uid)
+ except:
+ return ad.droid.connectivityQueryDetailsForUid(
+ ad.droid.telephonyGetSubscriberIdForSubscription(sid),
+ begin_time, end_time, uid)
+ else:
+ try:
+ usage_info = ad.droid.getMobileDataUsageInfo(sid)
+ ad.log.debug("Mobile data usage info = %s", usage_info)
+ return usage_info["UsageLevel"]
+ except:
+ try:
+ return ad.droid.connectivityQuerySummaryForDevice(
+ TYPE_MOBILE,
+ ad.droid.telephonyGetSubscriberIdForSubscription(sid),
+ begin_time, end_time)
+ except:
+ return ad.droid.connectivityQuerySummaryForDevice(
+ ad.droid.telephonyGetSubscriberIdForSubscription(sid),
+ begin_time, end_time)
+
+
+def set_mobile_data_usage_limit(ad, limit, subscriber_id=None):
+ if not subscriber_id:
+ subscriber_id = ad.droid.telephonyGetSubscriberId()
+ ad.log.debug("Set subscriber mobile data usage limit to %s", limit)
+ ad.droid.logV("Setting subscriber mobile data usage limit to %s" % limit)
+ try:
+ ad.droid.connectivitySetDataUsageLimit(subscriber_id, str(limit))
+ except:
+ ad.droid.connectivitySetDataUsageLimit(subscriber_id, limit)
+
+
+def remove_mobile_data_usage_limit(ad, subscriber_id=None):
+ if not subscriber_id:
+ subscriber_id = ad.droid.telephonyGetSubscriberId()
+ ad.log.debug("Remove subscriber mobile data usage limit")
+ ad.droid.logV(
+ "Setting subscriber mobile data usage limit to -1, unlimited")
+ try:
+ ad.droid.connectivitySetDataUsageLimit(subscriber_id, "-1")
+ except:
+ ad.droid.connectivitySetDataUsageLimit(subscriber_id, -1)
+
+
+def active_file_download_task(log, ad, file_name="5MB", method="curl"):
+ # files available for download on the same website:
+ # 1GB.zip, 512MB.zip, 200MB.zip, 50MB.zip, 20MB.zip, 10MB.zip, 5MB.zip
+ # download file by adb command, as phone call will use sl4a
+ file_size_map = {
+ '1MB': 1000000,
+ '5MB': 5000000,
+ '10MB': 10000000,
+ '20MB': 20000000,
+ '50MB': 50000000,
+ '100MB': 100000000,
+ '200MB': 200000000,
+ '512MB': 512000000
+ }
+ url_map = {
+ "1MB": [
+ "http://146.148.91.8/download/1MB.zip",
+ "http://ipv4.download.thinkbroadband.com/1MB.zip"
+ ],
+ "5MB": [
+ "http://146.148.91.8/download/5MB.zip",
+ "http://212.183.159.230/5MB.zip",
+ "http://ipv4.download.thinkbroadband.com/5MB.zip"
+ ],
+ "10MB": [
+ "http://146.148.91.8/download/10MB.zip",
+ "http://212.183.159.230/10MB.zip",
+ "http://ipv4.download.thinkbroadband.com/10MB.zip",
+ "http://lax.futurehosting.com/test.zip",
+ "http://ovh.net/files/10Mio.dat"
+ ],
+ "20MB": [
+ "http://146.148.91.8/download/20MB.zip",
+ "http://212.183.159.230/20MB.zip",
+ "http://ipv4.download.thinkbroadband.com/20MB.zip"
+ ],
+ "50MB": [
+ "http://146.148.91.8/download/50MB.zip",
+ "http://212.183.159.230/50MB.zip",
+ "http://ipv4.download.thinkbroadband.com/50MB.zip"
+ ],
+ "100MB": [
+ "http://146.148.91.8/download/100MB.zip",
+ "http://212.183.159.230/100MB.zip",
+ "http://ipv4.download.thinkbroadband.com/100MB.zip",
+ "http://speedtest-ca.turnkeyinternet.net/100mb.bin",
+ "http://ovh.net/files/100Mio.dat",
+ "http://lax.futurehosting.com/test100.zip"
+ ],
+ "200MB": [
+ "http://146.148.91.8/download/200MB.zip",
+ "http://212.183.159.230/200MB.zip",
+ "http://ipv4.download.thinkbroadband.com/200MB.zip"
+ ],
+ "512MB": [
+ "http://146.148.91.8/download/512MB.zip",
+ "http://212.183.159.230/512MB.zip",
+ "http://ipv4.download.thinkbroadband.com/512MB.zip"
+ ]
+ }
+
+ file_size = file_size_map.get(file_name)
+ file_urls = url_map.get(file_name)
+ file_url = None
+ for url in file_urls:
+ url_splits = url.split("/")
+ if verify_http_connection(log, ad, url=url, retry=1):
+ output_path = "/sdcard/Download/%s" % url_splits[-1]
+ file_url = url
+ break
+ if not file_url:
+ ad.log.error("No url is available to download %s", file_name)
+ return False
+ timeout = min(max(file_size / 100000, 600), 3600)
+ if method == "sl4a":
+ return (http_file_download_by_sl4a, (ad, file_url, output_path,
+ file_size, True, timeout))
+ if method == "curl" and check_curl_availability(ad):
+ return (http_file_download_by_curl, (ad, file_url, output_path,
+ file_size, True, timeout))
+ elif method == "sl4a" or method == "curl":
+ return (http_file_download_by_sl4a, (ad, file_url, output_path,
+ file_size, True, timeout))
+ else:
+ return (http_file_download_by_chrome, (ad, file_url, file_size, True,
+ timeout))
+
+
+def active_file_download_test(log, ad, file_name="5MB", method="sl4a"):
+ task = active_file_download_task(log, ad, file_name, method=method)
+ if not task:
+ return False
+ return task[0](*task[1])
+
+
+def check_data_stall_detection(ad, wait_time=WAIT_TIME_FOR_DATA_STALL):
+ data_stall_detected = False
+ time_var = 1
+ try:
+ while (time_var < wait_time):
+ out = ad.adb.shell("dumpsys network_stack " \
+ "| grep \"Suspecting data stall\"",
+ ignore_status=True)
+ ad.log.debug("Output is %s", out)
+ if out:
+ ad.log.info("NetworkMonitor detected - %s", out)
+ data_stall_detected = True
+ break
+ time.sleep(30)
+ time_var += 30
+ except Exception as e:
+ ad.log.error(e)
+ return data_stall_detected
+
+
+def check_network_validation_fail(ad, begin_time=None,
+ wait_time=WAIT_TIME_FOR_NW_VALID_FAIL):
+ network_validation_fail = False
+ time_var = 1
+ try:
+ while (time_var < wait_time):
+ time_var += 30
+ nw_valid = ad.search_logcat("validation failed",
+ begin_time)
+ if nw_valid:
+ ad.log.info("Validation Failed received here - %s",
+ nw_valid[0]["log_message"])
+ network_validation_fail = True
+ break
+ time.sleep(30)
+ except Exception as e:
+ ad.log.error(e)
+ return network_validation_fail
+
+
+def check_data_stall_recovery(ad, begin_time=None,
+ wait_time=WAIT_TIME_FOR_DATA_STALL_RECOVERY):
+ data_stall_recovery = False
+ time_var = 1
+ try:
+ while (time_var < wait_time):
+ time_var += 30
+ recovery = ad.search_logcat("doRecovery() cleanup all connections",
+ begin_time)
+ if recovery:
+ ad.log.info("Recovery Performed here - %s",
+ recovery[-1]["log_message"])
+ data_stall_recovery = True
+ break
+ time.sleep(30)
+ except Exception as e:
+ ad.log.error(e)
+ return data_stall_recovery
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_defines.py b/acts_tests/acts_contrib/test_utils/tel/tel_defines.py
index 6761380..a8b4108 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_defines.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_defines.py
@@ -354,6 +354,9 @@
CARRIER_KDDI = 'kddi'
CARRIER_RAKUTEN = 'rakuten'
CARRIER_SBM = 'sbm'
+CARRIER_SKT = 'skt'
+CARRIER_KT = 'kt'
+CARRIER_LG_UPLUS = 'lg_uplus'
RAT_FAMILY_CDMA = 'cdma'
RAT_FAMILY_CDMA2000 = 'cdma2000'
@@ -684,10 +687,17 @@
NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA = "NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA"
NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = "NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA"
+# Constants for APP Package Name
+DIALER_PACKAGE_NAME = "com.google.android.dialer"
+MESSAGE_PACKAGE_NAME = "com.google.android.apps.messaging"
+YOUTUBE_PACKAGE_NAME = "com.google.android.youtube"
+SL4A_PACKAGE_NAME = "com.googlecode.android_scripting"
+
# Constants for CellBroadcast module test
CARRIER_TEST_CONF_XML_PATH = "/data/user_de/0/com.android.phone/files/"
MAIN_ACTIVITY = "android.intent.action.MAIN"
CBR_PACKAGE = "com.google.android.cellbroadcastreceiver"
+SYSUI_PACKAGE = "com.android.systemui"
CBR_ACTIVITY = "com.android.cellbroadcastreceiver.CellBroadcastSettings"
CBR_TEST_APK = "com.android.cellbroadcastreceiver.tests"
MCC_MNC = "mccmnc"
@@ -696,15 +706,34 @@
WAIT_TIME_FOR_ALERTS_TO_POPULATE = 60
WAIT_TIME_FOR_UI = 5
SCROLL_DOWN = "input swipe 300 900 300 300"
+WAIT_TIME_FOR_ALERT_TO_RECEIVE = 15
+DEFAULT_SOUND_TIME = 16
+DEFAULT_VIBRATION_TIME = 10
+DEFAULT_OFFSET = 1
+EXIT_ALERT_LIST = ["Got it", "OK", "Hide", "TO CLOSE", "Yes"]
+CMD_DND_OFF = "cmd notification set_dnd off"
+CMD_DND_ON = "cmd notification set_dnd on"
+DUMPSYS_VIBRATION = "dumpsys vibrator_manager | grep -i com.google.android.cellbroadcastreceiver | tail -1"
+DEFAULT_ALERT_TYPE = "popup"
+EXPAND_NOTIFICATION_BAR = "cmd statusbar expand-notifications"
+COLLAPSE_NOTIFICATION_BAR = "cmd statusbar collapse"
+CLEAR_NOTIFICATION_BAR = "service call notification 1"
# Countries/Carriers for Compliance Testing
+AUSTRALIA = "australia"
BRAZIL = "brazil"
CANADA = "canada"
-CHILE = "chile"
+CHILE_ENTEL = "chile_entel"
+CHILE_TELEFONICA = "chile_telefonica"
COLUMBIA = "columbia"
-EQUADOR = "equador"
+ECUADOR_TELEFONICA = "ecuador_telefonica"
+ECUADOR_CLARO = "ecuador_claro"
+ELSALVADOR_TELEFONICA = "elsalvador_telefonica"
ESTONIA = "estonia"
+FRANCE = "france"
GREECE = "greece"
+GERMANY_TELEKOM = "germany_telekom"
+QATAR_VODAFONE = "qatar_vodafone"
HONGKONG = "hongkong"
ISRAEL = "israel"
ITALY = "italy"
@@ -713,10 +742,12 @@
KOREA = "korea"
LATVIA = "latvia"
LITHUANIA = "lithuania"
+MEXICO_TELEFONICA = "mexico_telefonica"
NETHERLANDS = "netherlands"
NEWZEALAND = "newzealand"
OMAN = "oman"
-PERU = "peru"
+PERU_ENTEL = "peru_entel"
+PERU_TELEFONICA = "peru_telefonica"
PUERTORICO = "puertorico"
ROMANIA = "romania"
SAUDIARABIA = "saudiarabia"
@@ -724,6 +755,9 @@
TAIWAN = "taiwan"
UAE = "uae"
UK = "uk"
+US_ATT = "us_att"
+US_TMO = "us_tmo"
+US_VZW = "us_vzw"
# Carrier Config Update
CARRIER_ID_VERSION = "3"
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_dsds_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_dsds_utils.py
new file mode 100644
index 0000000..e9279be
--- /dev/null
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_dsds_utils.py
@@ -0,0 +1,2762 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - Google
+#
+# 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 datetime import datetime, timedelta
+import re
+import time
+from typing import Optional, Sequence
+
+from acts import signals
+from acts import tracelogger
+from acts.controllers.android_device import AndroidDevice
+from acts.utils import rand_ascii_str
+from acts.libs.utils.multithread import multithread_func
+from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
+from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
+from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
+from acts_contrib.test_utils.tel.tel_defines import YOUTUBE_PACKAGE_NAME
+from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_test
+from acts_contrib.test_utils.tel.tel_data_utils import start_youtube_video
+from acts_contrib.test_utils.tel.tel_message_utils import log_messaging_screen_shot
+from acts_contrib.test_utils.tel.tel_message_utils import mms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify_for_subscription
+from acts_contrib.test_utils.tel.tel_ss_utils import erase_call_forwarding_by_mmi
+from acts_contrib.test_utils.tel.tel_ss_utils import set_call_forwarding_by_mmi
+from acts_contrib.test_utils.tel.tel_ss_utils import set_call_waiting
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_wfc_for_subscription
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_on_rat
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_network_idle
+from acts_contrib.test_utils.tel.tel_ss_utils import three_phone_call_forwarding_short_seq
+from acts_contrib.test_utils.tel.tel_ss_utils import three_phone_call_waiting_short_seq
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_subid
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_message_subid
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_data
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_voice_sub_id
+from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
+from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls
+from acts_contrib.test_utils.tel.tel_test_utils import power_off_sim
+from acts_contrib.test_utils.tel.tel_test_utils import power_on_sim
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
+from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
+from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_ims_conference_merge_drop_second_call_from_participant
+from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_wcdma_conference_merge_drop
+from acts_contrib.test_utils.tel.tel_voice_conf_utils import _three_phone_call_mo_add_mt
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_on_rat
+from acts_contrib.test_utils.tel.tel_voice_utils import swap_calls
+from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_msim_for_slot
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_reject_call_for_subscription
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
+
+CallResult = TelephonyVoiceTestResult.CallResult.Value
+
+
+def dsds_dds_swap_message_streaming_test(
+ log: tracelogger.TraceLogger,
+ ads: Sequence[AndroidDevice],
+ test_rat: list,
+ test_slot: list,
+ init_dds: int,
+ msg_type: str = "SMS",
+ direction: str = "mt",
+ streaming: bool = True,
+ expected_result: bool = True) -> bool:
+ """Make MO and MT message at specific slot in specific RAT with DDS at
+ specific slot and do the same steps after dds swap.
+
+ Args:
+ log: Logger object.
+ ads: A list of Android device objects.
+ test_rat: RAT for both slots of primary device.
+ test_slot: The slot which make/receive MO/MT SMS/MMS of primary device.
+ dds_slot: Preferred data slot of primary device.
+ msg_type: SMS or MMS to send.
+ direction: The direction of message("mo" or "mt") at first.
+ streaming: True for playing Youtube before send/receive SMS/MMS and
+ False on the contrary.
+ expected_result: True or False
+
+ Returns:
+ TestFailure if failed.
+ """
+ result = True
+
+ for test_slot, dds_slot in zip(test_slot, [init_dds, 1-init_dds]):
+ ads[0].log.info("test_slot: %d, dds_slot: %d", test_slot, dds_slot)
+ result = result and dsds_message_streaming_test(
+ log=log,
+ ads=ads,
+ test_rat=test_rat,
+ test_slot=test_slot,
+ dds_slot=dds_slot,
+ msg_type=msg_type,
+ direction=direction,
+ streaming=streaming,
+ expected_result=expected_result
+ )
+ if not result:
+ return result
+
+ log.info("Switch DDS back.")
+ if not set_dds_on_slot(ads[0], init_dds):
+ ads[0].log.error(
+ "Failed to set DDS at slot %s on %s",(init_dds, ads[0].serial))
+ return False
+
+ log.info("Check phones is in desired RAT.")
+ phone_setup_on_rat(
+ log,
+ ads[0],
+ test_rat[test_slot],
+ get_subid_from_slot_index(log, ads[0], init_dds)
+ )
+
+ log.info("Check HTTP connection after DDS switch.")
+ if not verify_http_connection(log, ads[0]):
+ ads[0].log.error("Failed to verify http connection.")
+ return False
+ else:
+ ads[0].log.info("Verify http connection successfully.")
+
+ return result
+
+
+def dsds_dds_swap_call_streaming_test(
+ log: tracelogger.TraceLogger,
+ tel_logger: TelephonyMetricLogger.for_test_case,
+ ads: Sequence[AndroidDevice],
+ test_rat: list,
+ test_slot: list,
+ init_dds: int,
+ direction: str = "mo",
+ duration: int = 360,
+ streaming: bool = True,
+ is_airplane_mode: bool = False,
+ wfc_mode: Sequence[str] = [
+ WFC_MODE_CELLULAR_PREFERRED,
+ WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid: Optional[str] = None,
+ wifi_network_pass: Optional[str] = None,
+ turn_off_wifi_in_the_end: bool = False,
+ turn_off_airplane_mode_in_the_end: bool = False) -> bool:
+ """Make MO/MT call at specific slot in specific RAT with DDS at specific
+ slot and do the same steps after dds swap.
+
+ Args:
+ log: Logger object.
+ tel_logger: Logger object for telephony proto.
+ ads: A list of Android device objects.
+ test_rat: RAT for both slots of primary device.
+ test_slot: The slot which make/receive MO/MT call of primary device.
+ init_dds: Initial preferred data slot of primary device.
+ direction: The direction of call("mo" or "mt").
+ streaming: True for playing Youtube and False on the contrary.
+ is_airplane_mode: True or False for WFC setup
+ wfc_mode: Cellular preferred or Wi-Fi preferred.
+ wifi_network_ssid: SSID of Wi-Fi AP.
+ wifi_network_pass: Password of Wi-Fi AP SSID.
+ turn_off_wifi_in_the_end: True to turn off Wi-Fi and False not to turn
+ off Wi-Fi in the end of the function.
+ turn_off_airplane_mode_in_the_end: True to turn off airplane mode and
+ False not to turn off airplane mode in the end of the function.
+
+ Returns:
+ TestFailure if failed.
+ """
+ result = True
+
+ for test_slot, dds_slot in zip(test_slot, [init_dds, 1-init_dds]):
+ ads[0].log.info("test_slot: %d, dds_slot: %d", test_slot, dds_slot)
+ result = result and dsds_long_call_streaming_test(
+ log=log,
+ tel_logger=tel_logger,
+ ads=ads,
+ test_rat=test_rat,
+ test_slot=test_slot,
+ dds_slot=dds_slot,
+ direction=direction,
+ duration=duration,
+ streaming=streaming,
+ is_airplane_mode=is_airplane_mode,
+ wfc_mode=wfc_mode,
+ wifi_network_ssid=wifi_network_ssid,
+ wifi_network_pass=wifi_network_pass,
+ turn_off_wifi_in_the_end=turn_off_wifi_in_the_end,
+ turn_off_airplane_mode_in_the_end=turn_off_airplane_mode_in_the_end
+ )
+ if not result:
+ return result
+
+ log.info("Switch DDS back.")
+ if not set_dds_on_slot(ads[0], init_dds):
+ ads[0].log.error(
+ "Failed to set DDS at slot %s on %s",(init_dds, ads[0].serial))
+ return False
+
+ log.info("Check phones is in desired RAT.")
+ phone_setup_on_rat(
+ log,
+ ads[0],
+ test_rat[test_slot],
+ get_subid_from_slot_index(log, ads[0], init_dds)
+ )
+
+ log.info("Check HTTP connection after DDS switch.")
+ if not verify_http_connection(log, ads[0]):
+ ads[0].log.error("Failed to verify http connection.")
+ return False
+ else:
+ ads[0].log.info("Verify http connection successfully.")
+
+ return result
+
+
+def dsds_long_call_streaming_test(
+ log: tracelogger.TraceLogger,
+ tel_logger: TelephonyMetricLogger.for_test_case,
+ ads: Sequence[AndroidDevice],
+ test_rat: list,
+ test_slot: int,
+ dds_slot: int,
+ direction: str = "mo",
+ duration: int = 360,
+ streaming: bool = True,
+ is_airplane_mode: bool = False,
+ wfc_mode: Sequence[str] = [
+ WFC_MODE_CELLULAR_PREFERRED,
+ WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid: Optional[str] = None,
+ wifi_network_pass: Optional[str] = None,
+ turn_off_wifi_in_the_end: bool = False,
+ turn_off_airplane_mode_in_the_end: bool = False) -> bool:
+ """Make MO/MT call at specific slot in specific RAT with DDS at specific
+ slot for the given time.
+
+ Args:
+ log: Logger object.
+ tel_logger: Logger object for telephony proto.
+ ads: A list of Android device objects.
+ test_rat: RAT for both slots of primary device.
+ test_slot: The slot which make/receive MO/MT call of primary device.
+ dds_slot: Preferred data slot of primary device.
+ direction: The direction of call("mo" or "mt").
+ streaming: True for playing Youtube and False on the contrary.
+ is_airplane_mode: True or False for WFC setup
+ wfc_mode: Cellular preferred or Wi-Fi preferred.
+ wifi_network_ssid: SSID of Wi-Fi AP.
+ wifi_network_pass: Password of Wi-Fi AP SSID.
+ turn_off_wifi_in_the_end: True to turn off Wi-Fi and False not to turn
+ off Wi-Fi in the end of the function.
+ turn_off_airplane_mode_in_the_end: True to turn off airplane mode and
+ False not to turn off airplane mode in the end of the function.
+
+ Returns:
+ TestFailure if failed.
+ """
+ log.info("Step 1: Switch DDS.")
+ if not set_dds_on_slot(ads[0], dds_slot):
+ ads[0].log.error(
+ "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
+ return False
+
+ log.info("Step 2: Check HTTP connection after DDS switch.")
+ if not verify_http_connection(log, ads[0]):
+ ads[0].log.error("Failed to verify http connection.")
+ return False
+ else:
+ ads[0].log.info("Verify http connection successfully.")
+
+ log.info("Step 3: Set up phones in desired RAT.")
+ if direction == "mo":
+ # setup voice subid on primary device.
+ ad_mo = ads[0]
+ mo_sub_id = get_subid_from_slot_index(log, ad_mo, test_slot)
+ if mo_sub_id == INVALID_SUB_ID:
+ ad_mo.log.warning("Failed to get sub ID at slot %s.", test_slot)
+ return False
+ mo_other_sub_id = get_subid_from_slot_index(
+ log, ad_mo, 1-test_slot)
+ sub_id_list = [mo_sub_id, mo_other_sub_id]
+ set_voice_sub_id(ad_mo, mo_sub_id)
+ ad_mo.log.info("Sub ID for outgoing call at slot %s: %s", test_slot,
+ get_outgoing_voice_sub_id(ad_mo))
+
+ # setup voice subid on secondary device.
+ ad_mt = ads[1]
+ _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
+ if mt_sub_id == INVALID_SUB_ID:
+ ad_mt.log.warning("Failed to get sub ID at default voice slot.")
+ return False
+ mt_slot = get_slot_index_from_subid(ad_mt, mt_sub_id)
+ set_voice_sub_id(ad_mt, mt_sub_id)
+ ad_mt.log.info("Sub ID for incoming call at slot %s: %s", mt_slot,
+ get_outgoing_voice_sub_id(ad_mt))
+
+ # setup the rat on non-test slot(primary device).
+ phone_setup_on_rat(
+ log,
+ ad_mo,
+ test_rat[1-test_slot],
+ mo_other_sub_id,
+ is_airplane_mode,
+ wfc_mode[1-test_slot],
+ wifi_network_ssid,
+ wifi_network_pass)
+ # assign phone setup argv for test slot.
+ mo_phone_setup_func_argv = (
+ log,
+ ad_mo,
+ test_rat[test_slot],
+ mo_sub_id,
+ is_airplane_mode,
+ wfc_mode[test_slot],
+ wifi_network_ssid,
+ wifi_network_pass)
+ verify_caller_func = is_phone_in_call_on_rat(
+ log, ad_mo, test_rat[test_slot], only_return_fn=True)
+ mt_phone_setup_func_argv = (log, ad_mt, 'general')
+ verify_callee_func = is_phone_in_call_on_rat(
+ log, ad_mt, 'general', only_return_fn=True)
+ else:
+ # setup voice subid on primary device.
+ ad_mt = ads[0]
+ mt_sub_id = get_subid_from_slot_index(log, ad_mt, test_slot)
+ if mt_sub_id == INVALID_SUB_ID:
+ ad_mt.log.warning("Failed to get sub ID at slot %s.", test_slot)
+ return False
+ mt_other_sub_id = get_subid_from_slot_index(
+ log, ad_mt, 1-test_slot)
+ sub_id_list = [mt_sub_id, mt_other_sub_id]
+ set_voice_sub_id(ad_mt, mt_sub_id)
+ ad_mt.log.info("Sub ID for incoming call at slot %s: %s", test_slot,
+ get_outgoing_voice_sub_id(ad_mt))
+
+ # setup voice subid on secondary device.
+ ad_mo = ads[1]
+ _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
+ if mo_sub_id == INVALID_SUB_ID:
+ ad_mo.log.warning("Failed to get sub ID at default voice slot.")
+ return False
+ mo_slot = get_slot_index_from_subid(ad_mo, mo_sub_id)
+ set_voice_sub_id(ad_mo, mo_sub_id)
+ ad_mo.log.info("Sub ID for outgoing call at slot %s: %s", mo_slot,
+ get_outgoing_voice_sub_id(ad_mo))
+
+ # setup the rat on non-test slot(primary device).
+ phone_setup_on_rat(
+ log,
+ ad_mt,
+ test_rat[1-test_slot],
+ mt_other_sub_id,
+ is_airplane_mode,
+ wfc_mode[1-test_slot],
+ wifi_network_ssid,
+ wifi_network_pass)
+ # assign phone setup argv for test slot.
+ mt_phone_setup_func_argv = (
+ log,
+ ad_mt,
+ test_rat[test_slot],
+ mt_sub_id,
+ is_airplane_mode,
+ wfc_mode[test_slot],
+ wifi_network_ssid,
+ wifi_network_pass)
+ verify_callee_func = is_phone_in_call_on_rat(
+ log, ad_mt, test_rat[test_slot], only_return_fn=True)
+ mo_phone_setup_func_argv = (log, ad_mo, 'general')
+ verify_caller_func = is_phone_in_call_on_rat(
+ log, ad_mo, 'general', only_return_fn=True)
+
+ tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv),
+ (phone_setup_on_rat, mt_phone_setup_func_argv)]
+ if not multithread_func(log, tasks):
+ log.error("Phone Failed to Set Up Properly.")
+ tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": "Phone Failed to Set Up Properly."})
+ if streaming:
+ log.info("Step 4-0: Start Youtube streaming.")
+ if not start_youtube_video(ads[0]):
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": "Fail to bring up youtube video."})
+ time.sleep(10)
+
+ log.info("Step 4: Make voice call.")
+ result = call_setup_teardown(log,
+ ad_mo,
+ ad_mt,
+ ad_hangup=ad_mo,
+ verify_caller_func=verify_caller_func,
+ verify_callee_func=verify_callee_func,
+ wait_time_in_call=duration)
+ tel_logger.set_result(result.result_value)
+
+ if not result:
+ log.error(
+ "Failed to make %s call from %s slot %s to %s slot %s",
+ direction, ad_mo.serial, mo_slot, ad_mt.serial, mt_slot)
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": str(result.result_value)})
+
+ log.info("Step 5: Verify RAT and HTTP connection.")
+ # For the tese cases related to WFC in which airplane mode will be turned
+ # off in the end.
+ if turn_off_airplane_mode_in_the_end:
+ log.info("Step 5-1: Turning off airplane mode......")
+ if not toggle_airplane_mode(log, ads[0], False):
+ ads[0].log.error('Failed to toggle off airplane mode.')
+
+ # For the tese cases related to WFC in which Wi-Fi will be turned off in the
+ # end.
+ rat_list = [test_rat[test_slot], test_rat[1-test_slot]]
+
+ if turn_off_wifi_in_the_end:
+ log.info("Step 5-2: Turning off Wi-Fi......")
+ if not wifi_toggle_state(log, ads[0], False):
+ ads[0].log.error('Failed to toggle off Wi-Fi.')
+ return False
+
+ for index, value in enumerate(rat_list):
+ if value == '5g_wfc':
+ rat_list[index] = '5g'
+ elif value == 'wfc':
+ rat_list[index] = '4g'
+
+ for rat, sub_id in zip(rat_list, sub_id_list):
+ if not wait_for_network_idle(log, ads[0], rat, sub_id):
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Idle state of sub ID %s does not match the "
+ "given RAT %s." % (sub_id, rat)})
+
+ if not verify_http_connection(log, ads[0]):
+ ads[0].log.error("Failed to verify http connection.")
+ return False
+ else:
+ ads[0].log.info("Verify http connection successfully.")
+
+ if streaming:
+ ads[0].force_stop_apk(YOUTUBE_PACKAGE_NAME)
+
+ return True
+
+
+def dsds_voice_call_test(
+ log,
+ tel_logger,
+ ads,
+ mo_slot,
+ mt_slot,
+ dds,
+ mo_rat=["", ""],
+ mt_rat=["", ""],
+ call_direction="mo",
+ is_airplane_mode=False,
+ wfc_mode=[
+ WFC_MODE_CELLULAR_PREFERRED,
+ WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=None,
+ wifi_network_pass=None,
+ turn_off_wifi_in_the_end=False,
+ turn_off_airplane_mode_in_the_end=False):
+ """Make MO/MT voice call at specific slot in specific RAT with DDS at
+ specific slot.
+
+ Test step:
+ 1. Get sub IDs of specific slots of both MO and MT devices.
+ 2. Switch DDS to specific slot.
+ 3. Check HTTP connection after DDS switch.
+ 4. Set up phones in desired RAT.
+ 5. Make voice call.
+ 6. Turn off airplane mode if necessary.
+ 7. Turn off Wi-Fi if necessary.
+ 8. Verify RAT and HTTP connection.
+
+ Args:
+ log: logger object
+ tel_logger: logger object for telephony proto
+ ads: list of android devices
+ mo_slot: Slot making MO call (0 or 1)
+ mt_slot: Slot receiving MT call (0 or 1)
+ dds: Preferred data slot
+ mo_rat: RAT for both slots of MO device
+ mt_rat: RAT for both slots of MT device
+ call_direction: "mo" or "mt"
+ is_airplane_mode: True or False for WFC setup
+ wfc_mode: Cellular preferred or Wi-Fi preferred.
+ wifi_network_ssid: SSID of Wi-Fi AP
+ wifi_network_pass: Password of Wi-Fi AP SSID
+ turn_off_wifi_in_the_end: True to turn off Wi-Fi and False not to turn
+ off Wi-Fi in the end of the function.
+ turn_off_airplane_mode_in_the_end: True to turn off airplane mode and
+ False not to turn off airplane mode in the end of the function.
+
+ Returns:
+ TestFailure if failed.
+ """
+ if not toggle_airplane_mode(log, ads[0], False):
+ ads[0].log.error("Failed to disable airplane mode.")
+ return False
+
+ if call_direction == "mo":
+ ad_mo = ads[0]
+ ad_mt = ads[1]
+ else:
+ ad_mo = ads[1]
+ ad_mt = ads[0]
+
+ if mo_slot is not None:
+ mo_sub_id = get_subid_from_slot_index(log, ad_mo, mo_slot)
+ if mo_sub_id == INVALID_SUB_ID:
+ ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot)
+ return False
+ mo_other_sub_id = get_subid_from_slot_index(
+ log, ad_mo, 1-mo_slot)
+ set_voice_sub_id(ad_mo, mo_sub_id)
+ else:
+ _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
+ if mo_sub_id == INVALID_SUB_ID:
+ ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot)
+ return False
+ mo_slot = "auto"
+ set_voice_sub_id(ad_mo, mo_sub_id)
+ ad_mo.log.info("Sub ID for outgoing call at slot %s: %s",
+ mo_slot, get_outgoing_voice_sub_id(ad_mo))
+
+ if mt_slot is not None:
+ mt_sub_id = get_subid_from_slot_index(log, ad_mt, mt_slot)
+ if mt_sub_id == INVALID_SUB_ID:
+ ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
+ return False
+ mt_other_sub_id = get_subid_from_slot_index(
+ log, ad_mt, 1-mt_slot)
+ set_voice_sub_id(ad_mt, mt_sub_id)
+ else:
+ _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
+ if mt_sub_id == INVALID_SUB_ID:
+ ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
+ return False
+ mt_slot = "auto"
+ set_voice_sub_id(ad_mt, mt_sub_id)
+ ad_mt.log.info("Sub ID for incoming call at slot %s: %s", mt_slot,
+ get_incoming_voice_sub_id(ad_mt))
+
+ log.info("Step 1: Switch DDS.")
+ if not set_dds_on_slot(ads[0], dds):
+ log.error(
+ "Failed to set DDS at slot %s on %s",(dds, ads[0].serial))
+ return False
+
+ log.info("Step 2: Check HTTP connection after DDS switch.")
+ if not verify_http_connection(log, ads[0]):
+ log.error("Failed to verify http connection.")
+ return False
+ else:
+ log.info("Verify http connection successfully.")
+
+ log.info("Step 3: Set up phones in desired RAT.")
+ if mo_slot == 0 or mo_slot == 1:
+ phone_setup_on_rat(
+ log,
+ ad_mo,
+ mo_rat[1-mo_slot],
+ mo_other_sub_id,
+ is_airplane_mode,
+ wfc_mode[1-mo_slot],
+ wifi_network_ssid,
+ wifi_network_pass)
+
+ mo_phone_setup_func_argv = (
+ log,
+ ad_mo,
+ mo_rat[mo_slot],
+ mo_sub_id,
+ is_airplane_mode,
+ wfc_mode[mo_slot],
+ wifi_network_ssid,
+ wifi_network_pass)
+
+ is_mo_in_call = is_phone_in_call_on_rat(
+ log, ad_mo, mo_rat[mo_slot], only_return_fn=True)
+ else:
+ mo_phone_setup_func_argv = (log, ad_mo, 'general')
+ is_mo_in_call = is_phone_in_call_on_rat(
+ log, ad_mo, 'general', only_return_fn=True)
+
+ if mt_slot == 0 or mt_slot == 1:
+ phone_setup_on_rat(
+ log,
+ ad_mt,
+ mt_rat[1-mt_slot],
+ mt_other_sub_id,
+ is_airplane_mode,
+ wfc_mode[1-mt_slot],
+ wifi_network_ssid,
+ wifi_network_pass)
+
+ mt_phone_setup_func_argv = (
+ log,
+ ad_mt,
+ mt_rat[mt_slot],
+ mt_sub_id,
+ is_airplane_mode,
+ wfc_mode[mt_slot],
+ wifi_network_ssid,
+ wifi_network_pass)
+
+ is_mt_in_call = is_phone_in_call_on_rat(
+ log, ad_mt, mt_rat[mt_slot], only_return_fn=True)
+ else:
+ mt_phone_setup_func_argv = (log, ad_mt, 'general')
+ is_mt_in_call = is_phone_in_call_on_rat(
+ log, ad_mt, 'general', only_return_fn=True)
+
+ tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv),
+ (phone_setup_on_rat, mt_phone_setup_func_argv)]
+ if not multithread_func(log, tasks):
+ log.error("Phone Failed to Set Up Properly.")
+ tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": "Phone Failed to Set Up Properly."})
+
+ log.info("Step 4: Make voice call.")
+ result = two_phone_call_msim_for_slot(
+ log,
+ ad_mo,
+ get_slot_index_from_subid(ad_mo, mo_sub_id),
+ None,
+ is_mo_in_call,
+ ad_mt,
+ get_slot_index_from_subid(ad_mt, mt_sub_id),
+ None,
+ is_mt_in_call)
+
+ tel_logger.set_result(result.result_value)
+
+ if not result:
+ log.error(
+ "Failed to make MO call from %s slot %s to %s slot %s",
+ ad_mo.serial, mo_slot, ad_mt.serial, mt_slot)
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": str(result.result_value)})
+
+ log.info("Step 5: Verify RAT and HTTP connection.")
+ if call_direction == "mo":
+ rat_list = [mo_rat[mo_slot], mo_rat[1-mo_slot]]
+ sub_id_list = [mo_sub_id, mo_other_sub_id]
+ else:
+ rat_list = [mt_rat[mt_slot], mt_rat[1-mt_slot]]
+ sub_id_list = [mt_sub_id, mt_other_sub_id]
+
+ # For the tese cases related to WFC in which airplane mode will be turned
+ # off in the end.
+ if turn_off_airplane_mode_in_the_end:
+ log.info("Step 5-1: Turning off airplane mode......")
+ if not toggle_airplane_mode(log, ads[0], False):
+ ads[0].log.error('Failed to toggle off airplane mode.')
+
+ # For the tese cases related to WFC in which Wi-Fi will be turned off in the
+ # end.
+ if turn_off_wifi_in_the_end:
+ log.info("Step 5-2: Turning off Wi-Fi......")
+ if not wifi_toggle_state(log, ads[0], False):
+ ads[0].log.error('Failed to toggle off Wi-Fi.')
+ return False
+
+ for index, value in enumerate(rat_list):
+ if value == '5g_wfc':
+ rat_list[index] = '5g'
+ elif value == 'wfc':
+ rat_list[index] = '4g'
+
+ for rat, sub_id in zip(rat_list, sub_id_list):
+ if not wait_for_network_idle(log, ads[0], rat, sub_id):
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Idle state of sub ID %s does not match the "
+ "given RAT %s." % (sub_id, rat)})
+
+
+def dsds_message_streaming_test(
+ log: tracelogger.TraceLogger,
+ ads: Sequence[AndroidDevice],
+ test_rat: list,
+ test_slot: int,
+ dds_slot: int,
+ msg_type: str = "SMS",
+ direction: str = "mt",
+ streaming: bool = True,
+ expected_result: bool = True) -> bool:
+ """Make MO and MT SMS/MMS at specific slot in specific RAT with DDS at
+ specific slot.
+
+ Test step:
+ 1. Get sub IDs of specific slots of both MO and MT devices.
+ 2. Switch DDS to specific slot.
+ 3. Check HTTP connection after DDS switch.
+ 4. Set up phones in desired RAT.
+ 5. Receive and Send SMS/MMS.
+
+ Args:
+ log: Logger object.
+ ads: A list of Android device objects.
+ test_rat: RAT for both slots of primary device.
+ test_slot: The slot which make/receive MO/MT SMS/MMS of primary device.
+ dds_slot: Preferred data slot of primary device.
+ msg_type: SMS or MMS to send.
+ direction: The direction of message("mo" or "mt") at first.
+ streaming: True for playing Youtube before send/receive SMS/MMS and
+ False on the contrary.
+ expected_result: True or False
+
+ Returns:
+ TestFailure if failed.
+ """
+ log.info("Step 1: Switch DDS.")
+ if not set_dds_on_slot(ads[0], dds_slot):
+ ads[0].log.error(
+ "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
+ return False
+
+ log.info("Step 2: Check HTTP connection after DDS switch.")
+ if not verify_http_connection(log, ads[0]):
+ ads[0].log.error("Failed to verify http connection.")
+ return False
+ else:
+ ads[0].log.info("Verify http connection successfully.")
+
+ log.info("Step 3: Set up phones in desired RAT.")
+ if direction == "mo":
+ # setup message subid on primary device.
+ ad_mo = ads[0]
+ mo_sub_id = get_subid_from_slot_index(log, ad_mo, test_slot)
+ if mo_sub_id == INVALID_SUB_ID:
+ ad_mo.log.warning("Failed to get sub ID at slot %s.", test_slot)
+ return False
+ mo_other_sub_id = get_subid_from_slot_index(
+ log, ad_mo, 1-test_slot)
+ sub_id_list = [mo_sub_id, mo_other_sub_id]
+ set_message_subid(ad_mo, mo_sub_id)
+ ad_mo.log.info("Sub ID for outgoing call at slot %s: %s", test_slot,
+ get_outgoing_message_sub_id(ad_mo))
+
+ # setup message subid on secondary device.
+ ad_mt = ads[1]
+ _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(ads, type="sms")
+ if mt_sub_id == INVALID_SUB_ID:
+ ad_mt.log.warning("Failed to get sub ID at default voice slot.")
+ return False
+ mt_slot = get_slot_index_from_subid(ad_mt, mt_sub_id)
+ set_message_subid(ad_mt, mt_sub_id)
+ ad_mt.log.info("Sub ID for incoming call at slot %s: %s", mt_slot,
+ get_outgoing_message_sub_id(ad_mt))
+
+ # setup the rat on non-test slot(primary device).
+ phone_setup_on_rat(
+ log,
+ ad_mo,
+ test_rat[1-test_slot],
+ mo_other_sub_id)
+ # assign phone setup argv for test slot.
+ mo_phone_setup_func_argv = (
+ log,
+ ad_mo,
+ test_rat[test_slot],
+ mo_sub_id)
+ else:
+ # setup message subid on primary device.
+ ad_mt = ads[0]
+ mt_sub_id = get_subid_from_slot_index(log, ad_mt, test_slot)
+ if mt_sub_id == INVALID_SUB_ID:
+ ad_mt.log.warning("Failed to get sub ID at slot %s.", test_slot)
+ return False
+ mt_other_sub_id = get_subid_from_slot_index(
+ log, ad_mt, 1-test_slot)
+ sub_id_list = [mt_sub_id, mt_other_sub_id]
+ set_message_subid(ad_mt, mt_sub_id)
+ ad_mt.log.info("Sub ID for incoming call at slot %s: %s", test_slot,
+ get_outgoing_message_sub_id(ad_mt))
+
+ # setup message subid on secondary device.
+ ad_mo = ads[1]
+ _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(ads, type="sms")
+ if mo_sub_id == INVALID_SUB_ID:
+ ad_mo.log.warning("Failed to get sub ID at default voice slot.")
+ return False
+ mo_slot = get_slot_index_from_subid(ad_mo, mo_sub_id)
+ set_message_subid(ad_mo, mo_sub_id)
+ ad_mo.log.info("Sub ID for outgoing call at slot %s: %s", mo_slot,
+ get_outgoing_message_sub_id(ad_mo))
+
+ # setup the rat on non-test slot(primary device).
+ phone_setup_on_rat(
+ log,
+ ad_mt,
+ test_rat[1-test_slot],
+ mt_other_sub_id)
+ # assign phone setup argv for test slot.
+ mt_phone_setup_func_argv = (
+ log,
+ ad_mt,
+ test_rat[test_slot],
+ mt_sub_id)
+ mo_phone_setup_func_argv = (log, ad_mo, 'general')
+
+ tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv),
+ (phone_setup_on_rat, mt_phone_setup_func_argv)]
+ if not multithread_func(log, tasks):
+ log.error("Phone Failed to Set Up Properly.")
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": "Phone Failed to Set Up Properly."})
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+
+ if streaming:
+ log.info("Step 4-0: Start Youtube streaming.")
+ if not start_youtube_video(ads[0]):
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": "Fail to bring up youtube video."})
+ time.sleep(10)
+
+ log.info("Step 4: Send %s.", msg_type)
+ if msg_type == "MMS":
+ for ad, current_data_sub_id, current_msg_sub_id in [
+ [ ads[0],
+ get_default_data_sub_id(ads[0]),
+ get_outgoing_message_sub_id(ads[0]) ],
+ [ ads[1],
+ get_default_data_sub_id(ads[1]),
+ get_outgoing_message_sub_id(ads[1]) ]]:
+ if current_data_sub_id != current_msg_sub_id:
+ ad.log.warning(
+ "Current data sub ID (%s) does not match message"
+ " sub ID (%s). MMS should NOT be sent.",
+ current_data_sub_id,
+ current_msg_sub_id)
+ expected_result = False
+
+ result_first = msim_message_test(log, ad_mo, ad_mt, mo_sub_id, mt_sub_id,
+ msg=msg_type, expected_result=expected_result)
+
+ if not result_first:
+ log_messaging_screen_shot(ad_mo, test_name="%s_tx" % msg_type)
+ log_messaging_screen_shot(ad_mt, test_name="%s_rx" % msg_type)
+
+ result_second = msim_message_test(log, ad_mt, ad_mo, mt_sub_id, mo_sub_id,
+ msg=msg_type, expected_result=expected_result)
+
+ if not result_second:
+ log_messaging_screen_shot(ad_mt, test_name="%s_tx" % msg_type)
+ log_messaging_screen_shot(ad_mo, test_name="%s_rx" % msg_type)
+
+ result = result_first and result_second
+
+ log.info("Step 5: Verify RAT and HTTP connection.")
+ rat_list = [test_rat[test_slot], test_rat[1-test_slot]]
+ for rat, sub_id in zip(rat_list, sub_id_list):
+ if not wait_for_network_idle(log, ads[0], rat, sub_id):
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Idle state of sub ID %s does not match the "
+ "given RAT %s." % (sub_id, rat)})
+
+ if streaming:
+ ads[0].force_stop_apk(YOUTUBE_PACKAGE_NAME)
+
+ return result
+
+
+def dsds_message_test(
+ log,
+ ads,
+ mo_slot,
+ mt_slot,
+ dds_slot,
+ msg="SMS",
+ mo_rat=["", ""],
+ mt_rat=["", ""],
+ direction="mo",
+ streaming=False,
+ expected_result=True):
+ """Make MO/MT SMS/MMS at specific slot in specific RAT with DDS at
+ specific slot.
+
+ Test step:
+ 1. Get sub IDs of specific slots of both MO and MT devices.
+ 2. Switch DDS to specific slot.
+ 3. Check HTTP connection after DDS switch.
+ 4. Set up phones in desired RAT.
+ 5. Send SMS/MMS.
+
+ Args:
+ mo_slot: Slot sending MO SMS (0 or 1)
+ mt_slot: Slot receiving MT SMS (0 or 1)
+ dds_slot: Preferred data slot
+ mo_rat: RAT for both slots of MO device
+ mt_rat: RAT for both slots of MT device
+ direction: "mo" or "mt"
+ streaming: True for playing Youtube before send/receive SMS/MMS and
+ False on the contrary.
+ expected_result: True or False
+
+ Returns:
+ TestFailure if failed.
+ """
+ if direction == "mo":
+ ad_mo = ads[0]
+ ad_mt = ads[1]
+ else:
+ ad_mo = ads[1]
+ ad_mt = ads[0]
+
+ if mo_slot is not None:
+ mo_sub_id = get_subid_from_slot_index(log, ad_mo, mo_slot)
+ if mo_sub_id == INVALID_SUB_ID:
+ ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot)
+ return False
+ mo_other_sub_id = get_subid_from_slot_index(
+ log, ad_mo, 1-mo_slot)
+ set_message_subid(ad_mo, mo_sub_id)
+ else:
+ _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(
+ ads, type="sms")
+ if mo_sub_id == INVALID_SUB_ID:
+ ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot)
+ return False
+ mo_slot = "auto"
+ set_message_subid(ad_mo, mo_sub_id)
+ if msg == "MMS":
+ set_subid_for_data(ad_mo, mo_sub_id)
+ ad_mo.droid.telephonyToggleDataConnection(True)
+ ad_mo.log.info("Sub ID for outgoing %s at slot %s: %s", msg, mo_slot,
+ get_outgoing_message_sub_id(ad_mo))
+
+ if mt_slot is not None:
+ mt_sub_id = get_subid_from_slot_index(log, ad_mt, mt_slot)
+ if mt_sub_id == INVALID_SUB_ID:
+ ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
+ return False
+ mt_other_sub_id = get_subid_from_slot_index(log, ad_mt, 1-mt_slot)
+ set_message_subid(ad_mt, mt_sub_id)
+ else:
+ _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(
+ ads, type="sms")
+ if mt_sub_id == INVALID_SUB_ID:
+ ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
+ return False
+ mt_slot = "auto"
+ set_message_subid(ad_mt, mt_sub_id)
+ if msg == "MMS":
+ set_subid_for_data(ad_mt, mt_sub_id)
+ ad_mt.droid.telephonyToggleDataConnection(True)
+ ad_mt.log.info("Sub ID for incoming %s at slot %s: %s", msg, mt_slot,
+ get_outgoing_message_sub_id(ad_mt))
+
+ log.info("Step 1: Switch DDS.")
+ if not set_dds_on_slot(ads[0], dds_slot):
+ log.error(
+ "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
+ return False
+
+ log.info("Step 2: Check HTTP connection after DDS switch.")
+ if not verify_http_connection(log, ads[0]):
+ log.error("Failed to verify http connection.")
+ return False
+ else:
+ log.info("Verify http connection successfully.")
+
+ if mo_slot == 0 or mo_slot == 1:
+ phone_setup_on_rat(log, ad_mo, mo_rat[1-mo_slot], mo_other_sub_id)
+ mo_phone_setup_func_argv = (log, ad_mo, mo_rat[mo_slot], mo_sub_id)
+ else:
+ mo_phone_setup_func_argv = (log, ad_mo, 'general', mo_sub_id)
+
+ if mt_slot == 0 or mt_slot == 1:
+ phone_setup_on_rat(log, ad_mt, mt_rat[1-mt_slot], mt_other_sub_id)
+ mt_phone_setup_func_argv = (log, ad_mt, mt_rat[mt_slot], mt_sub_id)
+ else:
+ mt_phone_setup_func_argv = (log, ad_mt, 'general', mt_sub_id)
+
+ log.info("Step 3: Set up phones in desired RAT.")
+ tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv),
+ (phone_setup_on_rat, mt_phone_setup_func_argv)]
+ if not multithread_func(log, tasks):
+ log.error("Phone Failed to Set Up Properly.")
+ return False
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+
+ if streaming:
+ log.info("Step 4: Start Youtube streaming.")
+ if not start_youtube_video(ads[0]):
+ log.warning("Fail to bring up youtube video")
+ time.sleep(10)
+ else:
+ log.info("Step 4: Skip Youtube streaming.")
+
+ log.info("Step 5: Send %s.", msg)
+ if msg == "MMS":
+ for ad, current_data_sub_id, current_msg_sub_id in [
+ [ ads[0],
+ get_default_data_sub_id(ads[0]),
+ get_outgoing_message_sub_id(ads[0]) ],
+ [ ads[1],
+ get_default_data_sub_id(ads[1]),
+ get_outgoing_message_sub_id(ads[1]) ]]:
+ if current_data_sub_id != current_msg_sub_id:
+ ad.log.warning(
+ "Current data sub ID (%s) does not match message"
+ " sub ID (%s). MMS should NOT be sent.",
+ current_data_sub_id,
+ current_msg_sub_id)
+ expected_result = False
+
+ result = msim_message_test(log, ad_mo, ad_mt, mo_sub_id, mt_sub_id,
+ msg=msg, expected_result=expected_result)
+
+ if not result:
+ log_messaging_screen_shot(ad_mo, test_name="%s_tx" % msg)
+ log_messaging_screen_shot(ad_mt, test_name="%s_rx" % msg)
+
+ if streaming:
+ ads[0].force_stop_apk(YOUTUBE_PACKAGE_NAME)
+ return result
+
+
+def dds_switch_during_data_transfer_test(
+ log,
+ tel_logger,
+ ads,
+ nw_rat=["volte", "volte"],
+ call_slot=0,
+ call_direction=None,
+ call_or_sms_or_mms="call",
+ streaming=True,
+ is_airplane_mode=False,
+ wfc_mode=[WFC_MODE_CELLULAR_PREFERRED, WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=None,
+ wifi_network_pass=None):
+ """Switch DDS and make voice call(VoLTE/WFC/CS call)/SMS/MMS together with
+ Youtube playing after each DDS switch at specific slot in specific RAT.
+
+ Test step:
+ 1. Get sub ID of each slot of the primary device.
+ 2. Set up phones in desired RAT.
+ 3. Switch DDS to slot 0.
+ 4. Check HTTP connection after DDS switch.
+ 5. Play Youtube.
+ 6. Make voice call (VoLTE/WFC/CS call)/SMS/MMS
+ 7. Switch DDS to slot 1 and repeat step 4-6.
+ 8. Switch DDS to slot 0 again and repeat step 4-6.
+
+ Args:
+ log: logger object
+ tel_logger: logger object for telephony proto
+ ads: list of android devices
+ nw_rat: RAT for both slots of the primary device
+ call_slot: Slot for making voice call
+ call_direction: "mo" or "mt" or None to stoping making call.
+ call_or_sms_or_mms: Voice call or SMS or MMS
+ streaming: True for playing Youtube after DDS switch and False on the contrary.
+ is_airplane_mode: True or False for WFC setup
+ wfc_mode: Cellular preferred or Wi-Fi preferred.
+ wifi_network_ssid: SSID of Wi-Fi AP
+ wifi_network_pass: Password of Wi-Fi AP SSID
+
+ Returns:
+ TestFailure if failed.
+ """
+ ad = ads[0]
+ slot_0_subid = get_subid_from_slot_index(log, ad, 0)
+ slot_1_subid = get_subid_from_slot_index(log, ad, 1)
+
+ if slot_0_subid == INVALID_SUB_ID or slot_1_subid == INVALID_SUB_ID:
+ ad.log.error("Not all slots have valid sub ID.")
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": "Not all slots have valid sub ID"})
+
+ ad.log.info(
+ "Step 0: Set up phone in desired RAT (slot 0: %s, slot 1: %s)",
+ nw_rat[0], nw_rat[1])
+
+ if not phone_setup_on_rat(
+ log,
+ ad,
+ nw_rat[0],
+ slot_0_subid,
+ is_airplane_mode,
+ wfc_mode[0],
+ wifi_network_ssid,
+ wifi_network_pass):
+ log.error("Phone Failed to Set Up Properly.")
+ tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": "Phone Failed to Set Up Properly."})
+
+ if not phone_setup_on_rat(
+ log,
+ ad,
+ nw_rat[1],
+ slot_1_subid,
+ is_airplane_mode,
+ wfc_mode[1],
+ wifi_network_ssid,
+ wifi_network_pass):
+ log.error("Phone Failed to Set Up Properly.")
+ tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": "Phone Failed to Set Up Properly."})
+
+ is_slot0_in_call = is_phone_in_call_on_rat(
+ log, ad, nw_rat[0], True)
+ is_slot1_in_call = is_phone_in_call_on_rat(
+ log, ad, nw_rat[1], True)
+
+ for attempt in range(3):
+ if attempt != 0:
+ ad.log.info("Repeat step 1 to 4.")
+
+ ad.log.info("Step 1: Switch DDS.")
+ if attempt % 2 == 0:
+ set_dds_on_slot(ad, 0)
+ else:
+ set_dds_on_slot(ad, 1)
+
+ ad.log.info("Step 2: Check HTTP connection after DDS switch.")
+ if not verify_http_connection(log, ad):
+ ad.log.error("Failed to verify http connection.")
+ return False
+ else:
+ ad.log.info("Verify http connection successfully.")
+
+ if streaming:
+ ad.log.info("Step 3: Start Youtube streaming.")
+ if not start_youtube_video(ad):
+ ad.log.warning("Fail to bring up youtube video")
+ time.sleep(10)
+ else:
+ ad.log.info("Step 3: Skip Youtube streaming.")
+
+ if not call_direction:
+ return True
+ else:
+ expected_result = True
+ if call_direction == "mo":
+ ad_mo = ads[0]
+ ad_mt = ads[1]
+ phone_setup_on_rat(log, ad_mt, 'general')
+ mo_sub_id = get_subid_from_slot_index(log, ad, call_slot)
+ if call_or_sms_or_mms == "call":
+ set_voice_sub_id(ad_mo, mo_sub_id)
+ _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(
+ ads)
+
+ if call_slot == 0:
+ is_mo_in_call = is_slot0_in_call
+ elif call_slot == 1:
+ is_mo_in_call = is_slot1_in_call
+ is_mt_in_call = None
+
+ elif call_or_sms_or_mms == "sms":
+ set_message_subid(ad_mo, mo_sub_id)
+ _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(
+ ads, type="sms")
+ set_message_subid(ad_mt, mt_sub_id)
+
+ elif call_or_sms_or_mms == "mms":
+ current_data_sub_id = get_default_data_sub_id(ad_mo)
+ if mo_sub_id != current_data_sub_id:
+ ad_mo.log.warning(
+ "Current data sub ID (%s) does not match"
+ " message sub ID (%s). MMS should NOT be sent.",
+ current_data_sub_id, mo_sub_id)
+ expected_result = False
+ set_message_subid(ad_mo, mo_sub_id)
+ _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(
+ ads, type="sms")
+ set_message_subid(ad_mt, mt_sub_id)
+ set_subid_for_data(ad_mt, mt_sub_id)
+ ad_mt.droid.telephonyToggleDataConnection(True)
+
+ elif call_direction == "mt":
+ ad_mo = ads[1]
+ ad_mt = ads[0]
+ phone_setup_on_rat(log, ad_mo, 'general')
+ mt_sub_id = get_subid_from_slot_index(log, ad, call_slot)
+ if call_or_sms_or_mms == "call":
+ set_voice_sub_id(ad_mt, mt_sub_id)
+ _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(
+ ads)
+
+ if call_slot == 0:
+ is_mt_in_call = is_slot0_in_call
+ elif call_slot == 1:
+ is_mt_in_call = is_slot1_in_call
+ is_mo_in_call = None
+
+ elif call_or_sms_or_mms == "sms":
+ set_message_subid(ad_mt, mt_sub_id)
+ _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(
+ ads, type="sms")
+ set_message_subid(ad_mo, mo_sub_id)
+
+ elif call_or_sms_or_mms == "mms":
+ current_data_sub_id = get_default_data_sub_id(ad_mt)
+ if mt_sub_id != current_data_sub_id:
+ ad_mt.log.warning(
+ "Current data sub ID (%s) does not match"
+ " message sub ID (%s). MMS should NOT be"
+ " received.", current_data_sub_id, mt_sub_id)
+ expected_result = False
+ set_message_subid(ad_mt, mt_sub_id)
+ _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(
+ ads, type="sms")
+ set_message_subid(ad_mo, mo_sub_id)
+ set_subid_for_data(ad_mo, mo_sub_id)
+ ad_mo.droid.telephonyToggleDataConnection(True)
+
+ if call_or_sms_or_mms == "call":
+ log.info("Step 4: Make voice call.")
+ mo_slot = get_slot_index_from_subid(ad_mo, mo_sub_id)
+ mt_slot = get_slot_index_from_subid(ad_mt, mt_sub_id)
+ result = two_phone_call_msim_for_slot(
+ log,
+ ad_mo,
+ mo_slot,
+ None,
+ is_mo_in_call,
+ ad_mt,
+ mt_slot,
+ None,
+ is_mt_in_call)
+ tel_logger.set_result(result.result_value)
+
+ if not result:
+ log.error(
+ "Failed to make MO call from %s slot %s to %s"
+ " slot %s", ad_mo.serial, mo_slot, ad_mt.serial,
+ mt_slot)
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": str(result.result_value)})
+ else:
+ log.info("Step 4: Send %s.", call_or_sms_or_mms)
+ if call_or_sms_or_mms == "sms":
+ result = msim_message_test(
+ ad_mo,
+ ad_mt,
+ mo_sub_id,
+ mt_sub_id,
+ msg=call_or_sms_or_mms.upper())
+ elif call_or_sms_or_mms == "mms":
+ result = msim_message_test(
+ ad_mo,
+ ad_mt,
+ mo_sub_id,
+ mt_sub_id,
+ msg=call_or_sms_or_mms.upper(),
+ expected_result=expected_result)
+ if not result:
+ log_messaging_screen_shot(
+ ad_mo, test_name="%s_tx" % call_or_sms_or_mms)
+ log_messaging_screen_shot(
+ ad_mt, test_name="%s_rx" % call_or_sms_or_mms)
+ return False
+ if streaming:
+ ad.force_stop_apk(YOUTUBE_PACKAGE_NAME)
+ return True
+
+
+def enable_slot_after_voice_call_test(
+ log,
+ tel_logger,
+ ads,
+ mo_slot,
+ mt_slot,
+ disabled_slot,
+ mo_rat=["", ""],
+ mt_rat=["", ""],
+ call_direction="mo"):
+ """Disable/enable pSIM or eSIM with voice call
+
+ Test step:
+ 1. Get sub IDs of specific slots of both MO and MT devices.
+ 2. Set up phones in desired RAT.
+ 3. Disable assigned slot.
+ 4. Switch DDS to the other slot.
+ 5. Verify RAT and HTTP connection after DDS switch.
+ 6. Make voice call.
+ 7. Enable assigned slot.
+ 8. Switch DDS to the assigned slot.
+ 9. Verify RAT and HTTP connection after DDS switch.
+
+ Args:
+ log: logger object
+ tel_logger: logger object for telephony proto
+ ads: list of android devices
+ mo_slot: Slot making MO call (0 or 1)
+ mt_slot: Slot receiving MT call (0 or 1)
+ disabled_slot: slot to be disabled/enabled
+ mo_rat: RAT for both slots of MO device
+ mt_rat: RAT for both slots of MT device
+ call_direction: "mo" or "mt"
+
+ Returns:
+ TestFailure if failed.
+ """
+ if call_direction == "mo":
+ ad_mo = ads[0]
+ ad_mt = ads[1]
+ else:
+ ad_mo = ads[1]
+ ad_mt = ads[0]
+
+ if mo_slot is not None:
+ mo_sub_id = get_subid_from_slot_index(log, ad_mo, mo_slot)
+ if mo_sub_id == INVALID_SUB_ID:
+ ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot)
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Failed to get sub ID at slot %s." % mo_slot})
+ mo_other_sub_id = get_subid_from_slot_index(
+ log, ad_mo, 1-mo_slot)
+ set_voice_sub_id(ad_mo, mo_sub_id)
+ else:
+ _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
+ if mo_sub_id == INVALID_SUB_ID:
+ ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot)
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Failed to get sub ID at slot %s." % mo_slot})
+ mo_slot = "auto"
+ set_voice_sub_id(ad_mo, mo_sub_id)
+ ad_mo.log.info("Sub ID for outgoing call at slot %s: %s",
+ mo_slot, get_outgoing_voice_sub_id(ad_mo))
+
+ if mt_slot is not None:
+ mt_sub_id = get_subid_from_slot_index(log, ad_mt, mt_slot)
+ if mt_sub_id == INVALID_SUB_ID:
+ ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Failed to get sub ID at slot %s." % mt_slot})
+ mt_other_sub_id = get_subid_from_slot_index(
+ log, ad_mt, 1-mt_slot)
+ set_voice_sub_id(ad_mt, mt_sub_id)
+ else:
+ _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
+ if mt_sub_id == INVALID_SUB_ID:
+ ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Failed to get sub ID at slot %s." % mt_slot})
+ mt_slot = "auto"
+ set_voice_sub_id(ad_mt, mt_sub_id)
+ ad_mt.log.info("Sub ID for incoming call at slot %s: %s", mt_slot,
+ get_incoming_voice_sub_id(ad_mt))
+
+ if mo_slot == 0 or mo_slot == 1:
+ phone_setup_on_rat(log, ad_mo, mo_rat[1-mo_slot], mo_other_sub_id)
+ mo_phone_setup_func_argv = (log, ad_mo, mo_rat[mo_slot], mo_sub_id)
+ is_mo_in_call = is_phone_in_call_on_rat(
+ log, ad_mo, mo_rat[mo_slot], only_return_fn=True)
+ else:
+ mo_phone_setup_func_argv = (log, ad_mo, 'general')
+ is_mo_in_call = is_phone_in_call_on_rat(
+ log, ad_mo, 'general', only_return_fn=True)
+
+ if mt_slot == 0 or mt_slot == 1:
+ phone_setup_on_rat(log, ad_mt, mt_rat[1-mt_slot], mt_other_sub_id)
+ mt_phone_setup_func_argv = (log, ad_mt, mt_rat[mt_slot], mt_sub_id)
+ is_mt_in_call = is_phone_in_call_on_rat(
+ log, ad_mt, mt_rat[mt_slot], only_return_fn=True)
+ else:
+ mt_phone_setup_func_argv = (log, ad_mt, 'general')
+ is_mt_in_call = is_phone_in_call_on_rat(
+ log, ad_mt, 'general', only_return_fn=True)
+
+ log.info("Step 1: Set up phones in desired RAT.")
+ tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv),
+ (phone_setup_on_rat, mt_phone_setup_func_argv)]
+ if not multithread_func(log, tasks):
+ log.error("Phone Failed to Set Up Properly.")
+ tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Phone Failed to Set Up Properly."})
+
+ log.info("Step 2: Disable slot %s.", disabled_slot)
+ if not power_off_sim(ads[0], disabled_slot):
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Failed to disable slot %s." % disabled_slot})
+
+ log.info("Step 3: Switch DDS.")
+ if not set_dds_on_slot(ads[0], 1-disabled_slot):
+ log.error(
+ "Failed to set DDS at slot %s on %s.",
+ (1-disabled_slot, ads[0].serial))
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Failed to set DDS at slot %s on %s." % (
+ 1-disabled_slot, ads[0].serial)})
+
+ log.info("Step 4: Verify RAT and HTTP connection after DDS switch.")
+ if mo_slot == 0 or mo_slot == 1:
+ if not wait_for_network_idle(
+ log, ad_mo, mo_rat[1-disabled_slot], mo_sub_id):
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Idle state does not match the given "
+ "RAT %s." % mo_rat[1-disabled_slot]})
+
+ if mt_slot == 0 or mt_slot == 1:
+ if not wait_for_network_idle(
+ log, ad_mt, mt_rat[1-disabled_slot], mt_sub_id):
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Idle state does not match the given "
+ "RAT %s." % mt_rat[1-disabled_slot]})
+
+ if not verify_http_connection(log, ads[0]):
+ log.error("Failed to verify http connection.")
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Failed to verify http connection."})
+ else:
+ log.info("Verify http connection successfully.")
+
+ log.info("Step 5: Make voice call.")
+ result = two_phone_call_msim_for_slot(
+ log,
+ ad_mo,
+ get_slot_index_from_subid(ad_mo, mo_sub_id),
+ None,
+ is_mo_in_call,
+ ad_mt,
+ get_slot_index_from_subid(ad_mt, mt_sub_id),
+ None,
+ is_mt_in_call)
+
+ tel_logger.set_result(result.result_value)
+
+ if not result:
+ log.error(
+ "Failed to make MO call from %s slot %s to %s slot %s",
+ ad_mo.serial, mo_slot, ad_mt.serial, mt_slot)
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": str(result.result_value)})
+
+ log.info("Step 6: Enable slot %s.", disabled_slot)
+ if not power_on_sim(ads[0], disabled_slot):
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Failed to enable slot %s." % disabled_slot})
+
+ log.info("Step 7: Switch DDS to slot %s.", disabled_slot)
+ if not set_dds_on_slot(ads[0], disabled_slot):
+ log.error(
+ "Failed to set DDS at slot %s on %s.",(disabled_slot, ads[0].serial))
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Failed to set DDS at slot %s on %s." % (
+ disabled_slot, ads[0].serial)})
+
+ log.info("Step 8: Verify RAT and HTTP connection after DDS switch.")
+ if mo_slot == 0 or mo_slot == 1:
+ if not wait_for_network_idle(
+ log, ad_mo, mo_rat[disabled_slot], mo_other_sub_id):
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Idle state does not match the given "
+ "RAT %s." % mo_rat[mo_slot]})
+
+ if mt_slot == 0 or mt_slot == 1:
+ if not wait_for_network_idle(
+ log, ad_mt, mt_rat[disabled_slot], mt_other_sub_id):
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Idle state does not match the given "
+ "RAT %s." % mt_rat[mt_slot]})
+
+ if not verify_http_connection(log, ads[0]):
+ log.error("Failed to verify http connection.")
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Failed to verify http connection."})
+ else:
+ log.info("Verify http connection successfully.")
+
+
+def enable_slot_after_data_call_test(
+ log,
+ ad,
+ disabled_slot,
+ rat=["", ""]):
+ """Disable/enable pSIM or eSIM with data call
+
+ Test step:
+ 1. Get sub IDs of specific slots of both MO and MT devices.
+ 2. Set up phones in desired RAT.
+ 3. Disable assigned slot.
+ 4. Switch DDS to the other slot.
+ 5. Verify RAT and HTTP connection after DDS switch.
+ 6. Make a data call by http download.
+ 7. Enable assigned slot.
+ 8. Switch DDS to the assigned slot.
+ 9. Verify RAT and HTTP connection after DDS switch.
+
+ Args:
+ log: logger object
+ ads: list of android devices
+ disabled_slot: slot to be disabled/enabled
+ mo_rat: RAT for both slots of MO device
+ mt_rat: RAT for both slots of MT device
+
+ Returns:
+ TestFailure if failed.
+ """
+ data_sub_id = get_subid_from_slot_index(log, ad, 1-disabled_slot)
+ if data_sub_id == INVALID_SUB_ID:
+ ad.log.warning("Failed to get sub ID at slot %s.", 1-disabled_slot)
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Failed to get sub ID at slot %s." % (
+ 1-disabled_slot)})
+ other_sub_id = get_subid_from_slot_index(log, ad, disabled_slot)
+
+ log.info("Step 1: Set up phones in desired RAT.")
+ if not phone_setup_on_rat(log, ad, rat[1-disabled_slot], data_sub_id):
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Phone Failed to Set Up Properly."})
+
+ if not phone_setup_on_rat(log, ad, rat[disabled_slot], other_sub_id):
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Phone Failed to Set Up Properly."})
+
+ log.info("Step 2: Disable slot %s.", disabled_slot)
+ if not power_off_sim(ad, disabled_slot):
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Failed to disable slot %s." % disabled_slot})
+
+ log.info("Step 3: Switch DDS.")
+ if not set_dds_on_slot(ad, 1-disabled_slot):
+ log.error(
+ "Failed to set DDS at slot %s on %s.",(1-disabled_slot, ad.serial))
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Failed to set DDS at slot %s on %s." % (
+ 1-disabled_slot, ad.serial)})
+
+ log.info("Step 4: Verify RAT and HTTP connection after DDS switch.")
+ if not wait_for_network_idle(log, ad, rat[1-disabled_slot], data_sub_id):
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Idle state does not match the given "
+ "RAT %s." % rat[1-disabled_slot]})
+
+ if not verify_http_connection(log, ad):
+ log.error("Failed to verify http connection.")
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": "Failed to verify http connection."})
+ else:
+ log.info("Verify http connection successfully.")
+
+ duration = 30
+ start_time = datetime.now()
+ while datetime.now() - start_time <= timedelta(seconds=duration):
+ if not active_file_download_test(
+ log, ad, file_name='20MB', method='sl4a'):
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Failed to download by sl4a."})
+
+ log.info("Step 6: Enable slot %s.", disabled_slot)
+ if not power_on_sim(ad, disabled_slot):
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Failed to enable slot %s." % disabled_slot})
+
+ log.info("Step 7: Switch DDS to slot %s.", disabled_slot)
+ if not set_dds_on_slot(ad, disabled_slot):
+ log.error(
+ "Failed to set DDS at slot %s on %s.",(disabled_slot, ad.serial))
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Failed to set DDS at slot %s on %s." % (
+ disabled_slot, ad.serial)})
+
+ log.info("Step 8: Verify RAT and HTTP connection after DDS switch.")
+ if not wait_for_network_idle(log, ad, rat[disabled_slot], other_sub_id):
+ raise signals.TestFailure(
+ "Failed",
+ extras={
+ "fail_reason": "Idle state does not match the given "
+ "RAT %s." % rat[disabled_slot]})
+
+ if not verify_http_connection(log, ad):
+ log.error("Failed to verify http connection.")
+ raise signals.TestFailure(
+ "Failed",
+ extras={"fail_reason": "Failed to verify http connection."})
+ else:
+ log.info("Verify http connection successfully.")
+
+
+def erase_call_forwarding(log, ad):
+ slot0_sub_id = get_subid_from_slot_index(log, ad, 0)
+ slot1_sub_id = get_subid_from_slot_index(log, ad, 1)
+ current_voice_sub_id = get_incoming_voice_sub_id(ad)
+ for sub_id in (slot0_sub_id, slot1_sub_id):
+ set_voice_sub_id(ad, sub_id)
+ get_operator_name(log, ad, sub_id)
+ erase_call_forwarding_by_mmi(log, ad)
+ set_voice_sub_id(ad, current_voice_sub_id)
+
+
+def three_way_calling_mo_and_mt_with_hangup_once(
+ log,
+ ads,
+ phone_setups,
+ verify_funcs,
+ reject_once=False):
+ """Use 3 phones to make MO call and MT call.
+
+ Call from PhoneA to PhoneB, accept on PhoneB.
+ Call from PhoneC to PhoneA, accept on PhoneA.
+
+ Args:
+ ads: list of ad object.
+ The list should have three objects.
+ phone_setups: list of phone setup functions.
+ The list should have three objects.
+ verify_funcs: list of phone call verify functions.
+ The list should have three objects.
+
+ Returns:
+ If success, return 'call_AB' id in PhoneA.
+ if fail, return None.
+ """
+
+ class _CallException(Exception):
+ pass
+
+ try:
+ verify_func_a, verify_func_b, verify_func_c = verify_funcs
+ tasks = []
+ for ad, setup_func in zip(ads, phone_setups):
+ if setup_func is not None:
+ tasks.append((setup_func, (log, ad, get_incoming_voice_sub_id(ad))))
+ if tasks != [] and not multithread_func(log, tasks):
+ log.error("Phone Failed to Set Up Properly.")
+ raise _CallException("Setup failed.")
+ for ad in ads:
+ ad.droid.telecomCallClearCallList()
+ if num_active_calls(log, ad) != 0:
+ ad.log.error("Phone Call List is not empty.")
+ raise _CallException("Clear call list failed.")
+
+ log.info("Step1: Call From PhoneA to PhoneB.")
+ if not call_setup_teardown(
+ log,
+ ads[0],
+ ads[1],
+ ad_hangup=None,
+ verify_caller_func=verify_func_a,
+ verify_callee_func=verify_func_b):
+ raise _CallException("PhoneA call PhoneB failed.")
+
+ calls = ads[0].droid.telecomCallGetCallIds()
+ ads[0].log.info("Calls in PhoneA %s", calls)
+ if num_active_calls(log, ads[0]) != 1:
+ raise _CallException("Call list verify failed.")
+ call_ab_id = calls[0]
+
+ log.info("Step2: Call From PhoneC to PhoneA.")
+ if reject_once:
+ log.info("Step2-1: Reject incoming call once.")
+ if not initiate_call(
+ log,
+ ads[2],
+ ads[0].telephony['subscription'][get_incoming_voice_sub_id(
+ ads[0])]['phone_num']):
+ ads[2].log.error("Initiate call failed.")
+ raise _CallException("Failed to initiate call.")
+
+ if not wait_and_reject_call_for_subscription(
+ log,
+ ads[0],
+ get_incoming_voice_sub_id(ads[0]),
+ incoming_number= \
+ ads[2].telephony['subscription'][
+ get_incoming_voice_sub_id(
+ ads[2])]['phone_num']):
+ ads[0].log.error("Reject call fail.")
+ raise _CallException("Failed to reject call.")
+
+ hangup_call(log, ads[2])
+ time.sleep(15)
+
+ if not call_setup_teardown(
+ log,
+ ads[2],
+ ads[0],
+ ad_hangup=None,
+ verify_caller_func=verify_func_c,
+ verify_callee_func=verify_func_a):
+ raise _CallException("PhoneA call PhoneC failed.")
+ if not verify_incall_state(log, [ads[0], ads[1], ads[2]],
+ True):
+ raise _CallException("Not All phones are in-call.")
+
+ except Exception as e:
+ setattr(ads[0], "exception", e)
+ return None
+
+ return call_ab_id
+
+
+def msim_message_test(
+ log,
+ ad_mo,
+ ad_mt,
+ mo_sub_id,
+ mt_sub_id, msg="SMS",
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
+ expected_result=True):
+ """Make MO/MT SMS/MMS at specific slot.
+
+ Args:
+ ad_mo: Android object of the device sending SMS/MMS
+ ad_mt: Android object of the device receiving SMS/MMS
+ mo_sub_id: Sub ID of MO device
+ mt_sub_id: Sub ID of MT device
+ max_wait_time: Max wait time before SMS/MMS is received.
+ expected_result: True for successful sending/receiving and False on
+ the contrary
+
+ Returns:
+ True if the result matches expected_result and False on the
+ contrary.
+ """
+ message_lengths = (50, 160, 180)
+ if msg == "SMS":
+ for length in message_lengths:
+ message_array = [rand_ascii_str(length)]
+ if not sms_send_receive_verify_for_subscription(
+ log,
+ ad_mo,
+ ad_mt,
+ mo_sub_id,
+ mt_sub_id,
+ message_array,
+ max_wait_time):
+ ad_mo.log.warning(
+ "%s of length %s test failed", msg, length)
+ return False
+ else:
+ ad_mo.log.info(
+ "%s of length %s test succeeded", msg, length)
+ log.info("%s test of length %s characters succeeded.",
+ msg, message_lengths)
+
+ elif msg == "MMS":
+ for length in message_lengths:
+ message_array = [("Test Message", rand_ascii_str(length), None)]
+
+ if not mms_send_receive_verify(
+ log,
+ ad_mo,
+ ad_mt,
+ message_array,
+ max_wait_time,
+ expected_result):
+ log.warning("%s of body length %s test failed",
+ msg, length)
+ return False
+ else:
+ log.info(
+ "%s of body length %s test succeeded", msg, length)
+ log.info("%s test of body lengths %s succeeded",
+ msg, message_lengths)
+ return True
+
+
+def msim_call_forwarding(
+ log,
+ tel_logger,
+ ads,
+ caller_slot,
+ callee_slot,
+ forwarded_callee_slot,
+ dds_slot,
+ caller_rat=["", ""],
+ callee_rat=["", ""],
+ forwarded_callee_rat=["", ""],
+ call_forwarding_type="unconditional"):
+ """Make MO voice call to the primary device at specific slot in specific
+ RAT with DDS at specific slot, and then forwarded to 3rd device with
+ specific call forwarding type.
+
+ Test step:
+ 1. Get sub IDs of specific slots of both MO and MT devices.
+ 2. Switch DDS to specific slot.
+ 3. Check HTTP connection after DDS switch.
+ 4. Set up phones in desired RAT.
+ 5. Register and enable call forwarding with specifc type.
+ 5. Make voice call to the primary device and wait for being forwarded
+ to 3rd device.
+
+ Args:
+ log: logger object
+ tel_logger: logger object for telephony proto
+ ads: list of android devices
+ caller_slot: Slot of 2nd device making MO call (0 or 1)
+ callee_slot: Slot of primary device receiving and forwarding MT call
+ (0 or 1)
+ forwarded_callee_slot: Slot of 3rd device receiving forwarded call.
+ dds_slot: Preferred data slot
+ caller_rat: RAT for both slots of the 2nd device
+ callee_rat: RAT for both slots of the primary device
+ forwarded_callee_rat: RAT for both slots of the 3rd device
+ call_forwarding_type:
+ "unconditional"
+ "busy"
+ "not_answered"
+ "not_reachable"
+
+ Returns:
+ True or False
+ """
+ ad_caller = ads[1]
+ ad_callee = ads[0]
+ ad_forwarded_callee = ads[2]
+
+ if callee_slot is not None:
+ callee_sub_id = get_subid_from_slot_index(
+ log, ad_callee, callee_slot)
+ if callee_sub_id == INVALID_SUB_ID:
+ ad_callee.log.warning(
+ "Failed to get sub ID at slot %s.", callee_slot)
+ return False
+ callee_other_sub_id = get_subid_from_slot_index(
+ log, ad_callee, 1-callee_slot)
+ set_voice_sub_id(ad_callee, callee_sub_id)
+ else:
+ callee_sub_id, _, _ = get_subid_on_same_network_of_host_ad(ads)
+ if callee_sub_id == INVALID_SUB_ID:
+ ad_callee.log.warning(
+ "Failed to get sub ID at slot %s.", callee_slot)
+ return False
+ callee_slot = "auto"
+ set_voice_sub_id(ad_callee, callee_sub_id)
+ ad_callee.log.info(
+ "Sub ID for incoming call at slot %s: %s",
+ callee_slot, get_incoming_voice_sub_id(ad_callee))
+
+ if caller_slot is not None:
+ caller_sub_id = get_subid_from_slot_index(
+ log, ad_caller, caller_slot)
+ if caller_sub_id == INVALID_SUB_ID:
+ ad_caller.log.warning(
+ "Failed to get sub ID at slot %s.", caller_slot)
+ return False
+ caller_other_sub_id = get_subid_from_slot_index(
+ log, ad_caller, 1-caller_slot)
+ set_voice_sub_id(ad_caller, caller_sub_id)
+ else:
+ _, caller_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
+ if caller_sub_id == INVALID_SUB_ID:
+ ad_caller.log.warning(
+ "Failed to get sub ID at slot %s.", caller_slot)
+ return False
+ caller_slot = "auto"
+ set_voice_sub_id(ad_caller, caller_sub_id)
+ ad_caller.log.info(
+ "Sub ID for outgoing call at slot %s: %s",
+ caller_slot, get_outgoing_voice_sub_id(ad_caller))
+
+ if forwarded_callee_slot is not None:
+ forwarded_callee_sub_id = get_subid_from_slot_index(
+ log, ad_forwarded_callee, forwarded_callee_slot)
+ if forwarded_callee_sub_id == INVALID_SUB_ID:
+ ad_forwarded_callee.log.warning(
+ "Failed to get sub ID at slot %s.", forwarded_callee_slot)
+ return False
+ forwarded_callee_other_sub_id = get_subid_from_slot_index(
+ log, ad_forwarded_callee, 1-forwarded_callee_slot)
+ set_voice_sub_id(
+ ad_forwarded_callee, forwarded_callee_sub_id)
+ else:
+ _, _, forwarded_callee_sub_id = \
+ get_subid_on_same_network_of_host_ad(ads)
+ if forwarded_callee_sub_id == INVALID_SUB_ID:
+ ad_forwarded_callee.log.warning(
+ "Failed to get sub ID at slot %s.", forwarded_callee_slot)
+ return False
+ forwarded_callee_slot = "auto"
+ set_voice_sub_id(
+ ad_forwarded_callee, forwarded_callee_sub_id)
+ ad_forwarded_callee.log.info(
+ "Sub ID for incoming call at slot %s: %s",
+ forwarded_callee_slot,
+ get_incoming_voice_sub_id(ad_forwarded_callee))
+
+ log.info("Step 1: Switch DDS.")
+ if not set_dds_on_slot(ads[0], dds_slot):
+ log.error(
+ "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
+ return False
+
+ log.info("Step 2: Check HTTP connection after DDS switch.")
+ if not verify_http_connection(log, ads[0]):
+ log.error("Failed to verify http connection.")
+ return False
+ else:
+ log.info("Verify http connection successfully.")
+
+ if caller_slot == 1:
+ phone_setup_on_rat(
+ log,
+ ad_caller,
+ caller_rat[0],
+ caller_other_sub_id)
+
+ elif caller_slot == 0:
+ phone_setup_on_rat(
+ log,
+ ad_caller,
+ caller_rat[1],
+ caller_other_sub_id)
+ else:
+ phone_setup_on_rat(
+ log,
+ ad_caller,
+ 'general')
+
+ if callee_slot == 1:
+ phone_setup_on_rat(
+ log,
+ ad_callee,
+ callee_rat[0],
+ callee_other_sub_id)
+
+ elif callee_slot == 0:
+ phone_setup_on_rat(
+ log,
+ ad_callee,
+ callee_rat[1],
+ callee_other_sub_id)
+ else:
+ phone_setup_on_rat(
+ log,
+ ad_callee,
+ 'general')
+
+ if forwarded_callee_slot == 1:
+ phone_setup_on_rat(
+ log,
+ ad_forwarded_callee,
+ forwarded_callee_rat[0],
+ forwarded_callee_other_sub_id)
+
+ elif forwarded_callee_slot == 0:
+ phone_setup_on_rat(
+ log,
+ ad_forwarded_callee,
+ forwarded_callee_rat[1],
+ forwarded_callee_other_sub_id)
+ else:
+ phone_setup_on_rat(
+ log,
+ ad_forwarded_callee,
+ 'general')
+
+ if caller_slot == 0 or caller_slot == 1:
+ caller_phone_setup_func_argv = (log, ad_caller, caller_rat[caller_slot], caller_sub_id)
+ else:
+ caller_phone_setup_func_argv = (log, ad_caller, 'general')
+
+ callee_phone_setup_func_argv = (log, ad_callee, callee_rat[callee_slot], callee_sub_id)
+
+ if forwarded_callee_slot == 0 or forwarded_callee_slot == 1:
+ forwarded_callee_phone_setup_func_argv = (
+ log,
+ ad_forwarded_callee,
+ forwarded_callee_rat[forwarded_callee_slot],
+ forwarded_callee_sub_id)
+ else:
+ forwarded_callee_phone_setup_func_argv = (
+ log,
+ ad_forwarded_callee,
+ 'general')
+
+ log.info("Step 3: Set up phones in desired RAT.")
+ tasks = [(phone_setup_on_rat, caller_phone_setup_func_argv),
+ (phone_setup_on_rat, callee_phone_setup_func_argv),
+ (phone_setup_on_rat,
+ forwarded_callee_phone_setup_func_argv)]
+ if not multithread_func(log, tasks):
+ log.error("Phone Failed to Set Up Properly.")
+ tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": "Phone Failed to Set Up Properly."})
+
+ is_callee_in_call = is_phone_in_call_on_rat(
+ log, ad_callee, callee_rat[callee_slot], only_return_fn=True)
+
+ is_call_waiting = re.search(
+ "call_waiting (True (\d)|False)", call_forwarding_type, re.I)
+ if is_call_waiting:
+ if is_call_waiting.group(1) == "False":
+ call_waiting = False
+ scenario = None
+ else:
+ call_waiting = True
+ scenario = int(is_call_waiting.group(2))
+
+ log.info(
+ "Step 4: Make voice call with call waiting enabled = %s.",
+ call_waiting)
+ result = three_phone_call_waiting_short_seq(
+ log,
+ ads[0],
+ None,
+ is_callee_in_call,
+ ads[1],
+ ads[2],
+ call_waiting=call_waiting, scenario=scenario)
+ else:
+ log.info(
+ "Step 4: Make voice call with call forwarding %s.",
+ call_forwarding_type)
+ result = three_phone_call_forwarding_short_seq(
+ log,
+ ads[0],
+ None,
+ is_callee_in_call,
+ ads[1],
+ ads[2],
+ call_forwarding_type=call_forwarding_type)
+
+ if not result:
+ if is_call_waiting:
+ pass
+ else:
+ log.error(
+ "Failed to make MO call from %s slot %s to %s slot %s"
+ " and forward to %s slot %s",
+ ad_caller.serial,
+ caller_slot,
+ ad_callee.serial,
+ callee_slot,
+ ad_forwarded_callee.serial,
+ forwarded_callee_slot)
+
+ return result
+
+
+def msim_call_voice_conf(
+ log,
+ tel_logger,
+ ads,
+ host_slot,
+ p1_slot,
+ p2_slot,
+ dds_slot,
+ host_rat=["volte", "volte"],
+ p1_rat="",
+ p2_rat="",
+ merge=True,
+ disable_cw=False):
+ """Make a voice conference call at specific slot in specific RAT with
+ DDS at specific slot.
+
+ Test step:
+ 1. Get sub IDs of specific slots of both MO and MT devices.
+ 2. Switch DDS to specific slot.
+ 3. Check HTTP connection after DDS switch.
+ 4. Set up phones in desired RAT and make 3-way voice call.
+ 5. Swap calls.
+ 6. Merge calls.
+
+ Args:
+ log: logger object
+ tel_logger: logger object for telephony proto
+ ads: list of android devices
+ host_slot: Slot on the primary device to host the comference call.
+ 0 or 1 (0 for pSIM or 1 for eSIM)
+ p1_slot: Slot on the participant device for the call
+ p2_slot: Slot on another participant device for the call
+ dds_slot: Preferred data slot
+ host_rat: RAT for both slots of the primary device
+ p1_rat: RAT for both slots of the participant device
+ p2_rat: RAT for both slots of another participant device
+ merge: True for merging 2 calls into the conference call. False for
+ not merging 2 separated call.
+ disable_cw: True for disabling call waiting and False on the
+ contrary.
+
+ Returns:
+ True or False
+ """
+ ad_host = ads[0]
+ ad_p1 = ads[1]
+ ad_p2 = ads[2]
+
+ if host_slot is not None:
+ host_sub_id = get_subid_from_slot_index(
+ log, ad_host, host_slot)
+ if host_sub_id == INVALID_SUB_ID:
+ ad_host.log.warning("Failed to get sub ID at slot.", host_slot)
+ return False
+ host_other_sub_id = get_subid_from_slot_index(
+ log, ad_host, 1-host_slot)
+ set_voice_sub_id(ad_host, host_sub_id)
+ else:
+ host_sub_id, _, _ = get_subid_on_same_network_of_host_ad(ads)
+ if host_sub_id == INVALID_SUB_ID:
+ ad_host.log.warning("Failed to get sub ID at slot.", host_slot)
+ return False
+ host_slot = "auto"
+ set_voice_sub_id(ad_host, host_sub_id)
+
+ ad_host.log.info("Sub ID for outgoing call at slot %s: %s",
+ host_slot, get_outgoing_voice_sub_id(ad_host))
+
+ if p1_slot is not None:
+ p1_sub_id = get_subid_from_slot_index(log, ad_p1, p1_slot)
+ if p1_sub_id == INVALID_SUB_ID:
+ ad_p1.log.warning("Failed to get sub ID at slot %s.", p1_slot)
+ return False
+ set_voice_sub_id(ad_p1, p1_sub_id)
+ else:
+ _, p1_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
+ if p1_sub_id == INVALID_SUB_ID:
+ ad_p1.log.warning("Failed to get sub ID at slot %s.", p1_slot)
+ return False
+ p1_slot = "auto"
+ set_voice_sub_id(ad_p1, p1_sub_id)
+ ad_p1.log.info("Sub ID for incoming call at slot %s: %s",
+ p1_slot, get_incoming_voice_sub_id(ad_p1))
+
+ if p2_slot is not None:
+ p2_sub_id = get_subid_from_slot_index(log, ad_p2, p2_slot)
+ if p2_sub_id == INVALID_SUB_ID:
+ ad_p2.log.warning("Failed to get sub ID at slot %s.", p2_slot)
+ return False
+ set_voice_sub_id(ad_p2, p2_sub_id)
+ else:
+ _, _, p2_sub_id = get_subid_on_same_network_of_host_ad(ads)
+ if p2_sub_id == INVALID_SUB_ID:
+ ad_p2.log.warning("Failed to get sub ID at slot %s.", p2_slot)
+ return False
+ p2_slot = "auto"
+ set_voice_sub_id(ad_p2, p2_sub_id)
+ ad_p2.log.info("Sub ID for incoming call at slot %s: %s",
+ p2_slot, get_incoming_voice_sub_id(ad_p2))
+
+ log.info("Step 1: Switch DDS.")
+ if not set_dds_on_slot(ads[0], dds_slot):
+ log.error(
+ "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
+ return False
+
+ log.info("Step 2: Check HTTP connection after DDS switch.")
+ if not verify_http_connection(log, ads[0]):
+ log.error("Failed to verify http connection.")
+ return False
+ else:
+ log.info("Verify http connection successfully.")
+
+ if disable_cw:
+ if not set_call_waiting(log, ad_host, enable=0):
+ return False
+ else:
+ if not set_call_waiting(log, ad_host, enable=1):
+ return False
+
+ if host_slot == 1:
+ phone_setup_on_rat(
+ log,
+ ad_host,
+ host_rat[0],
+ host_other_sub_id)
+
+ elif host_slot == 0:
+ phone_setup_on_rat(
+ log,
+ ad_host,
+ host_rat[1],
+ host_other_sub_id)
+
+ if host_slot == 0 or host_slot == 1:
+ host_phone_setup_func_argv = (log, ad_host, host_rat[host_slot], host_sub_id)
+ is_host_in_call = is_phone_in_call_on_rat(
+ log, ad_host, host_rat[host_slot], only_return_fn=True)
+ else:
+ host_phone_setup_func_argv = (log, ad_host, 'general')
+ is_host_in_call = is_phone_in_call_on_rat(
+ log, ad_host, 'general', only_return_fn=True)
+
+ if p1_rat:
+ p1_phone_setup_func_argv = (log, ad_p1, p1_rat, p1_sub_id)
+ is_p1_in_call = is_phone_in_call_on_rat(
+ log, ad_p1, p1_rat, only_return_fn=True)
+ else:
+ p1_phone_setup_func_argv = (log, ad_p1, 'general')
+ is_p1_in_call = is_phone_in_call_on_rat(
+ log, ad_p1, 'general', only_return_fn=True)
+
+ if p2_rat:
+ p2_phone_setup_func_argv = (log, ad_p2, p2_rat, p2_sub_id)
+ is_p2_in_call = is_phone_in_call_on_rat(
+ log, ad_p2, p2_rat, only_return_fn=True)
+ else:
+ p2_phone_setup_func_argv = (log, ad_p2, 'general')
+ is_p2_in_call = is_phone_in_call_on_rat(
+ log, ad_p2, 'general', only_return_fn=True)
+
+ log.info("Step 3: Set up phone in desired RAT and make 3-way"
+ " voice call.")
+
+ tasks = [(phone_setup_on_rat, host_phone_setup_func_argv),
+ (phone_setup_on_rat, p1_phone_setup_func_argv),
+ (phone_setup_on_rat, p2_phone_setup_func_argv)]
+ if not multithread_func(log, tasks):
+ log.error("Phone Failed to Set Up Properly.")
+ tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": "Phone Failed to Set Up Properly."})
+
+ call_ab_id = three_way_calling_mo_and_mt_with_hangup_once(
+ log,
+ [ad_host, ad_p1, ad_p2],
+ [None, None, None], [
+ is_host_in_call, is_p1_in_call,
+ is_p2_in_call
+ ])
+
+ if call_ab_id is None:
+ if disable_cw:
+ set_call_waiting(log, ad_host, enable=1)
+ if str(getattr(ad_host, "exception", None)) == \
+ "PhoneA call PhoneC failed.":
+ ads[0].log.info("PhoneA failed to call PhoneC due to call"
+ " waiting being disabled.")
+ delattr(ad_host, "exception")
+ return True
+ log.error("Failed to get call_ab_id")
+ return False
+ else:
+ if disable_cw:
+ return False
+
+ calls = ads[0].droid.telecomCallGetCallIds()
+ ads[0].log.info("Calls in PhoneA %s", calls)
+ if num_active_calls(log, ads[0]) != 2:
+ return False
+ if calls[0] == call_ab_id:
+ call_ac_id = calls[1]
+ else:
+ call_ac_id = calls[0]
+
+ if call_ac_id is None:
+ log.error("Failed to get call_ac_id")
+ return False
+
+ num_swaps = 2
+ log.info("Step 4: Begin Swap x%s test.", num_swaps)
+ if not swap_calls(log, ads, call_ab_id, call_ac_id,
+ num_swaps):
+ log.error("Swap test failed.")
+ return False
+
+ if not merge:
+ result = True
+ if not hangup_call(log, ads[1]):
+ result = False
+ if not hangup_call(log, ads[2]):
+ result = False
+ return result
+ else:
+ log.info("Step 5: Merge calls.")
+ if host_rat[host_slot] == "volte":
+ return _test_ims_conference_merge_drop_second_call_from_participant(
+ log, ads, call_ab_id, call_ac_id)
+ else:
+ return _test_wcdma_conference_merge_drop(
+ log, ads, call_ab_id, call_ac_id)
+
+
+def msim_volte_wfc_call_forwarding(
+ log,
+ tel_logger,
+ ads,
+ callee_slot,
+ dds_slot,
+ callee_rat=["5g_wfc", "5g_wfc"],
+ call_forwarding_type="unconditional",
+ is_airplane_mode=False,
+ is_wifi_connected=False,
+ wfc_mode=[
+ WFC_MODE_CELLULAR_PREFERRED,
+ WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=None,
+ wifi_network_pass=None):
+ """Make VoLTE/WFC call to the primary device at specific slot with DDS
+ at specific slot, and then forwarded to 3rd device with specific call
+ forwarding type.
+
+ Test step:
+ 1. Get sub IDs of specific slots of both MO and MT devices.
+ 2. Switch DDS to specific slot.
+ 3. Check HTTP connection after DDS switch.
+ 4. Set up phones in desired RAT.
+ 5. Register and enable call forwarding with specifc type.
+ 6. Make VoLTE/WFC call to the primary device and wait for being
+ forwarded to 3rd device.
+
+ Args:
+ log: logger object
+ tel_logger: logger object for telephony proto
+ ads: list of android devices
+ callee_slot: Slot of primary device receiving and forwarding MT call
+ (0 or 1)
+ dds_slot: Preferred data slot
+ callee_rat: RAT for both slots of the primary device
+ call_forwarding_type:
+ "unconditional"
+ "busy"
+ "not_answered"
+ "not_reachable"
+ is_airplane_mode: True or False for WFC setup
+ wfc_mode: Cellular preferred or Wi-Fi preferred.
+ wifi_network_ssid: SSID of Wi-Fi AP
+ wifi_network_pass: Password of Wi-Fi AP SSID
+
+ Returns:
+ True or False
+ """
+ ad_caller = ads[1]
+ ad_callee = ads[0]
+ ad_forwarded_callee = ads[2]
+
+ if not toggle_airplane_mode(log, ad_callee, False):
+ ad_callee.log.error("Failed to disable airplane mode.")
+ return False
+
+ # Set up callee (primary device)
+ callee_sub_id = get_subid_from_slot_index(
+ log, ad_callee, callee_slot)
+ if callee_sub_id == INVALID_SUB_ID:
+ log.warning(
+ "Failed to get sub ID at slot %s.", callee_slot)
+ return
+ callee_other_sub_id = get_subid_from_slot_index(
+ log, ad_callee, 1-callee_slot)
+ set_voice_sub_id(ad_callee, callee_sub_id)
+ ad_callee.log.info(
+ "Sub ID for incoming call at slot %s: %s",
+ callee_slot, get_incoming_voice_sub_id(ad_callee))
+
+ # Set up caller
+ _, caller_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
+ if caller_sub_id == INVALID_SUB_ID:
+ ad_caller.log.warning("Failed to get proper sub ID of the caller")
+ return
+ set_voice_sub_id(ad_caller, caller_sub_id)
+ ad_caller.log.info(
+ "Sub ID for outgoing call of the caller: %s",
+ get_outgoing_voice_sub_id(ad_caller))
+
+ # Set up forwarded callee
+ _, _, forwarded_callee_sub_id = get_subid_on_same_network_of_host_ad(
+ ads)
+ if forwarded_callee_sub_id == INVALID_SUB_ID:
+ ad_forwarded_callee.log.warning(
+ "Failed to get proper sub ID of the forwarded callee.")
+ return
+ set_voice_sub_id(ad_forwarded_callee, forwarded_callee_sub_id)
+ ad_forwarded_callee.log.info(
+ "Sub ID for incoming call of the forwarded callee: %s",
+ get_incoming_voice_sub_id(ad_forwarded_callee))
+
+ log.info("Step 1: Switch DDS.")
+ if not set_dds_on_slot(ads[0], dds_slot):
+ log.error(
+ "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
+ return False
+
+ log.info("Step 2: Check HTTP connection after DDS switch.")
+ if not verify_http_connection(log, ad_callee):
+ ad_callee.log.error("Failed to verify http connection.")
+ return False
+ else:
+ ad_callee.log.info("Verify http connection successfully.")
+
+ is_callee_in_call = is_phone_in_call_on_rat(
+ log, ad_callee, callee_rat[callee_slot], only_return_fn=True)
+
+ if is_airplane_mode:
+ set_call_forwarding_by_mmi(log, ad_callee, ad_forwarded_callee)
+
+ log.info("Step 3: Set up phones in desired RAT.")
+ if callee_slot == 1:
+ phone_setup_on_rat(
+ log,
+ ad_callee,
+ callee_rat[0],
+ callee_other_sub_id,
+ is_airplane_mode,
+ wfc_mode[0],
+ wifi_network_ssid,
+ wifi_network_pass)
+
+ elif callee_slot == 0:
+ phone_setup_on_rat(
+ log,
+ ad_callee,
+ callee_rat[1],
+ callee_other_sub_id,
+ is_airplane_mode,
+ wfc_mode[1],
+ wifi_network_ssid,
+ wifi_network_pass)
+
+ argv = (
+ log,
+ ad_callee,
+ callee_rat[callee_slot],
+ callee_sub_id,
+ is_airplane_mode,
+ wfc_mode[callee_slot],
+ wifi_network_ssid,
+ wifi_network_pass)
+
+ tasks = [(phone_setup_voice_general, (log, ad_caller)),
+ (phone_setup_on_rat, argv),
+ (phone_setup_voice_general, (log, ad_forwarded_callee))]
+
+ if not multithread_func(log, tasks):
+ log.error("Phone Failed to Set Up Properly.")
+ tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": "Phone Failed to Set Up Properly."})
+
+ if is_wifi_connected:
+ if not ensure_wifi_connected(
+ log,
+ ad_callee,
+ wifi_network_ssid,
+ wifi_network_pass,
+ apm=is_airplane_mode):
+ return False
+ time.sleep(5)
+
+ if "wfc" not in callee_rat[callee_slot]:
+ if not toggle_wfc_for_subscription(
+ log,
+ ad_callee,
+ new_state=True,
+ sub_id=callee_sub_id):
+ return False
+ if not set_wfc_mode_for_subscription(
+ ad_callee, wfc_mode[callee_slot], sub_id=callee_sub_id):
+ return False
+
+ log.info(
+ "Step 4: Make voice call with call forwarding %s.",
+ call_forwarding_type)
+ result = three_phone_call_forwarding_short_seq(
+ log,
+ ad_callee,
+ None,
+ is_callee_in_call,
+ ad_caller,
+ ad_forwarded_callee,
+ call_forwarding_type=call_forwarding_type)
+
+ if not result:
+ log.error(
+ "Failed to make MO call from %s to %s slot %s and forward"
+ " to %s.",
+ ad_caller.serial,
+ ad_callee.serial,
+ callee_slot,
+ ad_forwarded_callee.serial)
+ return result
+
+
+def msim_volte_wfc_call_voice_conf(
+ log,
+ tel_logger,
+ ads,
+ host_slot,
+ dds_slot,
+ host_rat=["5g_wfc", "5g_wfc"],
+ merge=True,
+ disable_cw=False,
+ is_airplane_mode=False,
+ is_wifi_connected=False,
+ wfc_mode=[WFC_MODE_CELLULAR_PREFERRED, WFC_MODE_CELLULAR_PREFERRED],
+ reject_once=False,
+ wifi_network_ssid=None,
+ wifi_network_pass=None):
+ """Make a VoLTE/WFC conference call at specific slot with DDS at
+ specific slot.
+
+ Test step:
+ 1. Get sub IDs of specific slots of both MO and MT devices.
+ 2. Set up phones in desired RAT
+ 3. Enable VoLTE/WFC.
+ 4. Switch DDS to specific slot.
+ 5. Check HTTP connection after DDS switch.
+ 6. Make 3-way VoLTE/WFC call.
+ 7. Swap calls.
+ 8. Merge calls.
+
+ Args:
+ log: logger object
+ tel_logger: logger object for telephony proto
+ ads: list of android devices
+ host_slot: Slot on the primary device to host the comference call.
+ 0 or 1 (0 for pSIM or 1 for eSIM)call
+ dds_slot: Preferred data slot
+ host_rat: RAT for both slots of the primary devicevice
+ merge: True for merging 2 calls into the conference call. False for
+ not merging 2 separated call.
+ disable_cw: True for disabling call waiting and False on the
+ contrary.
+ enable_volte: True for enabling and False for disabling VoLTE for
+ each slot on the primary device
+ enable_wfc: True for enabling and False for disabling WFC for
+ each slot on the primary device
+ is_airplane_mode: True or False for WFC setup
+ wfc_mode: Cellular preferred or Wi-Fi preferred.
+ reject_once: True for rejecting the 2nd call once from the 3rd
+ device (Phone C) to the primary device (Phone A).
+ wifi_network_ssid: SSID of Wi-Fi AP
+ wifi_network_pass: Password of Wi-Fi AP SSID
+
+ Returns:
+ True or False
+ """
+ ad_host = ads[0]
+ ad_p1 = ads[1]
+ ad_p2 = ads[2]
+
+ host_sub_id = get_subid_from_slot_index(log, ad_host, host_slot)
+ if host_sub_id == INVALID_SUB_ID:
+ ad_host.log.warning("Failed to get sub ID at slot.", host_slot)
+ return
+ host_other_sub_id = get_subid_from_slot_index(
+ log, ad_host, 1-host_slot)
+ set_voice_sub_id(ad_host, host_sub_id)
+ ad_host.log.info(
+ "Sub ID for outgoing call at slot %s: %s",
+ host_slot, get_outgoing_voice_sub_id(ad_host))
+
+ _, p1_sub_id, p2_sub_id = get_subid_on_same_network_of_host_ad(ads)
+
+ if p1_sub_id == INVALID_SUB_ID:
+ ad_p1.log.warning("Failed to get proper sub ID.")
+ return
+ set_voice_sub_id(ad_p1, p1_sub_id)
+ ad_p1.log.info(
+ "Sub ID for incoming call: %s",
+ get_incoming_voice_sub_id(ad_p1))
+
+ if p2_sub_id == INVALID_SUB_ID:
+ ad_p2.log.warning("Failed to get proper sub ID.")
+ return
+ set_voice_sub_id(ad_p2, p2_sub_id)
+ ad_p2.log.info(
+ "Sub ID for incoming call: %s", get_incoming_voice_sub_id(ad_p2))
+
+ log.info("Step 1: Switch DDS.")
+ if not set_dds_on_slot(ads[0], dds_slot):
+ log.error(
+ "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
+ return False
+
+ log.info("Step 2: Check HTTP connection after DDS switch.")
+ if not verify_http_connection(log, ads[0]):
+ ad_host.log.error("Failed to verify http connection.")
+ return False
+ else:
+ ad_host.log.info("Verify http connection successfully.")
+
+ if disable_cw:
+ if not set_call_waiting(log, ad_host, enable=0):
+ return False
+
+ log.info("Step 3: Set up phones in desired RAT.")
+ if host_slot == 1:
+ phone_setup_on_rat(
+ log,
+ ad_host,
+ host_rat[0],
+ host_other_sub_id,
+ is_airplane_mode,
+ wfc_mode[0],
+ wifi_network_ssid,
+ wifi_network_pass)
+
+ elif host_slot == 0:
+ phone_setup_on_rat(
+ log,
+ ad_host,
+ host_rat[1],
+ host_other_sub_id,
+ is_airplane_mode,
+ wfc_mode[1],
+ wifi_network_ssid,
+ wifi_network_pass)
+
+ argv = (
+ log,
+ ad_host,
+ host_rat[host_slot],
+ host_sub_id,
+ is_airplane_mode,
+ wfc_mode[host_slot],
+ wifi_network_ssid,
+ wifi_network_pass)
+
+ tasks = [(phone_setup_voice_general, (log, ad_p1)),
+ (phone_setup_on_rat, argv),
+ (phone_setup_voice_general, (log, ad_p2))]
+
+ if not multithread_func(log, tasks):
+ log.error("Phone Failed to Set Up Properly.")
+ tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
+ raise signals.TestFailure("Failed",
+ extras={"fail_reason": "Phone Failed to Set Up Properly."})
+
+ if is_wifi_connected:
+ if not ensure_wifi_connected(
+ log,
+ ad_host,
+ wifi_network_ssid,
+ wifi_network_pass,
+ apm=is_airplane_mode):
+ return False
+ time.sleep(5)
+
+ if "wfc" not in host_rat[host_slot]:
+ if not toggle_wfc_for_subscription(
+ log,
+ ad_host,
+ new_state=True,
+ sub_id=host_sub_id):
+ return False
+ if not set_wfc_mode_for_subscription(
+ ad_host, wfc_mode[host_slot], sub_id=host_sub_id):
+ return False
+
+ log.info("Step 4: Make 3-way voice call.")
+ is_host_in_call = is_phone_in_call_on_rat(
+ log, ad_host, host_rat[host_slot], only_return_fn=True)
+ call_ab_id = _three_phone_call_mo_add_mt(
+ log,
+ [ad_host, ad_p1, ad_p2],
+ [None, None, None],
+ [is_host_in_call, None, None],
+ reject_once=reject_once)
+
+ if call_ab_id is None:
+ if disable_cw:
+ set_call_waiting(log, ad_host, enable=1)
+ if str(getattr(ad_host, "exception", None)) == \
+ "PhoneA call PhoneC failed.":
+ ads[0].log.info("PhoneA failed to call PhoneC due to call"
+ " waiting being disabled.")
+ delattr(ad_host, "exception")
+ return True
+ log.error("Failed to get call_ab_id")
+ return False
+ else:
+ if disable_cw:
+ set_call_waiting(log, ad_host, enable=0)
+ return False
+
+ calls = ads[0].droid.telecomCallGetCallIds()
+ ads[0].log.info("Calls in PhoneA %s", calls)
+ if num_active_calls(log, ads[0]) != 2:
+ return False
+ if calls[0] == call_ab_id:
+ call_ac_id = calls[1]
+ else:
+ call_ac_id = calls[0]
+
+ if call_ac_id is None:
+ log.error("Failed to get call_ac_id")
+ return False
+
+ num_swaps = 2
+ log.info("Step 5: Begin Swap x%s test.", num_swaps)
+ if not swap_calls(log, ads, call_ab_id, call_ac_id,
+ num_swaps):
+ ad_host.log.error("Swap test failed.")
+ return False
+
+ if not merge:
+ result = True
+ if not hangup_call(log, ads[1]):
+ result = False
+ if not hangup_call(log, ads[2]):
+ result = False
+ return result
+ else:
+ log.info("Step 6: Merge calls.")
+
+ if re.search('csfb|2g|3g', host_rat[host_slot].lower(), re.I):
+ return _test_wcdma_conference_merge_drop(
+ log, ads, call_ab_id, call_ac_id)
+ else:
+ return _test_ims_conference_merge_drop_second_call_from_participant(
+ log, ads, call_ab_id, call_ac_id)
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_ims_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_ims_utils.py
index 7287971..4001f9b 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_ims_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_ims_utils.py
@@ -14,252 +14,778 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import time
+
+from acts import signals
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
-from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE
-from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC
-from acts_contrib.test_utils.tel.tel_defines import CarrierConfigs
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
-from acts_contrib.test_utils.tel.tel_defines import RAT_LTE
-from acts_contrib.test_utils.tel.tel_defines import RAT_NR
-from acts_contrib.test_utils.tel.tel_defines import RAT_UNKNOWN
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_incoming_voice_sub_id
+from acts_contrib.test_utils.tel.tel_defines import CARRIER_FRE
+from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_FOR_STATE_CHANGE
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOLTE_ENABLED
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_DISABLED
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import get_user_config_profile
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_wfc
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_not_network_rat
+from acts_contrib.test_utils.tel.tel_defines import CARRIER_VZW, CARRIER_ATT, \
+ CARRIER_BELL, CARRIER_ROGERS, CARRIER_KOODO, CARRIER_VIDEOTRON, CARRIER_TELUS
+from acts_contrib.test_utils.tel.tel_logging_utils import start_adb_tcpdump
+from acts_contrib.test_utils.tel.tel_test_utils import _wait_for_droid_in_state
+from acts_contrib.test_utils.tel.tel_test_utils import _wait_for_droid_in_state_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import bring_up_sl4a
+from acts_contrib.test_utils.tel.tel_test_utils import change_voice_subid_temporarily
+from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
from acts_contrib.test_utils.tel.tel_test_utils import wait_for_state
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_voice_attach
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_volte_enabled
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wfc_disabled
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wfc_enabled
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_toggle_state
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-def check_call(log, dut, dut_client):
+class TelImsUtilsError(Exception):
+ pass
+
+
+def show_enhanced_4g_lte(ad, sub_id):
result = True
- if not call_setup_teardown(log, dut_client, dut,
- dut):
- if not call_setup_teardown(log, dut_client,
- dut, dut):
- dut.log.error("MT call failed")
+ capabilities = ad.telephony["subscription"][sub_id].get("capabilities", [])
+ if capabilities:
+ if "hide_enhanced_4g_lte" in capabilities:
result = False
- if not call_setup_teardown(log, dut, dut_client,
- dut):
- dut.log.error("MO call failed")
- 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)
+ 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")
+
+ if sub_id != current_voice_sub_id:
+ set_incoming_voice_sub_id(ad, current_voice_sub_id)
+
+ result = True
return result
-def check_call_in_wfc(log, dut, dut_client):
+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:
+ TelImsUtilsError if platform does not support VoLTE.
+ """
+ return toggle_volte_for_subscription(
+ log, ad, get_outgoing_voice_sub_id(ad), new_state)
+
+
+def toggle_volte_for_subscription(log, ad, sub_id, new_state=None):
+ """Toggle enable/disable VoLTE for specified voice subscription.
+
+ Args:
+ ad: Android device object.
+ 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.
+ """
+ if not show_enhanced_4g_lte(ad, sub_id):
+ return False
+
+ current_state = None
result = True
- if not call_setup_teardown(log, dut_client, dut,
- dut, None, is_phone_in_call_iwlan):
- if not call_setup_teardown(log, dut_client,
- dut, dut, None,
- is_phone_in_call_iwlan):
- dut.log.error("MT WFC call failed")
+
+ 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
- if not call_setup_teardown(log, dut, dut_client,
- dut, is_phone_in_call_iwlan):
- dut.log.error("MO WFC call failed")
- result = False
- return result
-
-
-def check_call_in_volte(log, dut, dut_client):
- result = True
- if not call_setup_teardown(log, dut_client, dut,
- dut, None, is_phone_in_call_volte):
- if not call_setup_teardown(log, dut_client,
- dut, dut, None,
- is_phone_in_call_volte):
- dut.log.error("MT VoLTE call failed")
- result = False
- if not call_setup_teardown(log, dut, dut_client,
- dut, is_phone_in_call_volte):
- dut.log.error("MO VoLTE call failed")
- result = False
- return result
-
-
-def change_ims_setting(log,
- ad,
- dut_client,
- wifi_network_ssid,
- wifi_network_pass,
- subid,
- dut_capabilities,
- airplane_mode,
- wifi_enabled,
- volte_enabled,
- wfc_enabled,
- nw_gen=RAT_LTE,
- wfc_mode=None):
- result = True
- ad.log.info(
- "Setting APM %s, WIFI %s, VoLTE %s, WFC %s, WFC mode %s",
- airplane_mode, wifi_enabled, volte_enabled, wfc_enabled, wfc_mode)
-
- toggle_airplane_mode_by_adb(log, ad, airplane_mode)
- if wifi_enabled:
- if not ensure_wifi_connected(log, ad,
- wifi_network_ssid,
- wifi_network_pass,
- apm=airplane_mode):
- ad.log.error("Fail to connected to WiFi")
- result = False
+ return result
else:
- if not wifi_toggle_state(log, ad, False):
- ad.log.error("Failed to turn off WiFi.")
+ # 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
- toggle_volte(log, ad, volte_enabled)
- toggle_wfc(log, ad, wfc_enabled)
- if wfc_mode:
- set_wfc_mode(log, ad, wfc_mode)
- wfc_mode = ad.droid.imsGetWfcMode()
- if wifi_enabled or not airplane_mode:
- if not ensure_phone_subscription(log, ad):
- ad.log.error("Failed to find valid subscription")
- result = False
- if airplane_mode:
- if (CAPABILITY_WFC in dut_capabilities) and (wifi_enabled
- and wfc_enabled):
- if not wait_for_wfc_enabled(log, ad):
- result = False
- elif not check_call_in_wfc(log, ad, dut_client):
- result = False
- else:
- if not wait_for_state(
- ad.droid.telephonyGetCurrentVoiceNetworkType,
- RAT_UNKNOWN):
- ad.log.error(
- "Voice RAT is %s not UNKNOWN",
- ad.droid.telephonyGetCurrentVoiceNetworkType())
- result = False
- else:
- ad.log.info("Voice RAT is in UNKKNOWN")
- else:
- if (wifi_enabled and wfc_enabled) and (
- wfc_mode == WFC_MODE_WIFI_PREFERRED) and (
- CAPABILITY_WFC in dut_capabilities):
- if not wait_for_wfc_enabled(log, ad):
- result = False
- if not wait_for_state(
- ad.droid.telephonyGetCurrentVoiceNetworkType,
- RAT_UNKNOWN):
- ad.log.error(
- "Voice RAT is %s, not UNKNOWN",
- ad.droid.telephonyGetCurrentVoiceNetworkType())
- if not check_call_in_wfc(log, ad, dut_client):
- result = False
- else:
- if not wait_for_wfc_disabled(log, ad):
- ad.log.error("WFC is not disabled")
- result = False
- if volte_enabled and CAPABILITY_VOLTE in dut_capabilities:
- if not wait_for_volte_enabled(log, ad):
- result = False
- if not check_call_in_volte(log, ad, dut_client):
- result = False
- else:
- if not wait_for_not_network_rat(
- log,
- ad,
- nw_gen,
- voice_or_data=NETWORK_SERVICE_VOICE):
- ad.log.error(
- "Voice RAT is %s",
- ad.droid.telephonyGetCurrentVoiceNetworkType(
- ))
- result = False
- if not wait_for_voice_attach(log, ad):
- result = False
- if not check_call(log, ad, dut_client):
- result = False
- user_config_profile = get_user_config_profile(ad)
- ad.log.info("user_config_profile: %s ",
- sorted(user_config_profile.items()))
- return result
+
+ if voice_sub_id_changed:
+ set_incoming_voice_sub_id(ad, current_sub_id)
+
+ return result
-def verify_default_ims_setting(log,
- ad,
- dut_client,
- carrier_configs,
- default_wfc_enabled,
- default_volte,
- wfc_mode=None):
+def toggle_wfc(log, ad, new_state=None):
+ """ Toggle WFC enable/disable
+
+ Args:
+ log: Log object
+ ad: Android device object.
+ new_state: WFC state to set to.
+ True for enable, False for disable.
+ If None, opposite of the current state.
+ """
+ return toggle_wfc_for_subscription(
+ log, ad, new_state, get_outgoing_voice_sub_id(ad))
+
+
+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: 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
- airplane_mode = ad.droid.connectivityCheckAirplaneMode()
- default_wfc_mode = carrier_configs.get(
- CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT, wfc_mode)
- if default_wfc_enabled:
- wait_for_wfc_enabled(log, ad)
- else:
- wait_for_wfc_disabled(log, ad)
- if airplane_mode:
- wait_for_network_rat(
- log,
- ad,
- RAT_UNKNOWN,
- voice_or_data=NETWORK_SERVICE_VOICE)
- else:
- if default_volte:
- wait_for_volte_enabled(log, ad)
- else:
- wait_for_not_network_rat(
- log,
- ad,
- RAT_UNKNOWN,
- voice_or_data=NETWORK_SERVICE_VOICE)
- if not ensure_phone_subscription(log, ad):
- ad.log.error("Failed to find valid subscription")
- result = False
- user_config_profile = get_user_config_profile(ad)
- ad.log.info("user_config_profile = %s ",
- sorted(user_config_profile.items()))
- if user_config_profile["VoLTE Enabled"] != default_volte:
- ad.log.error("VoLTE mode is not %s", default_volte)
- result = False
- else:
- ad.log.info("VoLTE mode is %s as expected",
- default_volte)
- if user_config_profile["WFC Enabled"] != default_wfc_enabled:
- ad.log.error("WFC enabled is not %s", default_wfc_enabled)
- if user_config_profile["WFC Enabled"]:
- if user_config_profile["WFC Mode"] != default_wfc_mode:
- ad.log.error(
- "WFC mode is not %s after IMS factory reset",
- default_wfc_mode)
+ if sub_id is None:
+ sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
+
+ 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 Wi-Fi calling 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 Wi-Fi calling 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:
- ad.log.info("WFC mode is %s as expected",
- default_wfc_mode)
- if default_wfc_enabled and \
- default_wfc_mode == WFC_MODE_WIFI_PREFERRED:
- if not check_call_in_wfc(log, ad, dut_client):
- result = False
- elif not airplane_mode:
- if default_volte:
- if not check_call_in_volte(log, ad, dut_client):
- result = 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.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.
+
+ Args:
+ log: log object.
+ ad: android device.
+ max_time: maximal wait time.
+
+ Returns:
+ Return True if device report VoLTE enabled bit true within max_time.
+ Return False if timeout.
+ """
+ return wait_for_state(
+ is_enhanced_4g_lte_mode_setting_enabled,
+ True,
+ max_time,
+ WAIT_TIME_BETWEEN_STATE_CHECK,
+ ad,
+ sub_id,
+ enabled_by="platform")
+
+
+def set_wfc_mode(log, ad, wfc_mode):
+ """Set WFC enable/disable and mode.
+
+ Args:
+ log: Log object
+ ad: Android device object.
+ wfc_mode: WFC mode to set to.
+ Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED,
+ WFC_MODE_WIFI_PREFERRED, WFC_MODE_DISABLED.
+
+ Returns:
+ True if success. False if ad does not support WFC or error happened.
+ """
+ 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):
+ """Set WFC enable/disable and mode subscription based
+
+ Args:
+ ad: Android device object.
+ wfc_mode: WFC mode to set to.
+ Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED,
+ WFC_MODE_WIFI_PREFERRED.
+ sub_id: subscription Id
+
+ 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:
+ current_mode = ad.droid.imsMmTelGetVoWiFiModeSetting(sub_id)
+ ad.log.info("Current WFC mode of sub ID %s: %s", sub_id, current_mode)
+ except Exception as e:
+ 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:
+ ad.log.info("WFC is already 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.log.info(
+ "WFC is enabled for sub ID %s. Disabling WFC...", sub_id)
+ 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:
- if not check_call(log, ad, dut_client):
- result = False
- if result == False:
- user_config_profile = get_user_config_profile(ad)
- ad.log.info("user_config_profile = %s ",
- sorted(user_config_profile.items()))
- return result
+ 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:
+ ad.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):
+ """ Sets Provisioning Values for Subscription Id
+ Args:
+ ad: Android device object.
+ sub_id: Subscription Id
+ feature_flag: voice or video
+ value: enable or disable
+ """
+ try:
+ if sub_id is None:
+ sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
+ ad.log.info("SubId %s - setprovisioning for %s to %s",
+ sub_id, feature_flag, value)
+ result = ad.droid.provisioningSetProvisioningIntValue(sub_id,
+ feature_flag, value)
+ if result == 0:
+ return True
+ return False
+ except Exception as e:
+ ad.log.error(e)
+ return False
+
+
+def get_ims_provisioning_for_subscription(ad, feature_flag, tech, sub_id=None):
+ """ Gets Provisioning Values for Subscription Id
+
+ Args:
+ ad: Android device object.
+ sub_id: Subscription Id
+ feature_flag: voice, video, ut, sms
+ tech: lte, iwlan
+ """
+ try:
+ if sub_id is None:
+ sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
+ result = ad.droid.provisioningGetProvisioningStatusForCapability(
+ sub_id, feature_flag, tech)
+ ad.log.info("SubId %s - getprovisioning for %s on %s - %s",
+ sub_id, feature_flag, tech, result)
+ return result
+ except Exception as e:
+ ad.log.error(e)
+ return False
+
+
+def activate_wfc_on_device(log, ad):
+ """ Activates WiFi calling on device.
+
+ Required for certain network operators.
+
+ Args:
+ log: Log object
+ ad: Android device object
+ """
+ activate_wfc_on_device_for_subscription(log, ad,
+ ad.droid.subscriptionGetDefaultSubId())
+
+
+def activate_wfc_on_device_for_subscription(log, ad, sub_id):
+ """ Activates WiFi calling on device for a subscription.
+
+ Args:
+ log: Log object
+ ad: Android device object
+ sub_id: Subscription id (integer)
+ """
+ if not sub_id or INVALID_SUB_ID == sub_id:
+ ad.log.error("Subscription id invalid")
+ return
+ operator_name = get_operator_name(log, ad, sub_id)
+ if operator_name in (CARRIER_VZW, CARRIER_ATT, CARRIER_BELL, CARRIER_ROGERS,
+ CARRIER_TELUS, CARRIER_KOODO, CARRIER_VIDEOTRON, CARRIER_FRE):
+ ad.log.info("Activating WFC on operator : %s", operator_name)
+ if not ad.is_apk_installed("com.google.android.wfcactivation"):
+ ad.log.error("WFC Activation Failed, wfc activation apk not installed")
+ return
+ wfc_activate_cmd ="am start --ei EXTRA_LAUNCH_CARRIER_APP 0 --ei " \
+ "android.telephony.extra.SUBSCRIPTION_INDEX {} -n ".format(sub_id)
+ if CARRIER_ATT == operator_name:
+ ad.adb.shell("setprop dbg.att.force_wfc_nv_enabled true")
+ wfc_activate_cmd = wfc_activate_cmd+\
+ "\"com.google.android.wfcactivation/" \
+ ".WfcActivationActivity\""
+ elif CARRIER_VZW == operator_name:
+ ad.adb.shell("setprop dbg.vzw.force_wfc_nv_enabled true")
+ wfc_activate_cmd = wfc_activate_cmd + \
+ "\"com.google.android.wfcactivation/" \
+ ".VzwEmergencyAddressActivity\""
+ else:
+ wfc_activate_cmd = wfc_activate_cmd+ \
+ "\"com.google.android.wfcactivation/" \
+ ".can.WfcActivationCanadaActivity\""
+ ad.adb.shell(wfc_activate_cmd)
+
+
+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.
+ """
+ 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):
+ """Wait for android device to register on ims.
+
+ Args:
+ log: log object.
+ ad: android device.
+ max_time: maximal wait time.
+
+ Returns:
+ Return True if device register ims successfully within max_time.
+ Return False if timeout.
+ """
+ return _wait_for_droid_in_state(log, ad, max_time, is_ims_registered)
+
+
+def is_volte_available(log, ad, sub_id=None):
+ """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, 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, sub_id):
+ ad.log.info("IMS is not registered for sub ID %s.", sub_id)
+ return 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 for sub ID %s, IsVolteCallingAvailable "
+ "is True", sub_id)
+ return True
+
+
+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:
+ log: log object.
+ ad: android device.
+ max_time: maximal wait time.
+
+ Returns:
+ Return True if device report VoLTE enabled bit true within max_time.
+ Return False if timeout.
+ """
+ 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 toggle_video_calling(log, ad, new_state=None):
+ """Toggle enable/disable Video calling for default voice subscription.
+
+ Args:
+ ad: Android device object.
+ new_state: Video mode state to set to.
+ True for enable, False for disable.
+ If None, opposite of the current state.
+
+ Raises:
+ TelImsUtilsError if platform does not support Video calling.
+ """
+ if not ad.droid.imsIsVtEnabledByPlatform():
+ if new_state is not False:
+ raise TelImsUtilsError("VT not supported by platform.")
+ # if the user sets VT false and it's unavailable we just let it go
+ return False
+
+ current_state = ad.droid.imsIsVtEnabledByUser()
+ if new_state is None:
+ new_state = not current_state
+ if new_state != current_state:
+ ad.droid.imsSetVtSetting(new_state)
+ return True
+
+
+def toggle_video_calling_for_subscription(ad, new_state=None, sub_id=None):
+ """Toggle enable/disable Video calling for subscription.
+
+ Args:
+ ad: Android device object.
+ new_state: Video mode state to set to.
+ True for enable, False for disable.
+ If None, opposite of the current state.
+ sub_id: subscription Id
+ """
+ try:
+ if sub_id is None:
+ sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
+ current_state = ad.droid.imsMmTelIsVtSettingEnabled(sub_id)
+ if new_state is None:
+ new_state = not current_state
+ if new_state != current_state:
+ ad.log.info("SubId %s - Toggle VT from %s to %s", sub_id,
+ current_state, new_state)
+ ad.droid.imsMmTelSetVtSettingEnabled(sub_id, new_state)
+ except Exception as e:
+ ad.log.error(e)
+ return False
+ return True
+
+
+def is_video_enabled(log, ad):
+ """Return True if Video Calling feature bit is True.
+
+ Args:
+ log: log object.
+ ad: android device.
+
+ Returns:
+ Return True if Video Calling feature bit is True and IMS registered.
+ Return False if Video Calling feature bit is False or IMS not registered.
+ """
+ video_status = ad.droid.telephonyIsVideoCallingAvailable()
+ if video_status is True and is_ims_registered(log, ad) is False:
+ ad.log.error(
+ "Error! Video Call is Available, but IMS is not registered.")
+ return False
+ return video_status
+
+
+def wait_for_video_enabled(log, ad, max_time=MAX_WAIT_TIME_VOLTE_ENABLED):
+ """Wait for android device to report Video Telephony enabled bit true.
+
+ Args:
+ log: log object.
+ ad: android device.
+ max_time: maximal wait time.
+
+ Returns:
+ Return True if device report Video Telephony enabled bit true within max_time.
+ Return False if timeout.
+ """
+ return _wait_for_droid_in_state(log, ad, max_time, is_video_enabled)
+
+
+def is_wfc_enabled(log, ad):
+ """Return True if WiFi Calling feature bit is True.
+
+ Args:
+ log: log object.
+ ad: android device.
+
+ Returns:
+ Return True if WiFi Calling feature bit is True and IMS registered.
+ Return False if WiFi Calling feature bit is False or IMS not registered.
+ """
+ if not is_ims_registered(log, ad):
+ ad.log.info("IMS is not registered.")
+ return False
+ if not ad.droid.telephonyIsWifiCallingAvailable():
+ ad.log.info("IMS is registered, IsWifiCallingAvailable is False")
+ return False
+ else:
+ ad.log.info("IMS is registered, IsWifiCallingAvailable is True")
+ return True
+
+
+def wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED):
+ """Wait for android device to report WiFi Calling enabled bit true.
+
+ Args:
+ log: log object.
+ ad: android device.
+ max_time: maximal wait time.
+ Default value is MAX_WAIT_TIME_WFC_ENABLED.
+
+ Returns:
+ Return True if device report WiFi Calling enabled bit true within max_time.
+ Return False if timeout.
+ """
+ return _wait_for_droid_in_state(log, ad, max_time, is_wfc_enabled)
+
+
+def wait_for_wfc_disabled(log, ad, max_time=MAX_WAIT_TIME_WFC_DISABLED):
+ """Wait for android device to report WiFi Calling enabled bit false.
+
+ Args:
+ log: log object.
+ ad: android device.
+ max_time: maximal wait time.
+ Default value is MAX_WAIT_TIME_WFC_DISABLED.
+
+ Returns:
+ Return True if device report WiFi Calling enabled bit false within max_time.
+ Return False if timeout.
+ """
+ return _wait_for_droid_in_state(
+ log, ad, max_time, lambda log, ad: not is_wfc_enabled(log, ad))
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_logging_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_logging_utils.py
new file mode 100644
index 0000000..8ab69f6
--- /dev/null
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_logging_utils.py
@@ -0,0 +1,611 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - Google
+#
+# 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 datetime import datetime
+import os
+import re
+import shutil
+import time
+
+from acts import utils
+from acts.libs.proc import job
+from acts.controllers.android_device import DEFAULT_QXDM_LOG_PATH
+from acts.controllers.android_device import DEFAULT_SDM_LOG_PATH
+from acts.libs.utils.multithread import run_multithread_func
+from acts.utils import get_current_epoch_time
+from acts.utils import start_standing_subprocess
+
+
+_LS_MASK_NAME = "Lassen default + TCP"
+
+_LS_ENABLE_LOG_SHELL = f"""\
+am broadcast -n com.android.pixellogger/.receiver.AlwaysOnLoggingReceiver \
+ -a com.android.pixellogger.service.logging.LoggingService.ACTION_CONFIGURE_ALWAYS_ON_LOGGING \
+ -e intent_key_enable "true" -e intent_key_config "{_LS_MASK_NAME}" \
+ --ei intent_key_max_log_size_mb 100 --ei intent_key_max_number_of_files 100
+"""
+_LS_DISABLE_LOG_SHELL = """\
+am broadcast -n com.android.pixellogger/.receiver.AlwaysOnLoggingReceiver \
+ -a com.android.pixellogger.service.logging.LoggingService.ACTION_CONFIGURE_ALWAYS_ON_LOGGING \
+ -e intent_key_enable "false"
+"""
+
+
+def check_if_tensor_platform(ad):
+ """Check if current platform belongs to the Tensor platform
+
+ Args:
+ ad: Android object
+
+ Returns:
+ True if current platform belongs to the Tensor platform. Otherwise False.
+ """
+ result = ad.adb.getprop("ro.boot.hardware.platform")
+ if re.search('^gs', result, re.I):
+ return True
+ return False
+
+
+def start_pixellogger_always_on_logging(ad):
+ """Start always-on logging of Pixellogger for both Qualcomm and Tensor
+ platform.
+
+ Args:
+ ad: Android object
+
+ Returns:
+ True if the property is set correctly. Otherwise False.
+ """
+ setattr(ad, 'enable_always_on_modem_logger', True)
+ if check_if_tensor_platform(ad):
+ key = "persist.vendor.sys.modem.logging.enable"
+ else:
+ key = "persist.vendor.sys.modem.diag.mdlog"
+
+ if ad.adb.getprop(key) == "false":
+ ad.adb.shell("setprop persist.vendor.sys.modem.logging.enable true")
+ time.sleep(5)
+ if ad.adb.getprop(key) == "true":
+ return True
+ else:
+ return False
+ else:
+ return True
+
+
+def start_dsp_logger_p21(ad, retry=3):
+ """Start DSP logging for P21 devices.
+
+ Args:
+ ad: Android object.
+ retry: times of retry to enable DSP logger.
+
+ Returns:
+ True if DSP logger is enabled correctly. Otherwise False.
+ """
+ if not getattr(ad, "dsp_log_p21", False): return
+
+ def _is_dsp_enabled(ad):
+ return "00" in ad.adb.shell('am instrument -w -e request '
+ 'at+googgetnv=\\"\\!LTEL1\\.HAL\\.DSP\\ clkgating\\ Enb\\/Dis\\" '
+ '-e response wait "com.google.mdstest/com.google.mdstest.'
+ 'instrument.ModemATCommandInstrumentation"')
+
+ for _ in range(retry):
+ if not _is_dsp_enabled(ad):
+ ad.adb.shell('am instrument -w -e request at+googsetnv=\\"'
+ '\\!LTEL1\\.HAL\\.DSP\\ clkgating\\ Enb\\/Dis\\"\\,0\\,\\"'
+ '00\\" -e response wait "com.google.mdstest/com.google.mdstest.'
+ 'instrument.ModemATCommandInstrumentation"')
+ time.sleep(3)
+ else:
+ ad.log.info("DSP logger is enabled, reboot to start.")
+ ad.reboot()
+ return True
+ ad.log.warning("DSP logger enable failed")
+ return False
+
+
+def start_sdm_logger(ad):
+ """Start SDM logger."""
+ if not getattr(ad, "sdm_log", True): return
+
+ # Delete existing SDM logs which were created 15 mins prior
+ ad.sdm_log_path = DEFAULT_SDM_LOG_PATH
+ file_count = ad.adb.shell(
+ f"find {ad.sdm_log_path} -type f -iname sbuff_[0-9]*.sdm* | wc -l")
+ if int(file_count) > 3:
+ seconds = 15 * 60
+ # Remove sdm logs modified more than specified seconds ago
+ ad.adb.shell(
+ f"find {ad.sdm_log_path} -type f -iname sbuff_[0-9]*.sdm* "
+ f"-not -mtime -{seconds}s -delete")
+
+ # Disable modem logging already running
+ stop_sdm_logger(ad)
+
+ # start logging
+ ad.log.debug("start sdm logging")
+ while int(
+ ad.adb.shell(f"find {ad.sdm_log_path} -type f "
+ "-iname sbuff_profile.sdm | wc -l") == 0 or
+ int(
+ ad.adb.shell(f"find {ad.sdm_log_path} -type f "
+ "-iname sbuff_[0-9]*.sdm* | wc -l")) == 0):
+ ad.adb.shell(_LS_ENABLE_LOG_SHELL, ignore_status=True)
+ time.sleep(5)
+
+
+def stop_sdm_logger(ad):
+ """Stop SDM logger."""
+ ad.sdm_log_path = DEFAULT_SDM_LOG_PATH
+ cycle = 1
+
+ ad.log.debug("stop sdm logging")
+ while int(
+ ad.adb.shell(
+ f"find {ad.sdm_log_path} -type f -iname sbuff_profile.sdm -o "
+ "-iname sbuff_[0-9]*.sdm* | wc -l")) != 0:
+ if cycle == 1 and int(
+ ad.adb.shell(f"find {ad.sdm_log_path} -type f "
+ "-iname sbuff_profile.sdm | wc -l")) == 0:
+ ad.adb.shell(_LS_ENABLE_LOG_SHELL, ignore_status=True)
+ time.sleep(5)
+ ad.adb.shell(_LS_DISABLE_LOG_SHELL, ignore_status=True)
+ cycle += 1
+ time.sleep(15)
+
+
+def start_sdm_loggers(log, ads):
+ tasks = [(start_sdm_logger, [ad]) for ad in ads
+ if getattr(ad, "sdm_log", True)]
+ if tasks: run_multithread_func(log, tasks)
+
+
+def stop_sdm_loggers(log, ads):
+ tasks = [(stop_sdm_logger, [ad]) for ad in ads]
+ run_multithread_func(log, tasks)
+
+
+def find_qxdm_log_mask(ad, mask="default.cfg"):
+ """Find QXDM logger mask."""
+ if "/" not in mask:
+ # Call nexuslogger to generate log mask
+ start_nexuslogger(ad)
+ # Find the log mask path
+ for path in (DEFAULT_QXDM_LOG_PATH, "/data/diag_logs",
+ "/vendor/etc/mdlog/", "/vendor/etc/modem/"):
+ out = ad.adb.shell(
+ "find %s -type f -iname %s" % (path, mask), ignore_status=True)
+ if out and "No such" not in out and "Permission denied" not in out:
+ if path.startswith("/vendor/"):
+ setattr(ad, "qxdm_log_path", DEFAULT_QXDM_LOG_PATH)
+ else:
+ setattr(ad, "qxdm_log_path", path)
+ return out.split("\n")[0]
+ for mask_file in ("/vendor/etc/mdlog/", "/vendor/etc/modem/"):
+ if mask in ad.adb.shell("ls %s" % mask_file, ignore_status=True):
+ setattr(ad, "qxdm_log_path", DEFAULT_QXDM_LOG_PATH)
+ return "%s/%s" % (mask_file, mask)
+ else:
+ out = ad.adb.shell("ls %s" % mask, ignore_status=True)
+ if out and "No such" not in out:
+ qxdm_log_path, cfg_name = os.path.split(mask)
+ setattr(ad, "qxdm_log_path", qxdm_log_path)
+ return mask
+ ad.log.warning("Could NOT find QXDM logger mask path for %s", mask)
+
+
+def set_qxdm_logger_command(ad, mask=None):
+ """Set QXDM logger always on.
+
+ Args:
+ ad: android device object.
+
+ """
+ ## Neet to check if log mask will be generated without starting nexus logger
+ masks = []
+ mask_path = None
+ if mask:
+ masks = [mask]
+ masks.extend(["QC_Default.cfg", "default.cfg"])
+ for mask in masks:
+ mask_path = find_qxdm_log_mask(ad, mask)
+ if mask_path: break
+ if not mask_path:
+ ad.log.error("Cannot find QXDM mask %s", mask)
+ ad.qxdm_logger_command = None
+ return False
+ else:
+ ad.log.info("Use QXDM log mask %s", mask_path)
+ ad.log.debug("qxdm_log_path = %s", ad.qxdm_log_path)
+ output_path = os.path.join(ad.qxdm_log_path, "logs")
+ ad.qxdm_logger_command = ("diag_mdlog -f %s -o %s -s 90 -c" %
+ (mask_path, output_path))
+ return True
+
+
+def stop_qxdm_logger(ad):
+ """Stop QXDM logger."""
+ for cmd in ("diag_mdlog -k", "killall diag_mdlog"):
+ output = ad.adb.shell("ps -ef | grep mdlog") or ""
+ if "diag_mdlog" not in output:
+ break
+ ad.log.debug("Kill the existing qxdm process")
+ ad.adb.shell(cmd, ignore_status=True)
+ time.sleep(5)
+
+
+def start_qxdm_logger(ad, begin_time=None):
+ """Start QXDM logger."""
+ if not getattr(ad, "qxdm_log", True): return
+ # Delete existing QXDM logs 5 minutes earlier than the begin_time
+ current_time = get_current_epoch_time()
+ if getattr(ad, "qxdm_log_path", None):
+ seconds = None
+ file_count = ad.adb.shell(
+ "find %s -type f -iname *.qmdl | wc -l" % ad.qxdm_log_path)
+ if int(file_count) > 3:
+ if begin_time:
+ # if begin_time specified, delete old qxdm logs modified
+ # 10 minutes before begin time
+ seconds = int((current_time - begin_time) / 1000.0) + 10 * 60
+ else:
+ # if begin_time is not specified, delete old qxdm logs modified
+ # 15 minutes before current time
+ seconds = 15 * 60
+ if seconds:
+ # Remove qxdm logs modified more than specified seconds ago
+ ad.adb.shell(
+ "find %s -type f -iname *.qmdl -not -mtime -%ss -delete" %
+ (ad.qxdm_log_path, seconds))
+ ad.adb.shell(
+ "find %s -type f -iname *.xml -not -mtime -%ss -delete" %
+ (ad.qxdm_log_path, seconds))
+ if getattr(ad, "qxdm_logger_command", None):
+ output = ad.adb.shell("ps -ef | grep mdlog") or ""
+ if ad.qxdm_logger_command not in output:
+ ad.log.debug("QXDM logging command %s is not running",
+ ad.qxdm_logger_command)
+ if "diag_mdlog" in output:
+ # Kill the existing non-matching diag_mdlog process
+ # Only one diag_mdlog process can be run
+ stop_qxdm_logger(ad)
+ ad.log.info("Start QXDM logger")
+ ad.adb.shell_nb(ad.qxdm_logger_command)
+ time.sleep(10)
+ else:
+ run_time = check_qxdm_logger_run_time(ad)
+ if run_time < 600:
+ # the last diag_mdlog started within 10 minutes ago
+ # no need to restart
+ return True
+ if ad.search_logcat(
+ "Diag_Lib: diag: In delete_log",
+ begin_time=current_time -
+ run_time) or not ad.get_file_names(
+ ad.qxdm_log_path,
+ begin_time=current_time - 600000,
+ match_string="*.qmdl"):
+ # diag_mdlog starts deleting files or no qmdl logs were
+ # modified in the past 10 minutes
+ ad.log.debug("Quit existing diag_mdlog and start a new one")
+ stop_qxdm_logger(ad)
+ ad.adb.shell_nb(ad.qxdm_logger_command)
+ time.sleep(10)
+ return True
+
+
+def disable_qxdm_logger(ad):
+ for prop in ("persist.sys.modem.diag.mdlog",
+ "persist.vendor.sys.modem.diag.mdlog",
+ "vendor.sys.modem.diag.mdlog_on"):
+ if ad.adb.getprop(prop):
+ ad.adb.shell("setprop %s false" % prop, ignore_status=True)
+ for apk in ("com.android.nexuslogger", "com.android.pixellogger"):
+ if ad.is_apk_installed(apk) and ad.is_apk_running(apk):
+ ad.force_stop_apk(apk)
+ stop_qxdm_logger(ad)
+ return True
+
+
+def check_qxdm_logger_run_time(ad):
+ output = ad.adb.shell("ps -eo etime,cmd | grep diag_mdlog")
+ result = re.search(r"(\d+):(\d+):(\d+) diag_mdlog", output)
+ if result:
+ return int(result.group(1)) * 60 * 60 + int(
+ result.group(2)) * 60 + int(result.group(3))
+ else:
+ result = re.search(r"(\d+):(\d+) diag_mdlog", output)
+ if result:
+ return int(result.group(1)) * 60 + int(result.group(2))
+ else:
+ return 0
+
+
+def start_qxdm_loggers(log, ads, begin_time=None):
+ tasks = [(start_qxdm_logger, [ad, begin_time]) for ad in ads
+ if getattr(ad, "qxdm_log", True)]
+ if tasks: run_multithread_func(log, tasks)
+
+
+def stop_qxdm_loggers(log, ads):
+ tasks = [(stop_qxdm_logger, [ad]) for ad in ads]
+ run_multithread_func(log, tasks)
+
+
+def check_qxdm_logger_mask(ad, mask_file="QC_Default.cfg"):
+ """Check if QXDM logger always on is set.
+
+ Args:
+ ad: android device object.
+
+ """
+ output = ad.adb.shell(
+ "ls /data/vendor/radio/diag_logs/", ignore_status=True)
+ if not output or "No such" in output:
+ return True
+ if mask_file not in ad.adb.shell(
+ "cat /data/vendor/radio/diag_logs/diag.conf", ignore_status=True):
+ return False
+ return True
+
+
+def start_nexuslogger(ad):
+ """Start Nexus/Pixel Logger Apk."""
+ qxdm_logger_apk = None
+ for apk, activity in (("com.android.nexuslogger", ".MainActivity"),
+ ("com.android.pixellogger",
+ ".ui.main.MainActivity")):
+ if ad.is_apk_installed(apk):
+ qxdm_logger_apk = apk
+ break
+ if not qxdm_logger_apk: return
+ if ad.is_apk_running(qxdm_logger_apk):
+ if "granted=true" in ad.adb.shell(
+ "dumpsys package %s | grep READ_EXTERN" % qxdm_logger_apk):
+ return True
+ else:
+ ad.log.info("Kill %s" % qxdm_logger_apk)
+ ad.force_stop_apk(qxdm_logger_apk)
+ time.sleep(5)
+ for perm in ("READ",):
+ ad.adb.shell("pm grant %s android.permission.%s_EXTERNAL_STORAGE" %
+ (qxdm_logger_apk, perm))
+ time.sleep(2)
+ for i in range(3):
+ ad.unlock_screen()
+ ad.log.info("Start %s Attempt %d" % (qxdm_logger_apk, i + 1))
+ ad.adb.shell("am start -n %s/%s" % (qxdm_logger_apk, activity))
+ time.sleep(5)
+ if ad.is_apk_running(qxdm_logger_apk):
+ ad.send_keycode("HOME")
+ return True
+ return False
+
+
+def start_tcpdumps(ads,
+ test_name="",
+ begin_time=None,
+ interface="any",
+ mask="all"):
+ for ad in ads:
+ try:
+ start_adb_tcpdump(
+ ad,
+ test_name=test_name,
+ begin_time=begin_time,
+ interface=interface,
+ mask=mask)
+ except Exception as e:
+ ad.log.warning("Fail to start tcpdump due to %s", e)
+
+
+def start_adb_tcpdump(ad,
+ test_name="",
+ begin_time=None,
+ interface="any",
+ mask="all"):
+ """Start tcpdump on any iface
+
+ Args:
+ ad: android device object.
+ test_name: tcpdump file name will have this
+
+ """
+ out = ad.adb.shell("ls -l /data/local/tmp/tcpdump/", ignore_status=True)
+ if "No such file" in out or not out:
+ ad.adb.shell("mkdir /data/local/tmp/tcpdump")
+ else:
+ ad.adb.shell(
+ "find /data/local/tmp/tcpdump -type f -not -mtime -1800s -delete",
+ ignore_status=True)
+ ad.adb.shell(
+ "find /data/local/tmp/tcpdump -type f -size +5G -delete",
+ ignore_status=True)
+
+ if not begin_time:
+ begin_time = get_current_epoch_time()
+
+ out = ad.adb.shell(
+ 'ifconfig | grep -v -E "r_|-rmnet" | grep -E "lan|data"',
+ ignore_status=True,
+ timeout=180)
+ intfs = re.findall(r"(\S+).*", out)
+ if interface and interface not in ("any", "all"):
+ if interface not in intfs: return
+ intfs = [interface]
+
+ out = ad.adb.shell("ps -ef | grep tcpdump")
+ cmds = []
+ for intf in intfs:
+ if intf in out:
+ ad.log.info("tcpdump on interface %s is already running", intf)
+ continue
+ else:
+ log_file_name = "/data/local/tmp/tcpdump/tcpdump_%s_%s_%s_%s.pcap" \
+ % (ad.serial, intf, test_name, begin_time)
+ if mask == "ims":
+ cmds.append(
+ "adb -s %s shell tcpdump -i %s -s0 -n -p udp port 500 or "
+ "udp port 4500 -w %s" % (ad.serial, intf, log_file_name))
+ else:
+ cmds.append("adb -s %s shell tcpdump -i %s -s0 -w %s" %
+ (ad.serial, intf, log_file_name))
+ if "Qualcomm" not in str(ad.adb.shell("getprop gsm.version.ril-impl")):
+ log_file_name = ("/data/local/tmp/tcpdump/tcpdump_%s_any_%s_%s.pcap"
+ % (ad.serial, test_name, begin_time))
+ cmds.append("adb -s %s shell nohup tcpdump -i any -s0 -w %s" %
+ (ad.serial, log_file_name))
+ for cmd in cmds:
+ ad.log.info(cmd)
+ try:
+ start_standing_subprocess(cmd, 10)
+ except Exception as e:
+ ad.log.error(e)
+ if cmds:
+ time.sleep(5)
+
+
+def stop_tcpdumps(ads):
+ for ad in ads:
+ stop_adb_tcpdump(ad)
+
+
+def stop_adb_tcpdump(ad, interface="any"):
+ """Stops tcpdump on any iface
+ Pulls the tcpdump file in the tcpdump dir
+
+ Args:
+ ad: android device object.
+
+ """
+ if interface == "any":
+ try:
+ ad.adb.shell("killall -9 tcpdump", ignore_status=True)
+ except Exception as e:
+ ad.log.error("Killing tcpdump with exception %s", e)
+ else:
+ out = ad.adb.shell("ps -ef | grep tcpdump | grep %s" % interface)
+ if "tcpdump -i" in out:
+ pids = re.findall(r"\S+\s+(\d+).*tcpdump -i", out)
+ for pid in pids:
+ ad.adb.shell("kill -9 %s" % pid)
+ ad.adb.shell(
+ "find /data/local/tmp/tcpdump -type f -not -mtime -1800s -delete",
+ ignore_status=True)
+
+
+def get_tcpdump_log(ad, test_name="", begin_time=None):
+ """Stops tcpdump on any iface
+ Pulls the tcpdump file in the tcpdump dir
+ Zips all tcpdump files
+
+ Args:
+ ad: android device object.
+ test_name: test case name
+ begin_time: test begin time
+ """
+ logs = ad.get_file_names("/data/local/tmp/tcpdump", begin_time=begin_time)
+ if logs:
+ ad.log.info("Pulling tcpdumps %s", logs)
+ log_path = os.path.join(
+ ad.device_log_path, "TCPDUMP_%s_%s" % (ad.model, ad.serial))
+ os.makedirs(log_path, exist_ok=True)
+ ad.pull_files(logs, log_path)
+ shutil.make_archive(log_path, "zip", log_path)
+ shutil.rmtree(log_path)
+ return True
+
+
+def wait_for_log(ad, pattern, begin_time=None, end_time=None, max_wait_time=120):
+ """Wait for logcat logs matching given pattern. This function searches in
+ logcat for strings matching given pattern by using search_logcat per second
+ until max_wait_time reaches.
+
+ Args:
+ ad: android device object
+ pattern: pattern to be searched in grep format
+ begin_time: only the lines in logcat with time stamps later than
+ begin_time will be searched.
+ end_time: only the lines in logcat with time stamps earlier than
+ end_time will be searched.
+ max_wait_time: timeout of this function
+
+ Returns:
+ All matched lines will be returned. If no line matches the given pattern
+ None will be returned.
+ """
+ start_time = datetime.now()
+ while True:
+ ad.log.info(
+ '====== Searching logcat for "%s" ====== ', pattern)
+ res = ad.search_logcat(
+ pattern, begin_time=begin_time, end_time=end_time)
+ if res:
+ return res
+ time.sleep(1)
+ stop_time = datetime.now()
+ passed_time = (stop_time - start_time).total_seconds()
+ if passed_time > max_wait_time:
+ return
+
+
+def extract_test_log(log, src_file, dst_file, test_tag):
+ os.makedirs(os.path.dirname(dst_file), exist_ok=True)
+ cmd = "grep -n '%s' %s" % (test_tag, src_file)
+ result = job.run(cmd, ignore_status=True)
+ if not result.stdout or result.exit_status == 1:
+ log.warning("Command %s returns %s", cmd, result)
+ return
+ line_nums = re.findall(r"(\d+).*", result.stdout)
+ if line_nums:
+ begin_line = int(line_nums[0])
+ end_line = int(line_nums[-1])
+ if end_line - begin_line <= 5:
+ result = job.run("wc -l < %s" % src_file)
+ if result.stdout:
+ end_line = int(result.stdout)
+ log.info("Extract %s from line %s to line %s to %s", src_file,
+ begin_line, end_line, dst_file)
+ job.run("awk 'NR >= %s && NR <= %s' %s > %s" % (begin_line, end_line,
+ src_file, dst_file))
+
+
+def log_screen_shot(ad, test_name=""):
+ file_name = "/sdcard/Pictures/screencap"
+ if test_name:
+ file_name = "%s_%s" % (file_name, test_name)
+ file_name = "%s_%s.png" % (file_name, utils.get_current_epoch_time())
+ try:
+ ad.adb.shell("screencap -p %s" % file_name)
+ except:
+ ad.log.error("Fail to log screen shot to %s", file_name)
+
+
+def get_screen_shot_log(ad, test_name="", begin_time=None):
+ logs = ad.get_file_names("/sdcard/Pictures", begin_time=begin_time)
+ if logs:
+ ad.log.info("Pulling %s", logs)
+ log_path = os.path.join(ad.device_log_path, "Screenshot_%s" % ad.serial)
+ os.makedirs(log_path, exist_ok=True)
+ ad.pull_files(logs, log_path)
+ ad.adb.shell("rm -rf /sdcard/Pictures/screencap_*", ignore_status=True)
+
+
+def get_screen_shot_logs(ads, test_name="", begin_time=None):
+ for ad in ads:
+ get_screen_shot_log(ad, test_name=test_name, begin_time=begin_time)
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_lookup_tables.py b/acts_tests/acts_contrib/test_utils/tel/tel_lookup_tables.py
index 247f65e..df3336b 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_lookup_tables.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_lookup_tables.py
@@ -158,7 +158,10 @@
"Ntt Docomo" : tel_defines.CARRIER_NTT_DOCOMO,
"KDDI" : tel_defines.CARRIER_KDDI,
"Rakuten": tel_defines.CARRIER_RAKUTEN,
- "SBM": tel_defines.CARRIER_SBM
+ "SBM": tel_defines.CARRIER_SBM,
+ "SK Telecom": tel_defines.CARRIER_SKT,
+ "KT": tel_defines.CARRIER_KT,
+ "LG U+": tel_defines.CARRIER_LG_UPLUS
}
operator_id_to_name = {
@@ -277,7 +280,40 @@
#Telstra (Australia)
'52501': tel_defines.CARRIER_SING,
- '50501': tel_defines.CARRIER_TSA
+ '50501': tel_defines.CARRIER_TSA,
+
+ #KT (South Korea)
+ '45002': tel_defines.CARRIER_KT,
+ '45004': tel_defines.CARRIER_KT,
+ '45008': tel_defines.CARRIER_KT,
+
+ #Softbank (Japan)
+ '44004': tel_defines.CARRIER_SBM,
+ '44006': tel_defines.CARRIER_SBM,
+ '44020': tel_defines.CARRIER_SBM,
+ '44040': tel_defines.CARRIER_SBM,
+ '44041': tel_defines.CARRIER_SBM,
+ '44042': tel_defines.CARRIER_SBM,
+ '44043': tel_defines.CARRIER_SBM,
+ '44044': tel_defines.CARRIER_SBM,
+ '44045': tel_defines.CARRIER_SBM,
+ '44046': tel_defines.CARRIER_SBM,
+ '44047': tel_defines.CARRIER_SBM,
+ '44048': tel_defines.CARRIER_SBM,
+ '44090': tel_defines.CARRIER_SBM,
+ '44092': tel_defines.CARRIER_SBM,
+ '44093': tel_defines.CARRIER_SBM,
+ '44094': tel_defines.CARRIER_SBM,
+ '44095': tel_defines.CARRIER_SBM,
+ '44096': tel_defines.CARRIER_SBM,
+ '44097': tel_defines.CARRIER_SBM,
+ '44098': tel_defines.CARRIER_SBM,
+
+ #SK Telecom (South Korea)
+ '45005': tel_defines.CARRIER_SKT,
+
+ #LG U+ (South Korea)
+ '45006': tel_defines.CARRIER_LG_UPLUS
}
technology_gen_tbl = [
@@ -624,7 +660,10 @@
tel_defines.CARRIER_ESP: default_umts_operator_network_tbl,
tel_defines.CARRIER_ORG: default_umts_operator_network_tbl,
tel_defines.CARRIER_TEL: default_umts_operator_network_tbl,
- tel_defines.CARRIER_TSA: default_umts_operator_network_tbl
+ tel_defines.CARRIER_TSA: default_umts_operator_network_tbl,
+ tel_defines.CARRIER_KT: default_umts_operator_network_tbl,
+ tel_defines.CARRIER_SKT: default_umts_operator_network_tbl,
+ tel_defines.CARRIER_LG_UPLUS: default_umts_operator_network_tbl
}
operator_network_tbl_by_phone_type = {
tel_defines.PHONE_TYPE_GSM: default_umts_operator_network_tbl,
@@ -653,7 +692,10 @@
tel_defines.CARRIER_VZW: cdma_allowable_network_preference_tbl,
tel_defines.CARRIER_SPT: cdma_allowable_network_preference_tbl,
tel_defines.CARRIER_EEUK: umts_allowable_network_preference_tbl,
- tel_defines.CARRIER_VFUK: umts_allowable_network_preference_tbl
+ tel_defines.CARRIER_VFUK: umts_allowable_network_preference_tbl,
+ tel_defines.CARRIER_KT: umts_allowable_network_preference_tbl,
+ tel_defines.CARRIER_SKT: umts_allowable_network_preference_tbl,
+ tel_defines.CARRIER_LG_UPLUS: umts_allowable_network_preference_tbl
}
allowable_network_preference_tbl_by_phone_type = {
tel_defines.PHONE_TYPE_GSM: umts_allowable_network_preference_tbl,
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_message_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_message_utils.py
new file mode 100644
index 0000000..21c418f
--- /dev/null
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_message_utils.py
@@ -0,0 +1,1839 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - Google
+#
+# 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 time
+from queue import Empty
+from acts import signals
+from acts.utils import rand_ascii_str
+from acts.libs.utils.multithread import multithread_func
+from acts.libs.utils.multithread import run_multithread_func
+from acts_contrib.test_utils.tel.tel_defines import EventCallStateChanged
+from acts_contrib.test_utils.tel.tel_defines import EventMmsSentFailure
+from acts_contrib.test_utils.tel.tel_defines import EventMmsSentSuccess
+from acts_contrib.test_utils.tel.tel_defines import EventMmsDownloaded
+from acts_contrib.test_utils.tel.tel_defines import EventSmsDeliverFailure
+from acts_contrib.test_utils.tel.tel_defines import EventSmsDeliverSuccess
+from acts_contrib.test_utils.tel.tel_defines import EventSmsReceived
+from acts_contrib.test_utils.tel.tel_defines import EventSmsSentFailure
+from acts_contrib.test_utils.tel.tel_defines import EventSmsSentSuccess
+from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND
+from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_SENT_SUCCESS_IN_COLLISION
+from acts_contrib.test_utils.tel.tel_defines import SMS_OVER_WIFI_PROVIDERS
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
+from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_on_rat
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_message_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_message
+from acts_contrib.test_utils.tel.tel_test_utils import CallResult
+from acts_contrib.test_utils.tel.tel_test_utils import TelResultWrapper
+from acts_contrib.test_utils.tel.tel_test_utils import check_phone_number_match
+from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call
+from acts_contrib.test_utils.tel.tel_voice_utils import last_call_drop_reason
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_on_rat
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call_for_subscription
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_in_call_active
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_call_end
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_call_offhook_for_subscription
+from acts_contrib.test_utils.tel.tel_video_utils import is_phone_in_call_video_bidirectional
+from acts_contrib.test_utils.tel.tel_video_utils import video_call_setup_teardown
+from acts_contrib.test_utils.tel.tel_video_utils import phone_idle_video
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+
+
+def send_message_with_random_message_body(
+ log, ad_mo, ad_mt, msg_type='sms', long_msg=False, mms_expected_result=True):
+ """Test SMS/MMS between two phones.
+ Returns:
+ True if success.
+ False if failed.
+ """
+ message_lengths = (50, 160, 180)
+
+ if long_msg:
+ message_lengths = (800, 1600)
+ message_lengths_of_jp_carriers = (800, 1530)
+ sender_message_sub_id = get_outgoing_message_sub_id(ad_mo)
+ sender_mcc = ad_mo.telephony["subscription"][sender_message_sub_id]["mcc"]
+ if str(sender_mcc) in ["440", "441"]:
+ message_lengths = message_lengths_of_jp_carriers
+
+ if msg_type == 'sms':
+ for length in message_lengths:
+ message_array = [rand_ascii_str(length)]
+ if not sms_send_receive_verify(log, ad_mo, ad_mt, message_array):
+ ad_mo.log.error("SMS of length %s test failed", length)
+ return False
+ else:
+ ad_mo.log.info("SMS of length %s test succeeded", length)
+ log.info("SMS test of length %s characters succeeded.",
+ message_lengths)
+ elif msg_type == 'mms':
+ is_roaming = False
+ for ad in [ad_mo, ad_mt]:
+ ad.sms_over_wifi = False
+ # verizon supports sms over wifi. will add more carriers later
+ for sub in ad.telephony["subscription"].values():
+ if sub["operator"] in SMS_OVER_WIFI_PROVIDERS:
+ ad.sms_over_wifi = True
+
+ if getattr(ad, 'roaming', False):
+ is_roaming = True
+
+ if is_roaming:
+ # roaming device does not allow message of length 180
+ message_lengths = (50, 160)
+
+ for length in message_lengths:
+ message_array = [("Test Message", rand_ascii_str(length), None)]
+ result = True
+ if not mms_send_receive_verify(
+ log,
+ ad_mo,
+ ad_mt,
+ message_array,
+ expected_result=mms_expected_result):
+
+ if mms_expected_result is True:
+ if ad_mo.droid.telecomIsInCall() or ad_mt.droid.telecomIsInCall():
+ if not mms_receive_verify_after_call_hangup(
+ log, ad_mo, ad_mt, message_array):
+ result = False
+ else:
+ result = False
+
+ if not result:
+ log.error("MMS of body length %s test failed", length)
+ return False
+ else:
+ log.info("MMS of body length %s test succeeded", length)
+ log.info("MMS test of body lengths %s succeeded", message_lengths)
+ return True
+
+def message_test(
+ log,
+ ad_mo,
+ ad_mt,
+ mo_rat='general',
+ mt_rat='general',
+ msg_type='sms',
+ long_msg=False,
+ mms_expected_result=True,
+ msg_in_call=False,
+ video_or_voice='voice',
+ is_airplane_mode=False,
+ wfc_mode=None,
+ wifi_ssid=None,
+ wifi_pwd=None):
+
+ mo_phone_setup_argv = (
+ log, ad_mo, 'general', None, False, None, None, None, None, 'sms')
+ mt_phone_setup_argv = (
+ log, ad_mt, 'general', None, False, None, None, None, None, 'sms')
+ verify_caller_func = None
+ verify_callee_func = None
+
+ if mo_rat:
+ mo_phone_setup_argv = (
+ log,
+ ad_mo,
+ mo_rat,
+ None,
+ is_airplane_mode,
+ wfc_mode,
+ wifi_ssid,
+ wifi_pwd,
+ None,
+ 'sms')
+ verify_caller_func = is_phone_in_call_on_rat(
+ log, ad_mo, rat=mo_rat, only_return_fn=True)
+
+ if mt_rat:
+ mt_phone_setup_argv = (
+ log,
+ ad_mt,
+ mt_rat,
+ None,
+ is_airplane_mode,
+ wfc_mode,
+ wifi_ssid,
+ wifi_pwd,
+ None,
+ 'sms')
+ verify_callee_func = is_phone_in_call_on_rat(
+ log, ad_mo, rat=mt_rat, only_return_fn=True)
+
+ tasks = [(phone_setup_on_rat, mo_phone_setup_argv),
+ (phone_setup_on_rat, mt_phone_setup_argv)]
+ if not multithread_func(log, tasks):
+ log.error("Phone Failed to Set Up Properly.")
+ return False
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+
+ if wifi_ssid:
+ if not wfc_mode or wfc_mode == WFC_MODE_DISABLED:
+ tasks = [(ensure_wifi_connected, (log, ad_mo, wifi_ssid, wifi_pwd)),
+ (ensure_wifi_connected, (log, ad_mt, wifi_ssid, wifi_pwd))]
+ if not multithread_func(log, tasks):
+ log.error("Failed to connected to Wi-Fi.")
+ return False
+
+ if msg_in_call:
+ if video_or_voice == 'voice':
+ if not call_setup_teardown(
+ log,
+ ad_mo,
+ ad_mt,
+ ad_hangup=None,
+ verify_caller_func=verify_caller_func,
+ verify_callee_func=verify_callee_func):
+ log.error("Failed to setup a voice call")
+ return False
+ elif video_or_voice == 'video':
+ tasks = [
+ (phone_idle_video, (log, ad_mo)),
+ (phone_idle_video, (log, ad_mt))]
+ if not multithread_func(log, tasks):
+ log.error("Phone Failed to Set Up Properly.")
+ return False
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+ if not video_call_setup_teardown(
+ log,
+ ad_mo,
+ ad_mt,
+ None,
+ video_state=VT_STATE_BIDIRECTIONAL,
+ verify_caller_func=is_phone_in_call_video_bidirectional,
+ verify_callee_func=is_phone_in_call_video_bidirectional):
+ log.error("Failed to setup a video call")
+ return False
+
+ result = True
+ if not send_message_with_random_message_body(
+ log, ad_mo, ad_mt, msg_type, long_msg, mms_expected_result):
+ log.error("Test failed.")
+ result = False
+
+ if msg_in_call:
+ if not hangup_call(log, ad_mo):
+ ad_mo.log.info("Failed to hang up call!")
+ result = False
+
+ return result
+
+def sms_send_receive_verify(log,
+ ad_tx,
+ ad_rx,
+ array_message,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
+ expected_result=True,
+ slot_id_rx=None):
+ """Send SMS, receive SMS, and verify content and sender's number.
+
+ Send (several) SMS from droid_tx to droid_rx.
+ Verify SMS is sent, delivered and received.
+ Verify received content and sender's number are correct.
+
+ Args:
+ log: Log object.
+ ad_tx: Sender's Android Device Object
+ ad_rx: Receiver's Android Device Object
+ array_message: the array of message to send/receive
+ slot_id_rx: the slot on the Receiver's android device (0/1)
+ """
+ subid_tx = get_outgoing_message_sub_id(ad_tx)
+ if slot_id_rx is None:
+ subid_rx = get_incoming_message_sub_id(ad_rx)
+ else:
+ subid_rx = get_subid_from_slot_index(log, ad_rx, slot_id_rx)
+
+ result = sms_send_receive_verify_for_subscription(
+ log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time)
+ if result != expected_result:
+ log_messaging_screen_shot(ad_tx, test_name="sms_tx")
+ log_messaging_screen_shot(ad_rx, test_name="sms_rx")
+ return result == expected_result
+
+def sms_send_receive_verify_for_subscription(
+ log,
+ ad_tx,
+ ad_rx,
+ subid_tx,
+ subid_rx,
+ array_message,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
+ """Send SMS, receive SMS, and verify content and sender's number.
+
+ Send (several) SMS from droid_tx to droid_rx.
+ Verify SMS is sent, delivered and received.
+ Verify received content and sender's number are correct.
+
+ Args:
+ log: Log object.
+ ad_tx: Sender's Android Device Object..
+ ad_rx: Receiver's Android Device Object.
+ subid_tx: Sender's subscription ID to be used for SMS
+ subid_rx: Receiver's subscription ID to be used for SMS
+ array_message: the array of message to send/receive
+ """
+ phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
+ phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
+
+ for ad in (ad_tx, ad_rx):
+ if not getattr(ad, "messaging_droid", None):
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+ else:
+ try:
+ if not ad.messaging_droid.is_live:
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+ else:
+ ad.messaging_ed.clear_all_events()
+ ad.messaging_droid.logI(
+ "Start sms_send_receive_verify_for_subscription test")
+ except Exception:
+ ad.log.info("Create new sl4a session for messaging")
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+
+ for text in array_message:
+ length = len(text)
+ ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
+ phonenumber_tx, phonenumber_rx, length, text)
+ try:
+ ad_rx.messaging_ed.clear_events(EventSmsReceived)
+ ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
+ ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
+ ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
+ time.sleep(1) #sleep 100ms after starting event tracking
+ ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
+ ad_rx.messaging_droid.logI("Expecting SMS of length %s" % length)
+ ad_tx.messaging_droid.smsSendTextMessage(phonenumber_rx, text,
+ True)
+ try:
+ events = ad_tx.messaging_ed.pop_events(
+ "(%s|%s|%s|%s)" %
+ (EventSmsSentSuccess, EventSmsSentFailure,
+ EventSmsDeliverSuccess,
+ EventSmsDeliverFailure), max_wait_time)
+ for event in events:
+ ad_tx.log.info("Got event %s", event["name"])
+ if event["name"] == EventSmsSentFailure or event["name"] == EventSmsDeliverFailure:
+ if event.get("data") and event["data"].get("Reason"):
+ ad_tx.log.error("%s with reason: %s",
+ event["name"],
+ event["data"]["Reason"])
+ return False
+ elif event["name"] == EventSmsSentSuccess or event["name"] == EventSmsDeliverSuccess:
+ break
+ except Empty:
+ ad_tx.log.error("No %s or %s event for SMS of length %s.",
+ EventSmsSentSuccess, EventSmsSentFailure,
+ length)
+ return False
+
+ if not wait_for_matching_sms(
+ log,
+ ad_rx,
+ phonenumber_tx,
+ text,
+ max_wait_time,
+ allow_multi_part_long_sms=True):
+ ad_rx.log.error("No matching received SMS of length %s.",
+ length)
+ return False
+ except Exception as e:
+ log.error("Exception error %s", e)
+ raise
+ finally:
+ ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
+ return True
+
+def sms_in_collision_send_receive_verify(
+ log,
+ ad_rx,
+ ad_rx2,
+ ad_tx,
+ ad_tx2,
+ array_message,
+ array_message2,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
+ """Send 2 SMS', receive both SMS', and verify content and sender's number of
+ each SMS.
+
+ Send 2 SMS'. One from ad_tx to ad_rx and the other from ad_tx2 to ad_rx2.
+ When ad_rx is identical to ad_rx2, the scenario of SMS' in collision can
+ be tested.
+ Verify both SMS' are sent, delivered and received.
+ Verify received content and sender's number of each SMS is correct.
+
+ Args:
+ log: Log object.
+ ad_tx: Sender's Android Device Object..
+ ad_rx: Receiver's Android Device Object.
+ ad_tx2: 2nd sender's Android Device Object..
+ ad_rx2: 2nd receiver's Android Device Object.
+ array_message: the array of message to send/receive from ad_tx to ad_rx
+ array_message2: the array of message to send/receive from ad_tx2 to
+ ad_rx2
+ max_wait_time: Max time to wait for reception of SMS
+ """
+ rx_sub_id = get_outgoing_message_sub_id(ad_rx)
+ rx2_sub_id = get_outgoing_message_sub_id(ad_rx2)
+
+ _, tx_sub_id, _ = get_subid_on_same_network_of_host_ad(
+ [ad_rx, ad_tx, ad_tx2],
+ host_sub_id=rx_sub_id)
+ set_subid_for_message(ad_tx, tx_sub_id)
+
+ _, _, tx2_sub_id = get_subid_on_same_network_of_host_ad(
+ [ad_rx2, ad_tx, ad_tx2],
+ host_sub_id=rx2_sub_id)
+ set_subid_for_message(ad_tx2, tx2_sub_id)
+
+ if not sms_in_collision_send_receive_verify_for_subscription(
+ log,
+ ad_tx,
+ ad_tx2,
+ ad_rx,
+ ad_rx2,
+ tx_sub_id,
+ tx2_sub_id,
+ rx_sub_id,
+ rx_sub_id,
+ array_message,
+ array_message2,
+ max_wait_time):
+ log_messaging_screen_shot(
+ ad_rx, test_name="sms rx subid: %s" % rx_sub_id)
+ log_messaging_screen_shot(
+ ad_rx2, test_name="sms rx2 subid: %s" % rx2_sub_id)
+ log_messaging_screen_shot(
+ ad_tx, test_name="sms tx subid: %s" % tx_sub_id)
+ log_messaging_screen_shot(
+ ad_tx2, test_name="sms tx subid: %s" % tx2_sub_id)
+ return False
+ return True
+
+def sms_in_collision_send_receive_verify_for_subscription(
+ log,
+ ad_tx,
+ ad_tx2,
+ ad_rx,
+ ad_rx2,
+ subid_tx,
+ subid_tx2,
+ subid_rx,
+ subid_rx2,
+ array_message,
+ array_message2,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
+ """Send 2 SMS', receive both SMS', and verify content and sender's number of
+ each SMS.
+
+ Send 2 SMS'. One from ad_tx to ad_rx and the other from ad_tx2 to ad_rx2.
+ When ad_rx is identical to ad_rx2, the scenario of SMS' in collision can
+ be tested.
+ Verify both SMS' are sent, delivered and received.
+ Verify received content and sender's number of each SMS is correct.
+
+ Args:
+ log: Log object.
+ ad_tx: Sender's Android Device Object..
+ ad_rx: Receiver's Android Device Object.
+ ad_tx2: 2nd sender's Android Device Object..
+ ad_rx2: 2nd receiver's Android Device Object.
+ subid_tx: Sub ID of ad_tx as default Sub ID for outgoing SMS
+ subid_tx2: Sub ID of ad_tx2 as default Sub ID for outgoing SMS
+ subid_rx: Sub ID of ad_rx as default Sub ID for incoming SMS
+ subid_rx2: Sub ID of ad_rx2 as default Sub ID for incoming SMS
+ array_message: the array of message to send/receive from ad_tx to ad_rx
+ array_message2: the array of message to send/receive from ad_tx2 to
+ ad_rx2
+ max_wait_time: Max time to wait for reception of SMS
+ """
+
+ phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
+ phonenumber_tx2 = ad_tx2.telephony['subscription'][subid_tx2]['phone_num']
+ phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
+ phonenumber_rx2 = ad_rx2.telephony['subscription'][subid_rx2]['phone_num']
+
+ for ad in (ad_tx, ad_tx2, ad_rx, ad_rx2):
+ ad.send_keycode("BACK")
+ if not getattr(ad, "messaging_droid", None):
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+ else:
+ try:
+ if not ad.messaging_droid.is_live:
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+ else:
+ ad.messaging_ed.clear_all_events()
+ ad.messaging_droid.logI(
+ "Start sms_send_receive_verify_for_subscription test")
+ except Exception:
+ ad.log.info("Create new sl4a session for messaging")
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+
+ for text, text2 in zip(array_message, array_message2):
+ length = len(text)
+ length2 = len(text2)
+ ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
+ phonenumber_tx, phonenumber_rx, length, text)
+ ad_tx2.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
+ phonenumber_tx2, phonenumber_rx2, length2, text2)
+
+ try:
+ ad_rx.messaging_ed.clear_events(EventSmsReceived)
+ ad_rx2.messaging_ed.clear_events(EventSmsReceived)
+ ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
+ ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
+ ad_tx2.messaging_ed.clear_events(EventSmsSentSuccess)
+ ad_tx2.messaging_ed.clear_events(EventSmsSentFailure)
+ ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
+ if ad_rx2 != ad_rx:
+ ad_rx2.messaging_droid.smsStartTrackingIncomingSmsMessage()
+ time.sleep(1)
+ ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
+ ad_tx2.messaging_droid.logI("Sending SMS of length %s" % length2)
+ ad_rx.messaging_droid.logI(
+ "Expecting SMS of length %s from %s" % (length, ad_tx.serial))
+ ad_rx2.messaging_droid.logI(
+ "Expecting SMS of length %s from %s" % (length2, ad_tx2.serial))
+
+ tasks = [
+ (ad_tx.messaging_droid.smsSendTextMessage,
+ (phonenumber_rx, text, True)),
+ (ad_tx2.messaging_droid.smsSendTextMessage,
+ (phonenumber_rx2, text2, True))]
+ multithread_func(log, tasks)
+ try:
+ tasks = [
+ (ad_tx.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
+ EventSmsSentSuccess,
+ EventSmsSentFailure,
+ EventSmsDeliverSuccess,
+ EventSmsDeliverFailure), max_wait_time)),
+ (ad_tx2.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
+ EventSmsSentSuccess,
+ EventSmsSentFailure,
+ EventSmsDeliverSuccess,
+ EventSmsDeliverFailure), max_wait_time))
+ ]
+ results = run_multithread_func(log, tasks)
+ res = True
+ _ad = ad_tx
+ for ad, events in [(ad_tx, results[0]),(ad_tx2, results[1])]:
+ _ad = ad
+ for event in events:
+ ad.log.info("Got event %s", event["name"])
+ if event["name"] == EventSmsSentFailure or \
+ event["name"] == EventSmsDeliverFailure:
+ if event.get("data") and event["data"].get("Reason"):
+ ad.log.error("%s with reason: %s",
+ event["name"],
+ event["data"]["Reason"])
+ res = False
+ elif event["name"] == EventSmsSentSuccess or \
+ event["name"] == EventSmsDeliverSuccess:
+ break
+ if not res:
+ return False
+ except Empty:
+ _ad.log.error("No %s or %s event for SMS of length %s.",
+ EventSmsSentSuccess, EventSmsSentFailure,
+ length)
+ return False
+ if ad_rx == ad_rx2:
+ if not wait_for_matching_mt_sms_in_collision(
+ log,
+ ad_rx,
+ phonenumber_tx,
+ phonenumber_tx2,
+ text,
+ text2,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
+
+ ad_rx.log.error(
+ "No matching received SMS of length %s from %s.",
+ length,
+ ad_rx.serial)
+ return False
+ else:
+ if not wait_for_matching_mt_sms_in_collision_with_mo_sms(
+ log,
+ ad_rx,
+ ad_rx2,
+ phonenumber_tx,
+ phonenumber_tx2,
+ text,
+ text2,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
+ return False
+ except Exception as e:
+ log.error("Exception error %s", e)
+ raise
+ finally:
+ ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
+ ad_rx2.messaging_droid.smsStopTrackingIncomingSmsMessage()
+ return True
+
+def sms_rx_power_off_multiple_send_receive_verify(
+ log,
+ ad_rx,
+ ad_tx,
+ ad_tx2,
+ array_message_length,
+ array_message2_length,
+ num_array_message,
+ num_array_message2,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
+
+ rx_sub_id = get_outgoing_message_sub_id(ad_rx)
+
+ _, tx_sub_id, _ = get_subid_on_same_network_of_host_ad(
+ [ad_rx, ad_tx, ad_tx2],
+ host_sub_id=rx_sub_id)
+ set_subid_for_message(ad_tx, tx_sub_id)
+
+ _, _, tx2_sub_id = get_subid_on_same_network_of_host_ad(
+ [ad_rx, ad_tx, ad_tx2],
+ host_sub_id=rx_sub_id)
+ set_subid_for_message(ad_tx2, tx2_sub_id)
+
+ if not sms_rx_power_off_multiple_send_receive_verify_for_subscription(
+ log,
+ ad_tx,
+ ad_tx2,
+ ad_rx,
+ tx_sub_id,
+ tx2_sub_id,
+ rx_sub_id,
+ rx_sub_id,
+ array_message_length,
+ array_message2_length,
+ num_array_message,
+ num_array_message2):
+ log_messaging_screen_shot(
+ ad_rx, test_name="sms rx subid: %s" % rx_sub_id)
+ log_messaging_screen_shot(
+ ad_tx, test_name="sms tx subid: %s" % tx_sub_id)
+ log_messaging_screen_shot(
+ ad_tx2, test_name="sms tx subid: %s" % tx2_sub_id)
+ return False
+ return True
+
+def sms_rx_power_off_multiple_send_receive_verify_for_subscription(
+ log,
+ ad_tx,
+ ad_tx2,
+ ad_rx,
+ subid_tx,
+ subid_tx2,
+ subid_rx,
+ subid_rx2,
+ array_message_length,
+ array_message2_length,
+ num_array_message,
+ num_array_message2,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
+
+ phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
+ phonenumber_tx2 = ad_tx2.telephony['subscription'][subid_tx2]['phone_num']
+ phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
+ phonenumber_rx2 = ad_rx.telephony['subscription'][subid_rx2]['phone_num']
+
+ if not toggle_airplane_mode(log, ad_rx, True):
+ ad_rx.log.error("Failed to enable Airplane Mode")
+ return False
+ ad_rx.stop_services()
+ ad_rx.log.info("Rebooting......")
+ ad_rx.adb.reboot()
+
+ message_dict = {phonenumber_tx: [], phonenumber_tx2: []}
+ for index in range(max(num_array_message, num_array_message2)):
+ array_message = [rand_ascii_str(array_message_length)]
+ array_message2 = [rand_ascii_str(array_message2_length)]
+ for text, text2 in zip(array_message, array_message2):
+ message_dict[phonenumber_tx].append(text)
+ message_dict[phonenumber_tx2].append(text2)
+ length = len(text)
+ length2 = len(text2)
+
+ ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
+ phonenumber_tx, phonenumber_rx, length, text)
+ ad_tx2.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
+ phonenumber_tx2, phonenumber_rx2, length2, text2)
+
+ try:
+ for ad in (ad_tx, ad_tx2):
+ ad.send_keycode("BACK")
+ if not getattr(ad, "messaging_droid", None):
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+ else:
+ try:
+ if not ad.messaging_droid.is_live:
+ ad.messaging_droid, ad.messaging_ed = \
+ ad.get_droid()
+ ad.messaging_ed.start()
+ else:
+ ad.messaging_ed.clear_all_events()
+ ad.messaging_droid.logI(
+ "Start sms_send_receive_verify_for_subscription"
+ " test")
+ except Exception:
+ ad.log.info("Create new sl4a session for messaging")
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+
+ ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
+ ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
+ ad_tx2.messaging_ed.clear_events(EventSmsSentSuccess)
+ ad_tx2.messaging_ed.clear_events(EventSmsSentFailure)
+
+ if index < num_array_message and index < num_array_message2:
+ ad_tx.messaging_droid.logI(
+ "Sending SMS of length %s" % length)
+ ad_tx2.messaging_droid.logI(
+ "Sending SMS of length %s" % length2)
+ tasks = [
+ (ad_tx.messaging_droid.smsSendTextMessage,
+ (phonenumber_rx, text, True)),
+ (ad_tx2.messaging_droid.smsSendTextMessage,
+ (phonenumber_rx2, text2, True))]
+ multithread_func(log, tasks)
+ else:
+ if index < num_array_message:
+ ad_tx.messaging_droid.logI(
+ "Sending SMS of length %s" % length)
+ ad_tx.messaging_droid.smsSendTextMessage(
+ phonenumber_rx, text, True)
+ if index < num_array_message2:
+ ad_tx2.messaging_droid.logI(
+ "Sending SMS of length %s" % length2)
+ ad_tx2.messaging_droid.smsSendTextMessage(
+ phonenumber_rx2, text2, True)
+
+ try:
+ if index < num_array_message and index < num_array_message2:
+ tasks = [
+ (ad_tx.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
+ EventSmsSentSuccess,
+ EventSmsSentFailure,
+ EventSmsDeliverSuccess,
+ EventSmsDeliverFailure),
+ max_wait_time)),
+ (ad_tx2.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
+ EventSmsSentSuccess,
+ EventSmsSentFailure,
+ EventSmsDeliverSuccess,
+ EventSmsDeliverFailure),
+ max_wait_time))
+ ]
+ results = run_multithread_func(log, tasks)
+ res = True
+ _ad = ad_tx
+ for ad, events in [
+ (ad_tx, results[0]), (ad_tx2, results[1])]:
+ _ad = ad
+ for event in events:
+ ad.log.info("Got event %s", event["name"])
+ if event["name"] == EventSmsSentFailure or \
+ event["name"] == EventSmsDeliverFailure:
+ if event.get("data") and \
+ event["data"].get("Reason"):
+ ad.log.error("%s with reason: %s",
+ event["name"],
+ event["data"]["Reason"])
+ res = False
+ elif event["name"] == EventSmsSentSuccess or \
+ event["name"] == EventSmsDeliverSuccess:
+ break
+ if not res:
+ return False
+ else:
+ if index < num_array_message:
+ result = ad_tx.messaging_ed.pop_events(
+ "(%s|%s|%s|%s)" % (
+ EventSmsSentSuccess,
+ EventSmsSentFailure,
+ EventSmsDeliverSuccess,
+ EventSmsDeliverFailure),
+ max_wait_time)
+ res = True
+ _ad = ad_tx
+ for ad, events in [(ad_tx, result)]:
+ _ad = ad
+ for event in events:
+ ad.log.info("Got event %s", event["name"])
+ if event["name"] == EventSmsSentFailure or \
+ event["name"] == EventSmsDeliverFailure:
+ if event.get("data") and \
+ event["data"].get("Reason"):
+ ad.log.error(
+ "%s with reason: %s",
+ event["name"],
+ event["data"]["Reason"])
+ res = False
+ elif event["name"] == EventSmsSentSuccess \
+ or event["name"] == EventSmsDeliverSuccess:
+ break
+ if not res:
+ return False
+ if index < num_array_message2:
+ result = ad_tx2.messaging_ed.pop_events(
+ "(%s|%s|%s|%s)" % (
+ EventSmsSentSuccess,
+ EventSmsSentFailure,
+ EventSmsDeliverSuccess,
+ EventSmsDeliverFailure),
+ max_wait_time)
+ res = True
+ _ad = ad_tx2
+ for ad, events in [(ad_tx2, result)]:
+ _ad = ad
+ for event in events:
+ ad.log.info("Got event %s", event["name"])
+ if event["name"] == EventSmsSentFailure or \
+ event["name"] == EventSmsDeliverFailure:
+ if event.get("data") and \
+ event["data"].get("Reason"):
+ ad.log.error(
+ "%s with reason: %s",
+ event["name"],
+ event["data"]["Reason"])
+ res = False
+ elif event["name"] == EventSmsSentSuccess \
+ or event["name"] == EventSmsDeliverSuccess:
+ break
+ if not res:
+ return False
+
+
+ except Empty:
+ _ad.log.error("No %s or %s event for SMS of length %s.",
+ EventSmsSentSuccess, EventSmsSentFailure,
+ length)
+ return False
+
+ except Exception as e:
+ log.error("Exception error %s", e)
+ raise
+
+ ad_rx.wait_for_boot_completion()
+ ad_rx.root_adb()
+ ad_rx.start_services(skip_setup_wizard=False)
+
+ output = ad_rx.adb.logcat("-t 1")
+ match = re.search(r"\d+-\d+\s\d+:\d+:\d+.\d+", output)
+ if match:
+ ad_rx.test_log_begin_time = match.group(0)
+
+ ad_rx.messaging_droid, ad_rx.messaging_ed = ad_rx.get_droid()
+ ad_rx.messaging_ed.start()
+ ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
+ time.sleep(1) #sleep 100ms after starting event tracking
+
+ if not toggle_airplane_mode(log, ad_rx, False):
+ ad_rx.log.error("Failed to disable Airplane Mode")
+ return False
+
+ res = True
+ try:
+ if not wait_for_matching_multiple_sms(log,
+ ad_rx,
+ phonenumber_tx,
+ phonenumber_tx2,
+ messages=message_dict,
+ max_wait_time=max_wait_time):
+ res = False
+ except Exception as e:
+ log.error("Exception error %s", e)
+ raise
+ finally:
+ ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
+
+ return res
+
+def is_sms_match(event, phonenumber_tx, text):
+ """Return True if 'text' equals to event['data']['Text']
+ and phone number match.
+
+ Args:
+ event: Event object to verify.
+ phonenumber_tx: phone number for sender.
+ text: text string to verify.
+
+ Returns:
+ Return True if 'text' equals to event['data']['Text']
+ and phone number match.
+ """
+ return (check_phone_number_match(event['data']['Sender'], phonenumber_tx)
+ and event['data']['Text'].strip() == text)
+
+def is_sms_partial_match(event, phonenumber_tx, text):
+ """Return True if 'text' starts with event['data']['Text']
+ and phone number match.
+
+ Args:
+ event: Event object to verify.
+ phonenumber_tx: phone number for sender.
+ text: text string to verify.
+
+ Returns:
+ Return True if 'text' starts with event['data']['Text']
+ and phone number match.
+ """
+ event_text = event['data']['Text'].strip()
+ if event_text.startswith("("):
+ event_text = event_text.split(")")[-1]
+ return (check_phone_number_match(event['data']['Sender'], phonenumber_tx)
+ and text.startswith(event_text))
+
+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):
+ return True
+ return False
+
+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:
+ return True
+ return False
+
+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:
+ return True
+
+ for txt in texts2:
+ 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=[]):
+ 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):
+ return True
+
+ for txt in texts2:
+ if check_phone_number_match(
+ event['data']['Sender'], phonenumber_tx2) and \
+ txt.startswith(event_text):
+ return True
+
+ return False
+
+def wait_for_matching_sms(log,
+ ad_rx,
+ phonenumber_tx,
+ text,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
+ allow_multi_part_long_sms=True):
+ """Wait for matching incoming SMS.
+
+ Args:
+ log: Log object.
+ ad_rx: Receiver's Android Device Object
+ phonenumber_tx: Sender's phone number.
+ text: SMS content string.
+ allow_multi_part_long_sms: is long SMS allowed to be received as
+ multiple short SMS. This is optional, default value is True.
+
+ Returns:
+ True if matching incoming SMS is received.
+ """
+ if not allow_multi_part_long_sms:
+ try:
+ ad_rx.messaging_ed.wait_for_event(EventSmsReceived, is_sms_match,
+ max_wait_time, phonenumber_tx,
+ text)
+ ad_rx.log.info("Got event %s", EventSmsReceived)
+ return True
+ except Empty:
+ ad_rx.log.error("No matched SMS received event.")
+ return False
+ else:
+ try:
+ received_sms = ''
+ remaining_text = text
+ while (remaining_text != ''):
+ event = ad_rx.messaging_ed.wait_for_event(
+ EventSmsReceived, is_sms_partial_match, max_wait_time,
+ phonenumber_tx, remaining_text)
+ event_text = event['data']['Text'].split(")")[-1].strip()
+ event_text_length = len(event_text)
+ ad_rx.log.info("Got event %s of text length %s from %s",
+ EventSmsReceived, event_text_length,
+ phonenumber_tx)
+ remaining_text = remaining_text[event_text_length:]
+ received_sms += event_text
+ ad_rx.log.info("Received SMS of length %s", len(received_sms))
+ return True
+ except Empty:
+ ad_rx.log.error(
+ "Missing SMS received event of text length %s from %s",
+ len(remaining_text), phonenumber_tx)
+ if received_sms != '':
+ ad_rx.log.error(
+ "Only received partial matched SMS of length %s",
+ len(received_sms))
+ return False
+
+def wait_for_matching_mt_sms_in_collision(log,
+ ad_rx,
+ phonenumber_tx,
+ phonenumber_tx2,
+ text,
+ text2,
+ allow_multi_part_long_sms=True,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
+
+ if not allow_multi_part_long_sms:
+ try:
+ ad_rx.messaging_ed.wait_for_event(
+ EventSmsReceived,
+ is_sms_in_collision_match,
+ max_wait_time,
+ phonenumber_tx,
+ phonenumber_tx2,
+ text,
+ text2)
+ ad_rx.log.info("Got event %s", EventSmsReceived)
+ return True
+ except Empty:
+ ad_rx.log.error("No matched SMS received event.")
+ return False
+ else:
+ try:
+ received_sms = ''
+ received_sms2 = ''
+ remaining_text = text
+ remaining_text2 = text2
+ while (remaining_text != '' or remaining_text2 != ''):
+ event = ad_rx.messaging_ed.wait_for_event(
+ EventSmsReceived,
+ is_sms_in_collision_partial_match,
+ max_wait_time,
+ phonenumber_tx,
+ phonenumber_tx2,
+ remaining_text,
+ remaining_text2)
+ event_text = event['data']['Text'].split(")")[-1].strip()
+ event_text_length = len(event_text)
+
+ if event_text in remaining_text:
+ ad_rx.log.info("Got event %s of text length %s from %s",
+ EventSmsReceived, event_text_length,
+ phonenumber_tx)
+ remaining_text = remaining_text[event_text_length:]
+ received_sms += event_text
+ elif event_text in remaining_text2:
+ ad_rx.log.info("Got event %s of text length %s from %s",
+ EventSmsReceived, event_text_length,
+ phonenumber_tx2)
+ remaining_text2 = remaining_text2[event_text_length:]
+ received_sms2 += event_text
+
+ ad_rx.log.info("Received SMS of length %s", len(received_sms))
+ ad_rx.log.info("Received SMS of length %s", len(received_sms2))
+ return True
+ except Empty:
+ ad_rx.log.error(
+ "Missing SMS received event.")
+ if received_sms != '':
+ ad_rx.log.error(
+ "Only received partial matched SMS of length %s from %s",
+ len(received_sms), phonenumber_tx)
+ if received_sms2 != '':
+ ad_rx.log.error(
+ "Only received partial matched SMS of length %s from %s",
+ len(received_sms2), phonenumber_tx2)
+ return False
+
+def wait_for_matching_mt_sms_in_collision_with_mo_sms(log,
+ ad_rx,
+ ad_rx2,
+ phonenumber_tx,
+ phonenumber_tx2,
+ text,
+ text2,
+ allow_multi_part_long_sms=True,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
+
+ if not allow_multi_part_long_sms:
+ result = True
+ try:
+ ad_rx.messaging_ed.wait_for_call_offhook_event(
+ EventSmsReceived,
+ is_sms_match,
+ max_wait_time,
+ phonenumber_tx,
+ text)
+ ad_rx.log.info("Got event %s", EventSmsReceived)
+ except Empty:
+ ad_rx.log.error("No matched SMS received event.")
+ result = False
+
+ try:
+ ad_rx2.messaging_ed.wait_for_call_offhook_event(
+ EventSmsReceived,
+ is_sms_match,
+ max_wait_time,
+ phonenumber_tx2,
+ text2)
+ ad_rx2.log.info("Got event %s", EventSmsReceived)
+ except Empty:
+ ad_rx2.log.error("No matched SMS received event.")
+ result = False
+
+ return result
+ else:
+ result = True
+ try:
+ received_sms = ''
+ remaining_text = text
+ while remaining_text != '':
+ event = ad_rx.messaging_ed.wait_for_event(
+ EventSmsReceived, is_sms_partial_match, max_wait_time,
+ phonenumber_tx, remaining_text)
+ event_text = event['data']['Text'].split(")")[-1].strip()
+ event_text_length = len(event_text)
+
+ if event_text in remaining_text:
+ ad_rx.log.info("Got event %s of text length %s from %s",
+ EventSmsReceived, event_text_length,
+ phonenumber_tx)
+ remaining_text = remaining_text[event_text_length:]
+ received_sms += event_text
+
+ ad_rx.log.info("Received SMS of length %s", len(received_sms))
+ except Empty:
+ ad_rx.log.error(
+ "Missing SMS received event.")
+ if received_sms != '':
+ ad_rx.log.error(
+ "Only received partial matched SMS of length %s from %s",
+ len(received_sms), phonenumber_tx)
+ result = False
+
+ try:
+ received_sms2 = ''
+ remaining_text2 = text2
+ while remaining_text2 != '':
+ event2 = ad_rx2.messaging_ed.wait_for_event(
+ EventSmsReceived, is_sms_partial_match, max_wait_time,
+ phonenumber_tx2, remaining_text2)
+ event_text2 = event2['data']['Text'].split(")")[-1].strip()
+ event_text_length2 = len(event_text2)
+
+ if event_text2 in remaining_text2:
+ ad_rx2.log.info("Got event %s of text length %s from %s",
+ EventSmsReceived, event_text_length2,
+ phonenumber_tx2)
+ remaining_text2 = remaining_text2[event_text_length2:]
+ received_sms2 += event_text2
+
+ ad_rx2.log.info("Received SMS of length %s", len(received_sms2))
+ except Empty:
+ ad_rx2.log.error(
+ "Missing SMS received event.")
+ if received_sms2 != '':
+ ad_rx2.log.error(
+ "Only received partial matched SMS of length %s from %s",
+ len(received_sms2), phonenumber_tx2)
+ result = False
+
+ return result
+
+def wait_for_matching_multiple_sms(log,
+ ad_rx,
+ phonenumber_tx,
+ phonenumber_tx2,
+ messages={},
+ allow_multi_part_long_sms=True,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
+
+ if not allow_multi_part_long_sms:
+ try:
+ ad_rx.messaging_ed.wait_for_event(
+ EventSmsReceived,
+ is_sms_match_among_multiple_sms,
+ max_wait_time,
+ phonenumber_tx,
+ phonenumber_tx2,
+ messages[phonenumber_tx],
+ messages[phonenumber_tx2])
+ ad_rx.log.info("Got event %s", EventSmsReceived)
+ return True
+ except Empty:
+ ad_rx.log.error("No matched SMS received event.")
+ return False
+ else:
+ all_msgs = []
+ for tx, msgs in messages.items():
+ for msg in msgs:
+ all_msgs.append([tx, msg, msg, ''])
+
+ all_msgs_copy = all_msgs.copy()
+
+ try:
+ while (all_msgs != []):
+ event = ad_rx.messaging_ed.wait_for_event(
+ EventSmsReceived,
+ is_sms_partial_match_among_multiple_sms,
+ max_wait_time,
+ phonenumber_tx,
+ phonenumber_tx2,
+ messages[phonenumber_tx],
+ messages[phonenumber_tx2])
+ event_text = event['data']['Text'].split(")")[-1].strip()
+ event_text_length = len(event_text)
+
+ for msg in all_msgs_copy:
+ if event_text in msg[2]:
+ ad_rx.log.info("Got event %s of text length %s from %s",
+ EventSmsReceived, event_text_length,
+ msg[0])
+ msg[2] = msg[2][event_text_length:]
+ msg[3] += event_text
+
+ if msg[2] == "":
+ all_msgs.remove(msg)
+
+ ad_rx.log.info("Received all SMS' sent when power-off.")
+ except Empty:
+ ad_rx.log.error(
+ "Missing SMS received event.")
+
+ for msg in all_msgs_copy:
+ if msg[3] != '':
+ ad_rx.log.error(
+ "Only received partial matched SMS of length %s from %s",
+ len(msg[3]), msg[0])
+ return False
+
+ return True
+
+def wait_for_sending_sms(ad_tx, max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
+ try:
+ events = ad_tx.messaging_ed.pop_events(
+ "(%s|%s|%s|%s)" %
+ (EventSmsSentSuccess, EventSmsSentFailure,
+ EventSmsDeliverSuccess,
+ EventSmsDeliverFailure), max_wait_time)
+ for event in events:
+ ad_tx.log.info("Got event %s", event["name"])
+ if event["name"] == EventSmsSentFailure or \
+ event["name"] == EventSmsDeliverFailure:
+ if event.get("data") and event["data"].get("Reason"):
+ ad_tx.log.error("%s with reason: %s",
+ event["name"],
+ event["data"]["Reason"])
+ return False
+ elif event["name"] == EventSmsSentSuccess or \
+ event["name"] == EventSmsDeliverSuccess:
+ return True
+ except Empty:
+ ad_tx.log.error("No %s or %s event for SMS.",
+ EventSmsSentSuccess, EventSmsSentFailure)
+ return False
+
+def voice_call_in_collision_with_mt_sms_msim(
+ log,
+ ad_primary,
+ ad_sms,
+ ad_voice,
+ sms_subid_ad_primary,
+ sms_subid_ad_sms,
+ voice_subid_ad_primary,
+ voice_subid_ad_voice,
+ array_message,
+ ad_hangup=None,
+ verify_caller_func=None,
+ verify_callee_func=None,
+ call_direction="mo",
+ wait_time_in_call=WAIT_TIME_IN_CALL,
+ incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
+ dialing_number_length=None,
+ video_state=None):
+
+ ad_tx = ad_sms
+ ad_rx = ad_primary
+ subid_tx = sms_subid_ad_sms
+ subid_rx = sms_subid_ad_primary
+
+ if call_direction == "mo":
+ ad_caller = ad_primary
+ ad_callee = ad_voice
+ subid_caller = voice_subid_ad_primary
+ subid_callee = voice_subid_ad_voice
+ elif call_direction == "mt":
+ ad_callee = ad_primary
+ ad_caller = ad_voice
+ subid_callee = voice_subid_ad_primary
+ subid_caller = voice_subid_ad_voice
+
+
+ phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
+ phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
+
+ tel_result_wrapper = TelResultWrapper(CallResult('SUCCESS'))
+
+ for ad in (ad_tx, ad_rx):
+ ad.send_keycode("BACK")
+ if not getattr(ad, "messaging_droid", None):
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+ else:
+ try:
+ if not ad.messaging_droid.is_live:
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+ else:
+ ad.messaging_ed.clear_all_events()
+ except Exception:
+ ad.log.info("Create new sl4a session for messaging")
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+
+ if not verify_caller_func:
+ verify_caller_func = is_phone_in_call
+ if not verify_callee_func:
+ verify_callee_func = is_phone_in_call
+
+ caller_number = ad_caller.telephony['subscription'][subid_caller][
+ 'phone_num']
+ callee_number = ad_callee.telephony['subscription'][subid_callee][
+ 'phone_num']
+ if dialing_number_length:
+ skip_test = False
+ trunc_position = 0 - int(dialing_number_length)
+ try:
+ caller_area_code = caller_number[:trunc_position]
+ callee_area_code = callee_number[:trunc_position]
+ callee_dial_number = callee_number[trunc_position:]
+ except:
+ skip_test = True
+ if caller_area_code != callee_area_code:
+ skip_test = True
+ if skip_test:
+ msg = "Cannot make call from %s to %s by %s digits" % (
+ caller_number, callee_number, dialing_number_length)
+ ad_caller.log.info(msg)
+ raise signals.TestSkip(msg)
+ else:
+ callee_number = callee_dial_number
+
+ msg = "Call from %s to %s" % (caller_number, callee_number)
+ if video_state:
+ msg = "Video %s" % msg
+ video = True
+ else:
+ video = False
+ if ad_hangup:
+ msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
+ ad_caller.log.info(msg)
+
+ for ad in (ad_caller, ad_callee):
+ call_ids = ad.droid.telecomCallGetCallIds()
+ setattr(ad, "call_ids", call_ids)
+ if call_ids:
+ ad.log.info("Pre-exist CallId %s before making call", call_ids)
+
+ ad_caller.ed.clear_events(EventCallStateChanged)
+ call_begin_time = get_device_epoch_time(ad)
+ ad_caller.droid.telephonyStartTrackingCallStateForSubscription(subid_caller)
+
+ for text in array_message:
+ length = len(text)
+ ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
+ phonenumber_tx, phonenumber_rx, length, text)
+ try:
+ ad_rx.messaging_ed.clear_events(EventSmsReceived)
+ ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
+ ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
+ ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
+ time.sleep(1) #sleep 100ms after starting event tracking
+ ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
+ ad_rx.messaging_droid.logI("Expecting SMS of length %s" % length)
+ ad_caller.log.info("Make a phone call to %s", callee_number)
+
+ tasks = [
+ (ad_tx.messaging_droid.smsSendTextMessage,
+ (phonenumber_rx, text, True)),
+ (ad_caller.droid.telecomCallNumber,
+ (callee_number, video))]
+
+ run_multithread_func(log, tasks)
+
+ try:
+ # Verify OFFHOOK state
+ if not wait_for_call_offhook_for_subscription(
+ log,
+ ad_caller,
+ subid_caller,
+ event_tracking_started=True):
+ ad_caller.log.info(
+ "sub_id %s not in call offhook state", subid_caller)
+ last_call_drop_reason(ad_caller, begin_time=call_begin_time)
+
+ ad_caller.log.error("Initiate call failed.")
+ tel_result_wrapper.result_value = CallResult(
+ 'INITIATE_FAILED')
+ return tel_result_wrapper
+ else:
+ ad_caller.log.info("Caller initate call successfully")
+ finally:
+ ad_caller.droid.telephonyStopTrackingCallStateChangeForSubscription(
+ subid_caller)
+ if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
+ ad_caller.droid.telecomShowInCallScreen()
+ elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
+ ad_caller.droid.showHomeScreen()
+
+ if not wait_and_answer_call_for_subscription(
+ log,
+ ad_callee,
+ subid_callee,
+ incoming_number=caller_number,
+ caller=ad_caller,
+ incall_ui_display=incall_ui_display,
+ video_state=video_state):
+ ad_callee.log.error("Answer call fail.")
+ tel_result_wrapper.result_value = CallResult(
+ 'NO_RING_EVENT_OR_ANSWER_FAILED')
+ return tel_result_wrapper
+ else:
+ ad_callee.log.info("Callee answered the call successfully")
+
+ for ad, call_func in zip([ad_caller, ad_callee],
+ [verify_caller_func, verify_callee_func]):
+ call_ids = ad.droid.telecomCallGetCallIds()
+ new_call_ids = set(call_ids) - set(ad.call_ids)
+ if not new_call_ids:
+ ad.log.error(
+ "No new call ids are found after call establishment")
+ ad.log.error("telecomCallGetCallIds returns %s",
+ ad.droid.telecomCallGetCallIds())
+ tel_result_wrapper.result_value = CallResult(
+ 'NO_CALL_ID_FOUND')
+ for new_call_id in new_call_ids:
+ if not wait_for_in_call_active(ad, call_id=new_call_id):
+ tel_result_wrapper.result_value = CallResult(
+ 'CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT')
+ else:
+ ad.log.info(
+ "callProperties = %s",
+ ad.droid.telecomCallGetProperties(new_call_id))
+
+ if not ad.droid.telecomCallGetAudioState():
+ ad.log.error("Audio is not in call state")
+ tel_result_wrapper.result_value = CallResult(
+ 'AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT')
+
+ if call_func(log, ad):
+ ad.log.info("Call is in %s state", call_func.__name__)
+ else:
+ ad.log.error("Call is not in %s state, voice in RAT %s",
+ call_func.__name__,
+ ad.droid.telephonyGetCurrentVoiceNetworkType())
+ tel_result_wrapper.result_value = CallResult(
+ 'CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT')
+ if not tel_result_wrapper:
+ return tel_result_wrapper
+
+ if not wait_for_sending_sms(
+ ad_tx,
+ max_wait_time=MAX_WAIT_TIME_SMS_SENT_SUCCESS_IN_COLLISION):
+ return False
+
+ tasks = [
+ (wait_for_matching_sms,
+ (log, ad_rx, phonenumber_tx, text,
+ MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION, True)),
+ (wait_for_call_end,
+ (log, ad_caller, ad_callee, ad_hangup, verify_caller_func,
+ verify_callee_func, call_begin_time, 5, tel_result_wrapper,
+ WAIT_TIME_IN_CALL))]
+
+ results = run_multithread_func(log, tasks)
+
+ if not results[0]:
+ ad_rx.log.error("No matching received SMS of length %s.",
+ length)
+ return False
+
+ tel_result_wrapper = results[1]
+
+ except Exception as e:
+ log.error("Exception error %s", e)
+ raise
+ finally:
+ ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
+
+ return tel_result_wrapper
+
+
+def is_mms_match(event, phonenumber_tx, text):
+ """Return True if 'text' equals to event['data']['Text']
+ and phone number match.
+
+ Args:
+ event: Event object to verify.
+ phonenumber_tx: phone number for sender.
+ text: text string to verify.
+
+ Returns:
+ Return True if 'text' equals to event['data']['Text']
+ and phone number match.
+ """
+ #TODO: add mms matching after mms message parser is added in sl4a. b/34276948
+ return True
+
+
+def wait_for_matching_mms(log,
+ ad_rx,
+ phonenumber_tx,
+ text,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
+ """Wait for matching incoming SMS.
+
+ Args:
+ log: Log object.
+ ad_rx: Receiver's Android Device Object
+ phonenumber_tx: Sender's phone number.
+ text: SMS content string.
+ allow_multi_part_long_sms: is long SMS allowed to be received as
+ multiple short SMS. This is optional, default value is True.
+
+ Returns:
+ True if matching incoming SMS is received.
+ """
+ try:
+ #TODO: add mms matching after mms message parser is added in sl4a. b/34276948
+ ad_rx.messaging_ed.wait_for_event(EventMmsDownloaded, is_mms_match,
+ max_wait_time, phonenumber_tx, text)
+ ad_rx.log.info("Got event %s", EventMmsDownloaded)
+ return True
+ except Empty:
+ ad_rx.log.warning("No matched MMS downloaded event.")
+ return False
+
+
+def mms_send_receive_verify(log,
+ ad_tx,
+ ad_rx,
+ array_message,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
+ expected_result=True,
+ slot_id_rx=None):
+ """Send MMS, receive MMS, and verify content and sender's number.
+
+ Send (several) MMS from droid_tx to droid_rx.
+ Verify MMS is sent, delivered and received.
+ Verify received content and sender's number are correct.
+
+ Args:
+ log: Log object.
+ ad_tx: Sender's Android Device Object
+ ad_rx: Receiver's Android Device Object
+ array_message: the array of message to send/receive
+ """
+ subid_tx = get_outgoing_message_sub_id(ad_tx)
+ if slot_id_rx is None:
+ subid_rx = get_incoming_message_sub_id(ad_rx)
+ else:
+ subid_rx = get_subid_from_slot_index(log, ad_rx, slot_id_rx)
+
+ result = mms_send_receive_verify_for_subscription(
+ log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time)
+ if result != expected_result:
+ log_messaging_screen_shot(ad_tx, test_name="mms_tx")
+ log_messaging_screen_shot(ad_rx, test_name="mms_rx")
+ return result == expected_result
+
+
+def sms_mms_send_logcat_check(ad, type, begin_time):
+ type = type.upper()
+ log_results = ad.search_logcat(
+ "%s Message sent successfully" % type, begin_time=begin_time)
+ if log_results:
+ ad.log.info("Found %s sent successful log message: %s", type,
+ log_results[-1]["log_message"])
+ return True
+ else:
+ log_results = ad.search_logcat(
+ "ProcessSentMessageAction: Done sending %s message" % type,
+ begin_time=begin_time)
+ if log_results:
+ for log_result in log_results:
+ if "status is SUCCEEDED" in log_result["log_message"]:
+ ad.log.info(
+ "Found BugleDataModel %s send succeed log message: %s",
+ type, log_result["log_message"])
+ return True
+ return False
+
+
+def sms_mms_receive_logcat_check(ad, type, begin_time):
+ type = type.upper()
+ smshandle_logs = ad.search_logcat(
+ "InboundSmsHandler: No broadcast sent on processing EVENT_BROADCAST_SMS",
+ begin_time=begin_time)
+ if smshandle_logs:
+ ad.log.warning("Found %s", smshandle_logs[-1]["log_message"])
+ log_results = ad.search_logcat(
+ "New %s Received" % type, begin_time=begin_time) or \
+ ad.search_logcat("New %s Downloaded" % type, begin_time=begin_time)
+ if log_results:
+ ad.log.info("Found SL4A %s received log message: %s", type,
+ log_results[-1]["log_message"])
+ return True
+ else:
+ log_results = ad.search_logcat(
+ "Received %s message" % type, begin_time=begin_time)
+ if log_results:
+ ad.log.info("Found %s received log message: %s", type,
+ log_results[-1]["log_message"])
+ log_results = ad.search_logcat(
+ "ProcessDownloadedMmsAction", begin_time=begin_time)
+ for log_result in log_results:
+ ad.log.info("Found %s", log_result["log_message"])
+ if "status is SUCCEEDED" in log_result["log_message"]:
+ ad.log.info("Download succeed with ProcessDownloadedMmsAction")
+ return True
+ return False
+
+
+#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
+def mms_send_receive_verify_for_subscription(
+ log,
+ ad_tx,
+ ad_rx,
+ subid_tx,
+ subid_rx,
+ array_payload,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
+ """Send MMS, receive MMS, and verify content and sender's number.
+
+ Send (several) MMS from droid_tx to droid_rx.
+ Verify MMS is sent, delivered and received.
+ Verify received content and sender's number are correct.
+
+ Args:
+ log: Log object.
+ ad_tx: Sender's Android Device Object..
+ ad_rx: Receiver's Android Device Object.
+ subid_tx: Sender's subscription ID to be used for SMS
+ subid_rx: Receiver's subscription ID to be used for SMS
+ array_message: the array of message to send/receive
+ """
+
+ phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
+ phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
+ toggle_enforce = False
+
+ for ad in (ad_tx, ad_rx):
+ if "Permissive" not in ad.adb.shell("su root getenforce"):
+ ad.adb.shell("su root setenforce 0")
+ toggle_enforce = True
+ if not getattr(ad, "messaging_droid", None):
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+ else:
+ try:
+ if not ad.messaging_droid.is_live:
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+ else:
+ ad.messaging_ed.clear_all_events()
+ ad.messaging_droid.logI(
+ "Start mms_send_receive_verify_for_subscription test")
+ except Exception:
+ ad.log.info("Create new sl4a session for messaging")
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+
+ for subject, message, filename in array_payload:
+ ad_tx.messaging_ed.clear_events(EventMmsSentSuccess)
+ ad_tx.messaging_ed.clear_events(EventMmsSentFailure)
+ ad_rx.messaging_ed.clear_events(EventMmsDownloaded)
+ ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage()
+ ad_tx.log.info(
+ "Sending MMS from %s to %s, subject: %s, message: %s, file: %s.",
+ phonenumber_tx, phonenumber_rx, subject, message, filename)
+ try:
+ ad_tx.messaging_droid.smsSendMultimediaMessage(
+ phonenumber_rx, subject, message, phonenumber_tx, filename)
+ try:
+ events = ad_tx.messaging_ed.pop_events(
+ "(%s|%s)" % (EventMmsSentSuccess,
+ EventMmsSentFailure), max_wait_time)
+ for event in events:
+ ad_tx.log.info("Got event %s", event["name"])
+ if event["name"] == EventMmsSentFailure:
+ if event.get("data") and event["data"].get("Reason"):
+ ad_tx.log.error("%s with reason: %s",
+ event["name"],
+ event["data"]["Reason"])
+ return False
+ elif event["name"] == EventMmsSentSuccess:
+ break
+ except Empty:
+ ad_tx.log.warning("No %s or %s event.", EventMmsSentSuccess,
+ EventMmsSentFailure)
+ return False
+
+ if not wait_for_matching_mms(log, ad_rx, phonenumber_tx,
+ message, max_wait_time):
+ return False
+ except Exception as e:
+ log.error("Exception error %s", e)
+ raise
+ finally:
+ ad_rx.messaging_droid.smsStopTrackingIncomingMmsMessage()
+ for ad in (ad_tx, ad_rx):
+ if toggle_enforce:
+ ad.send_keycode("BACK")
+ ad.adb.shell("su root setenforce 1")
+ return True
+
+
+def mms_receive_verify_after_call_hangup(
+ log, ad_tx, ad_rx, array_message,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
+ """Verify the suspanded MMS during call will send out after call release.
+
+ Hangup call from droid_tx to droid_rx.
+ Verify MMS is sent, delivered and received.
+ Verify received content and sender's number are correct.
+
+ Args:
+ log: Log object.
+ ad_tx: Sender's Android Device Object
+ ad_rx: Receiver's Android Device Object
+ array_message: the array of message to send/receive
+ """
+ return mms_receive_verify_after_call_hangup_for_subscription(
+ log, ad_tx, ad_rx, get_outgoing_message_sub_id(ad_tx),
+ get_incoming_message_sub_id(ad_rx), array_message, max_wait_time)
+
+
+#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
+def mms_receive_verify_after_call_hangup_for_subscription(
+ log,
+ ad_tx,
+ ad_rx,
+ subid_tx,
+ subid_rx,
+ array_payload,
+ max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
+ """Verify the suspanded MMS during call will send out after call release.
+
+ Hangup call from droid_tx to droid_rx.
+ Verify MMS is sent, delivered and received.
+ Verify received content and sender's number are correct.
+
+ Args:
+ log: Log object.
+ ad_tx: Sender's Android Device Object..
+ ad_rx: Receiver's Android Device Object.
+ subid_tx: Sender's subscription ID to be used for SMS
+ subid_rx: Receiver's subscription ID to be used for SMS
+ array_message: the array of message to send/receive
+ """
+
+ phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
+ phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
+ for ad in (ad_tx, ad_rx):
+ if not getattr(ad, "messaging_droid", None):
+ ad.messaging_droid, ad.messaging_ed = ad.get_droid()
+ ad.messaging_ed.start()
+ for subject, message, filename in array_payload:
+ ad_rx.log.info(
+ "Waiting MMS from %s to %s, subject: %s, message: %s, file: %s.",
+ phonenumber_tx, phonenumber_rx, subject, message, filename)
+ ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage()
+ time.sleep(5)
+ try:
+ hangup_call(log, ad_tx)
+ hangup_call(log, ad_rx)
+ try:
+ ad_tx.messaging_ed.pop_event(EventMmsSentSuccess,
+ max_wait_time)
+ ad_tx.log.info("Got event %s", EventMmsSentSuccess)
+ except Empty:
+ log.warning("No sent_success event.")
+ if not wait_for_matching_mms(log, ad_rx, phonenumber_tx, message):
+ return False
+ finally:
+ ad_rx.messaging_droid.smsStopTrackingIncomingMmsMessage()
+ return True
+
+
+def log_messaging_screen_shot(ad, test_name=""):
+ ad.ensure_screen_on()
+ ad.send_keycode("HOME")
+ ad.adb.shell("am start -n com.google.android.apps.messaging/.ui."
+ "ConversationListActivity")
+ time.sleep(3)
+ ad.screenshot(test_name)
+ ad.adb.shell("am start -n com.google.android.apps.messaging/com.google."
+ "android.apps.messaging.ui.conversation."
+ "LaunchConversationShimActivity -e conversation_id 1")
+ time.sleep(3)
+ ad.screenshot(test_name)
+ ad.send_keycode("HOME")
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_mms_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_mms_utils.py
index 92bd9cf..d9d85a7 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_mms_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_mms_utils.py
@@ -16,14 +16,15 @@
import time
from acts.utils import rand_ascii_str
-from acts_contrib.test_utils.tel.tel_test_utils import mms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_message_utils import mms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_message_utils import mms_receive_verify_after_call_hangup
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
-from acts_contrib.test_utils.tel.tel_test_utils import mms_receive_verify_after_call_hangup
message_lengths = (50, 160, 180)
long_message_lengths = (800, 1600)
+
def _mms_test_mo(log, ads, expected_result=True):
return _mms_test(log,
[ads[0], ads[1]], expected_result=expected_result)
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_ops_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_ops_utils.py
new file mode 100644
index 0000000..02b23b4
--- /dev/null
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_ops_utils.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - Google
+#
+# 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_contrib.test_utils.tel.tel_data_utils import active_file_download_task
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call
+
+
+def initiate_call_verify_operation(log,
+ caller,
+ callee,
+ download=False):
+ """Initiate call and verify operations with an option of data idle or data download
+
+ Args:
+ log: log object.
+ caller: android device object as caller.
+ callee: android device object as callee.
+ download: True if download operation is to be performed else False
+
+ Return:
+ True: if call initiated and verified operations successfully
+ False: for errors
+ """
+ caller_number = caller.telephony['subscription'][
+ get_outgoing_voice_sub_id(caller)]['phone_num']
+ callee_number = callee.telephony['subscription'][
+ get_outgoing_voice_sub_id(callee)]['phone_num']
+ if not initiate_call(log, caller, callee_number):
+ caller.log.error("Phone was unable to initate a call")
+ return False
+
+ if not wait_and_answer_call(log, callee, caller_number):
+ callee.log.error("Callee failed to receive incoming call or answered the call.")
+ return False
+
+ if download:
+ if not active_file_download_task(log, caller, "10MB"):
+ caller.log.error("Unable to download file")
+ return False
+
+ if not hangup_call(log, caller):
+ caller.log.error("Unable to hang up the call")
+ return False
+ return True
+
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_parse_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_parse_utils.py
new file mode 100644
index 0000000..6d8811b
--- /dev/null
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_parse_utils.py
@@ -0,0 +1,1844 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - Google
+#
+# 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 re
+import statistics
+
+from acts import signals
+from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_data_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_voice_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
+
+SETUP_DATA_CALL = 'SETUP_DATA_CALL'
+SETUP_DATA_CALL_REQUEST = '> SETUP_DATA_CALL'
+SETUP_DATA_CALL_RESPONSE = '< SETUP_DATA_CALL'
+IS_CAPTIVEPORTAL = r'isCaptivePortal: isSuccessful()=true'
+
+DEACTIVATE_DATA_CALL = 'DEACTIVATE_DATA_CALL'
+DEACTIVATE_DATA_CALL_REQUEST = '> DEACTIVATE_DATA_CALL'
+DEACTIVATE_DATA_CALL_RESPONSE = '< DEACTIVATE_DATA_CALL'
+UNSOL_DATA_CALL_LIST_CHANGED = 'UNSOL_DATA_CALL_LIST_CHANGED'
+
+IWLAN_DATA_SERVICE = 'IWlanDataService'
+IWLAN_SETUP_DATA_CALL_REQUEST = '> REQUEST_SETUP_DATA_CALL'
+IWLAN_SETUP_DATA_CALL_RESPONSE = 'setupDataCallResponse'
+IWLAN_SEND_ACK = '> send ACK for serial'
+
+IWLAN_DEACTIVATE_DATA_CALL_REQUEST = '> REQUEST_DEACTIVATE_DATA_CALL'
+IWLAN_DEACTIVATE_DATA_CALL_RESPONSE = 'deactivateDataCallResponse'
+
+SET_PREFERRED_DATA_MODEM = 'SET_PREFERRED_DATA_MODEM'
+
+WHI_IWLAN_DATA_SERVICE = 'IwlanDataService'
+WHI_IWLAN_SETUP_DATA_CALL_REQUEST = r'IwlanDataService\[\d\]: Setup data call'
+WHI_IWLAN_SETUP_DATA_CALL_RESPONSE = r'IwlanDataService\[\d\]: Tunnel opened!'
+WHI_IWLAN_DEACTIVATE_DATA_CALL_REQUEST = r'IwlanDataService\[\d\]: Deactivate data call'
+WHI_IWLAN_DEACTIVATE_DATA_CALL_RESPONSE = r'IwlanDataService\[\d\]: Tunnel closed!'
+
+ON_ENABLE_APN_IMS_SLOT0 = 'DCT-C-0 : onEnableApn: apnType=ims, request type=NORMAL'
+ON_ENABLE_APN_IMS_SLOT1 = 'DCT-C-1 : onEnableApn: apnType=ims, request type=NORMAL'
+ON_ENABLE_APN_IMS_HANDOVER_SLOT0 = 'DCT-C-0 : onEnableApn: apnType=ims, request type=HANDOVER'
+ON_ENABLE_APN_IMS_HANDOVER_SLOT1 = 'DCT-C-1 : onEnableApn: apnType=ims, request type=HANDOVER'
+RADIO_ON_4G_SLOT0 = r'GsmCdmaPhone: \[0\] Event EVENT_RADIO_ON Received'
+RADIO_ON_4G_SLOT1 = r'GsmCdmaPhone: \[1\] Event EVENT_RADIO_ON Received'
+RADIO_ON_IWLAN = 'Switching to new default network.*WIFI CONNECTED'
+WIFI_OFF = 'setWifiEnabled.*enable=false'
+ON_IMS_MM_TEL_CONNECTED_4G_SLOT0 = r'ImsPhone: \[0\].*onImsMmTelConnected imsRadioTech=WWAN'
+ON_IMS_MM_TEL_CONNECTED_4G_SLOT1 = r'ImsPhone: \[1\].*onImsMmTelConnected imsRadioTech=WWAN'
+ON_IMS_MM_TEL_CONNECTED_IWLAN_SLOT0 = r'ImsPhone: \[0\].*onImsMmTelConnected imsRadioTech=WLAN'
+ON_IMS_MM_TEL_CONNECTED_IWLAN_SLOT1 = r'ImsPhone: \[1\].*onImsMmTelConnected imsRadioTech=WLAN'
+
+DEFAULT_MO_SMS_BODY = 'MO SMS body not yet found'
+DEFAULT_MT_SMS_BODY = 'MT SMS body not yet found'
+
+MMS_SERVICE = 'MmsService:'
+MMS_SEND_REQUEST_ID_PATTERN = r'SendRequest@(\S+)'
+MMS_DOWNLOAD_REQUEST_ID_PATTERN = r'DownloadRequest@(\S+)'
+MMS_START_NEW_NW_REQUEST = 'start new network request'
+MMS_200_OK = '200 OK'
+
+SMS_SEND_TEXT_MESSAGE = 'smsSendTextMessage'
+MO_SMS_LOGCAT_PATTERN = r'smsSendTextMessage.*"(\S+)", true|false'
+SEND_SMS = 'SEND_SMS'
+SEND_SMS_REQUEST = '> SEND_SMS'
+SEND_SMS_RESPONSE = '< SEND_SMS'
+SEND_SMS_EXPECT_MORE = 'SEND_SMS_EXPECT_MORE'
+UNSOL_RESPONSE_NEW_SMS = '< UNSOL_RESPONSE_NEW_SMS'
+SMS_RECEIVED = 'SmsReceived'
+MT_SMS_CONTENT_PATTERN = 'sl4a.*?SmsReceived.*?"Text":"(.*?)"'
+
+SEND_SMS_OVER_IMS = r'ImsSmsDispatcher \[(\d)\]'
+SEND_SMS_REQUEST_OVER_IMS = 'sendSms: mRetryCount'
+SEND_SMS_RESPONSE_OVER_IMS = 'onSendSmsResult token'
+SMS_RECEIVED_OVER_IMS = 'SMS received'
+SMS_RECEIVED_OVER_IMS_SLOT0 = r'ImsSmsDispatcher \[0\]: SMS received'
+SMS_RECEIVED_OVER_IMS_SLOT1 = r'ImsSmsDispatcher \[1\]: SMS received'
+
+
+def print_nested_dict(ad, d):
+ divider = "------"
+ for k, v in d.items():
+ if isinstance(v, dict):
+ ad.log.info('%s %s %s', divider, k, divider)
+ print_nested_dict(ad, v)
+ else:
+ ad.log.info('%s: %s', k, v)
+
+
+def get_slot_from_logcat(msg):
+ """Get slot index from specific pattern in logcat
+
+ Args:
+ msg: logcat message string
+
+ Returns:
+ 0 for pSIM or 1 for eSIM
+ """
+ res = re.findall(r'\[(PHONE[\d])\]', msg)
+ try:
+ phone = res[0]
+ except:
+ phone = None
+ return phone
+
+
+def get_apn_from_logcat(msg):
+ """Get APN from logcat
+
+ Args:
+ msg: logcat message string
+
+ Returns:
+ APN
+ """
+ res = re.findall(r'DataProfile=[^/]+/[^/]+/[^/]+/([^/]+)/', msg)
+ try:
+ apn = res[0]
+ except:
+ apn = None
+ return apn
+
+
+def parse_setup_data_call(ad, apn='internet', dds_switch=False):
+ """Search in logcat for lines containing data call setup procedure.
+ Calculate the data call setup time with given APN and validation
+ time on LTE.
+
+ Args:
+ ad: Android object
+ apn: access point name
+ dds_switch: True for switching DDS. Otherwise False.
+
+ Returns:
+ setup_data_call: Dictionary containing data call setup request and
+ response messages for each data call. The format is shown as
+ below:
+ {
+ message_id:
+ {
+ 'request':
+ {
+ 'message': logcat message body of data call setup
+ request message
+ 'time_stamp': time stamp in text format
+ 'datetime_obj': datetime object of time stamp
+ 'apn': access point name of this request
+ 'phone': 0 for pSIM or 1 for eSIM
+ }
+ 'response':
+ {
+ 'message': logcat message body of data call setup
+ response message
+ 'time_stamp': time stamp in text format
+ 'datetime_obj': datetime object of time stamp
+ 'cause': failure cause if data call setup failed
+ 'cid': PDP context ID
+ 'ifname': the name of the interface of the network
+ 'phone': 0 for pSIM or 1 for eSIM
+ 'unsol_data_call_list_changed': message of
+ unsol_data_call_list_changed
+ 'unsol_data_call_list_changed_time': time stamp of
+ the message unsol_data_call_list_changed
+ 'is_captive_portal': message of LTE validation pass
+ 'data_call_setup_time': time between data call setup
+ request and unsol_data_call_list_changed
+ 'validation_time_on_lte': time between data call
+ setup response and LTE validation pass
+ }
+ }
+ }
+
+ data_call_setup_time_list: List. This is a summary of necessary
+ messages of data call setup procedure The format is shown as
+ below:
+ [
+ {
+ 'request': logcat message body of data call setup
+ request message
+ 'response': logcat message body of data call setup
+ response message
+ 'unsol_data_call_list_changed': message of
+ unsol_data_call_list_changed
+ 'start': time stamp of data call setup request
+ 'end': time stamp of the message
+ unsol_data_call_list_changed
+ 'duration': time between data call setup request and
+ unsol_data_call_list_changed
+ 'validation_time_on_lte': time between data call
+ setup response and LTE validation pass
+ }
+ ]
+
+ avg_data_call_setup_time: average of data call setup time
+
+ avg_validation_time_on_lte: average of time for validation time on
+ LTE
+ """
+ ad.log.info('====== Start to search logcat ====== ')
+ logcat = ad.search_logcat(
+ r'%s\|%s\|%s\|%s' % (
+ SET_PREFERRED_DATA_MODEM,
+ SETUP_DATA_CALL,
+ UNSOL_DATA_CALL_LIST_CHANGED, IS_CAPTIVEPORTAL))
+
+ if not logcat:
+ return False
+
+ for msg in logcat:
+ ad.log.info(msg["log_message"])
+
+ dds_slot = get_slot_index_from_data_sub_id(ad)
+
+ set_preferred_data_modem = {}
+ setup_data_call = {}
+ data_call_setup_time_list = []
+ last_message_id = None
+
+ for line in logcat:
+ if line['message_id']:
+ if SET_PREFERRED_DATA_MODEM in line['log_message']:
+ set_preferred_data_modem['message'] = line['log_message']
+ set_preferred_data_modem['time_stamp'] = line['time_stamp']
+ set_preferred_data_modem[
+ 'datetime_obj'] = line['datetime_obj']
+
+ if SETUP_DATA_CALL_REQUEST in line['log_message']:
+ found_apn = get_apn_from_logcat(line['log_message'])
+ if found_apn != apn:
+ continue
+
+ phone = get_slot_from_logcat(line['log_message'])
+ if not phone:
+ continue
+
+ if not dds_switch:
+ if str(dds_slot) not in phone:
+ continue
+
+ msg_id = line['message_id']
+ last_message_id = line['message_id']
+ if msg_id not in setup_data_call:
+ setup_data_call[msg_id] = {}
+
+ setup_data_call[msg_id]['request'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj'],
+ 'apn': found_apn,
+ 'phone': phone}
+
+ if set_preferred_data_modem:
+ setup_data_call[msg_id]['request'][
+ 'set_preferred_data_modem_message'] = set_preferred_data_modem['message']
+ setup_data_call[msg_id]['request'][
+ 'set_preferred_data_modem_time_stamp'] = set_preferred_data_modem['time_stamp']
+ setup_data_call[msg_id]['request'][
+ 'set_preferred_data_modem_datetime_obj'] = set_preferred_data_modem['datetime_obj']
+ set_preferred_data_modem = {}
+
+ if SETUP_DATA_CALL_RESPONSE in line['log_message']:
+ phone = get_slot_from_logcat(line['log_message'])
+ if not phone:
+ continue
+
+ if not dds_switch:
+ if str(dds_slot) not in phone:
+ continue
+
+ msg_id = line['message_id']
+ if msg_id not in setup_data_call:
+ continue
+
+ if 'request' not in setup_data_call[msg_id]:
+ continue
+
+ last_message_id = line['message_id']
+
+ setup_data_call[msg_id]['response'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj'],
+ 'cause': '0',
+ 'cid': None,
+ 'ifname': None,
+ 'phone': phone,
+ 'unsol_data_call_list_changed': None,
+ 'unsol_data_call_list_changed_time': None,
+ 'is_captive_portal': None,
+ 'data_call_setup_time': None,
+ 'validation_time_on_lte': None}
+
+ res = re.findall(r'cause=(\d+)', line['log_message'])
+ try:
+ cause = res[0]
+ setup_data_call[msg_id]['response']['cause'] = cause
+ except:
+ pass
+
+ res = re.findall(r'cid=(\d+)', line['log_message'])
+ try:
+ cid = res[0]
+ setup_data_call[msg_id]['response']['cid'] = cid
+ except:
+ pass
+
+ res = re.findall(r'ifname=(\S+)', line['log_message'])
+ try:
+ ifname = res[0]
+ setup_data_call[msg_id]['response']['ifname'] = ifname
+ except:
+ pass
+
+ if UNSOL_DATA_CALL_LIST_CHANGED in line['log_message']:
+ if not last_message_id:
+ continue
+
+ phone = get_slot_from_logcat(line['log_message'])
+ if not phone:
+ continue
+
+ if not dds_switch:
+ if str(dds_slot) not in phone:
+ continue
+
+ if 'request' not in setup_data_call[last_message_id]:
+ continue
+
+ if 'response' not in setup_data_call[last_message_id]:
+ continue
+
+ cid = setup_data_call[last_message_id]['response']['cid']
+ if 'cid = %s' % cid not in line['log_message']:
+ continue
+
+ if setup_data_call[last_message_id]['response']['cause'] != '0':
+ continue
+
+ if dds_switch:
+ if 'set_preferred_data_modem_message' not in setup_data_call[
+ last_message_id]['request']:
+ continue
+ data_call_start_time = setup_data_call[last_message_id][
+ 'request']['set_preferred_data_modem_datetime_obj']
+
+ else:
+ data_call_start_time = setup_data_call[last_message_id][
+ 'request']['datetime_obj']
+
+ data_call_end_time = line['datetime_obj']
+ setup_data_call[last_message_id]['response'][
+ 'unsol_data_call_list_changed_time'] = data_call_end_time
+ setup_data_call[last_message_id]['response'][
+ 'unsol_data_call_list_changed'] = line['log_message']
+ data_call_setup_time = data_call_end_time - data_call_start_time
+ setup_data_call[last_message_id]['response'][
+ 'data_call_setup_time'] = data_call_setup_time.total_seconds()
+
+ if apn == 'ims':
+ data_call_setup_time_list.append(
+ {'request': setup_data_call[
+ last_message_id]['request']['message'],
+ 'response': setup_data_call[
+ last_message_id]['response']['message'],
+ 'unsol_data_call_list_changed': setup_data_call[
+ last_message_id]['response'][
+ 'unsol_data_call_list_changed'],
+ 'start': data_call_start_time,
+ 'end': data_call_end_time,
+ 'duration': setup_data_call[last_message_id]['response'][
+ 'data_call_setup_time']})
+
+ last_message_id = None
+
+ if IS_CAPTIVEPORTAL in line['log_message']:
+ if not last_message_id:
+ continue
+
+ if 'request' not in setup_data_call[last_message_id]:
+ continue
+
+ if 'response' not in setup_data_call[last_message_id]:
+ continue
+
+ if dds_switch:
+ data_call_start_time = setup_data_call[last_message_id][
+ 'request']['set_preferred_data_modem_datetime_obj']
+
+ else:
+ data_call_start_time = setup_data_call[last_message_id][
+ 'request']['datetime_obj']
+
+ setup_data_call[last_message_id]['response'][
+ 'is_captive_portal'] = line['log_message']
+ validation_start_time_on_lte = setup_data_call[
+ last_message_id]['response']['datetime_obj']
+ validation_end_time_on_lte = line['datetime_obj']
+ validation_time_on_lte = (
+ validation_end_time_on_lte - validation_start_time_on_lte).total_seconds()
+ setup_data_call[last_message_id]['response'][
+ 'validation_time_on_lte'] = validation_time_on_lte
+
+ data_call_setup_time_list.append(
+ {'request': setup_data_call[last_message_id]['request'][
+ 'message'],
+ 'response': setup_data_call[last_message_id]['response'][
+ 'message'],
+ 'unsol_data_call_list_changed': setup_data_call[
+ last_message_id]['response']['unsol_data_call_list_changed'],
+ 'start': data_call_start_time,
+ 'end': setup_data_call[last_message_id]['response'][
+ 'unsol_data_call_list_changed_time'],
+ 'duration': setup_data_call[last_message_id]['response'][
+ 'data_call_setup_time'],
+ 'validation_time_on_lte': validation_time_on_lte})
+
+ last_message_id = None
+
+ duration_list = []
+ for item in data_call_setup_time_list:
+ if 'duration' in item:
+ duration_list.append(item['duration'])
+
+ try:
+ avg_data_call_setup_time = statistics.mean(duration_list)
+ except:
+ avg_data_call_setup_time = None
+
+ validation_time_on_lte_list = []
+ for item in data_call_setup_time_list:
+ if 'validation_time_on_lte' in item:
+ validation_time_on_lte_list.append(
+ item['validation_time_on_lte'])
+
+ try:
+ avg_validation_time_on_lte = statistics.mean(
+ validation_time_on_lte_list)
+ except:
+ avg_validation_time_on_lte = None
+
+ return (
+ setup_data_call,
+ data_call_setup_time_list,
+ avg_data_call_setup_time,
+ avg_validation_time_on_lte)
+
+
+def parse_setup_data_call_on_iwlan(ad):
+ """Search in logcat for lines containing data call setup procedure.
+ Calculate the data call setup time with given APN on iwlan.
+
+ Args:
+ ad: Android object
+ apn: access point name
+
+ Returns:
+ setup_data_call: Dictionary containing data call setup request and
+ response messages for each data call. The format is shown as
+ below:
+ {
+ message_id:
+ {
+ 'request':
+ {
+ 'message': logcat message body of data call setup
+ request message
+ 'time_stamp': time stamp in text format
+ 'datetime_obj': datetime object of time stamp
+ }
+ 'response':
+ {
+ 'message': logcat message body of data call setup
+ response message
+ 'time_stamp': time stamp in text format
+ 'datetime_obj': datetime object of time stamp
+ 'cause': failure cause if data call setup failed
+ 'data_call_setup_time': time between data call setup
+ request and response
+ }
+ }
+ }
+
+ data_call_setup_time_list:
+ List. This is a summary of mecessary messages of data call setup
+ procedure The format is shown as below:
+ [
+ {
+ 'request': logcat message body of data call setup
+ request message
+ 'response': logcat message body of data call setup
+ response message
+ 'start': time stamp of data call setup request
+ 'end': time stamp of data call setup response
+ 'duration': time between data call setup request and
+ response
+ }
+ ]
+
+ avg_data_call_setup_time: average of data call setup time
+ """
+ ad.log.info('====== Start to search logcat ====== ')
+ logcat = ad.search_logcat(r'%s\|%s' % (
+ IWLAN_DATA_SERVICE, WHI_IWLAN_DATA_SERVICE))
+
+ found_iwlan_data_service = 1
+ if not logcat:
+ found_iwlan_data_service = 0
+
+ if not found_iwlan_data_service:
+ (
+ setup_data_call,
+ data_call_setup_time_list,
+ avg_data_call_setup_time,
+ _) = parse_setup_data_call(ad, apn='ims')
+
+ return (
+ setup_data_call,
+ data_call_setup_time_list,
+ avg_data_call_setup_time)
+
+ for msg in logcat:
+ ad.log.info(msg["log_message"])
+
+ setup_data_call = {}
+ data_call_setup_time_list = []
+ last_message_id = None
+
+ whi_msg_index = None
+ for line in logcat:
+ serial = None
+ cause = None
+ if IWLAN_SETUP_DATA_CALL_REQUEST in line['log_message']:
+ match_res = re.findall(
+ r'%s:\s(\d+)' % IWLAN_DATA_SERVICE, line['log_message'])
+ if match_res:
+ try:
+ serial = match_res[0]
+ except:
+ pass
+
+ if not serial:
+ continue
+
+ msg_id = serial
+ last_message_id = serial
+ if msg_id not in setup_data_call:
+ setup_data_call[msg_id] = {}
+
+ setup_data_call[msg_id]['request'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj']}
+
+ else:
+ if re.search(
+ WHI_IWLAN_SETUP_DATA_CALL_REQUEST, line['log_message']):
+ if whi_msg_index is None:
+ whi_msg_index = 0
+ else:
+ whi_msg_index = whi_msg_index + 1
+
+ if str(whi_msg_index) not in setup_data_call:
+ setup_data_call[str(whi_msg_index)] = {}
+
+ setup_data_call[str(whi_msg_index)]['request'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj']}
+
+ if IWLAN_SETUP_DATA_CALL_RESPONSE in line['log_message']:
+ match_res = re.findall(r'Serial = (\d+)', line['log_message'])
+ if match_res:
+ try:
+ serial = match_res[0]
+ except:
+ pass
+
+ if serial:
+ msg_id = serial
+ else:
+ msg_id = last_message_id
+
+ if msg_id not in setup_data_call:
+ continue
+
+ if 'request' not in setup_data_call[msg_id]:
+ continue
+
+ setup_data_call[msg_id]['response'] = {
+ 'message': None,
+ 'time_stamp': None,
+ 'datetime_obj': None,
+ 'cause': None,
+ 'data_call_setup_time': None}
+
+ match_res = re.findall(
+ r'Fail Cause = (\d+)', line['log_message'])
+ if match_res:
+ try:
+ cause = match_res[0]
+ except:
+ cause = None
+
+ if cause != '0':
+ continue
+
+ setup_data_call[msg_id]['response']['message'] = line[
+ 'log_message']
+ setup_data_call[msg_id]['response']['time_stamp'] = line[
+ 'time_stamp']
+ setup_data_call[msg_id]['response']['datetime_obj'] = line[
+ 'datetime_obj']
+ setup_data_call[msg_id]['response']['cause'] = 0
+
+ data_call_start_time = setup_data_call[last_message_id][
+ 'request']['datetime_obj']
+ data_call_end_time = line['datetime_obj']
+ data_call_setup_time = data_call_end_time - data_call_start_time
+ setup_data_call[last_message_id]['response'][
+ 'data_call_setup_time'] = data_call_setup_time.total_seconds()
+
+ data_call_setup_time_list.append(
+ {'request': setup_data_call[last_message_id]['request'][
+ 'message'],
+ 'response': setup_data_call[last_message_id]['response'][
+ 'message'],
+ 'start': setup_data_call[last_message_id]['request'][
+ 'datetime_obj'],
+ 'end': setup_data_call[last_message_id]['response'][
+ 'datetime_obj'],
+ 'duration': setup_data_call[last_message_id]['response'][
+ 'data_call_setup_time']})
+
+ last_message_id = None
+
+ else:
+ if re.search(
+ WHI_IWLAN_SETUP_DATA_CALL_RESPONSE, line['log_message']):
+ if whi_msg_index is None:
+ continue
+
+ if 'response' in setup_data_call[str(whi_msg_index)]:
+ ad.log.error('Duplicated setup data call response is '
+ 'found or the request message is lost.')
+ continue
+
+ setup_data_call[str(whi_msg_index)]['response'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj'],
+ 'data_call_setup_time': None}
+
+ data_call_start_time = setup_data_call[str(whi_msg_index)][
+ 'request']['datetime_obj']
+ data_call_end_time = line['datetime_obj']
+ data_call_setup_time = data_call_end_time - data_call_start_time
+ setup_data_call[str(whi_msg_index)]['response'][
+ 'data_call_setup_time'] = data_call_setup_time.total_seconds()
+
+ data_call_setup_time_list.append(
+ {'request': setup_data_call[str(whi_msg_index)][
+ 'request']['message'],
+ 'response': setup_data_call[str(whi_msg_index)][
+ 'response']['message'],
+ 'start': setup_data_call[str(whi_msg_index)]['request'][
+ 'datetime_obj'],
+ 'end': setup_data_call[str(whi_msg_index)]['response'][
+ 'datetime_obj'],
+ 'duration': setup_data_call[str(whi_msg_index)][
+ 'response']['data_call_setup_time']})
+
+ duration_list = []
+ for item in data_call_setup_time_list:
+ if 'duration' in item:
+ duration_list.append(item['duration'])
+
+ try:
+ avg_data_call_setup_time = statistics.mean(duration_list)
+ except:
+ avg_data_call_setup_time = None
+
+ ad.log.warning('setup_data_call: %s', setup_data_call)
+ ad.log.warning('duration list: %s', duration_list)
+ ad.log.warning('avg_data_call_setup_time: %s', avg_data_call_setup_time)
+
+ return (
+ setup_data_call,
+ data_call_setup_time_list,
+ avg_data_call_setup_time)
+
+
+def parse_deactivate_data_call(ad):
+ """Search in logcat for lines containing data call deactivation procedure.
+ Calculate the data call deactivation time on LTE.
+
+ Args:
+ ad: Android object
+
+ Returns:
+ deactivate_data_call: Dictionary containing data call deactivation
+ request and response messages for each data call. The format is
+ shown as below:
+ {
+ message_id:
+ {
+ 'request':
+ {
+ 'message': logcat message body of data call
+ deactivation request message
+ 'time_stamp': time stamp in text format
+ 'datetime_obj': datetime object of time stamp
+ 'cid': PDP context ID
+ 'phone': 0 for pSIM or 1 for eSIM
+ }
+ 'response':
+ {
+ 'message': logcat message body of data call
+ deactivation response message
+ 'time_stamp': time stamp in text format
+ 'datetime_obj': datetime object of time stamp
+ 'phone': 0 for pSIM or 1 for eSIM
+ 'unsol_data_call_list_changed': message of
+ unsol_data_call_list_changed
+ 'deactivate_data_call_time': time between data call
+ deactivation request and unsol_data_call_list_changed
+ }
+ }
+ }
+
+ deactivate_data_call_time_list: List. This is a summary of necessary
+ messages of data call deactivation procedure The format is shown
+ as below:
+ [
+ {
+ 'request': logcat message body of data call
+ deactivation request message
+ 'response': logcat message body of data call
+ deactivation response message
+ 'unsol_data_call_list_changed': message of
+ unsol_data_call_list_changed
+ 'start': time stamp of data call deactivation request
+ 'end': time stamp of the message
+ unsol_data_call_list_changed
+ 'duration': time between data call deactivation
+ request and unsol_data_call_list_changed
+ }
+ ]
+
+ avg_deactivate_data_call_time: average of data call deactivation time
+ """
+ ad.log.info('====== Start to search logcat ====== ')
+ logcat = ad.search_logcat(
+ r'%s\|%s' % (DEACTIVATE_DATA_CALL, UNSOL_DATA_CALL_LIST_CHANGED))
+ if not logcat:
+ return False
+
+ for msg in logcat:
+ ad.log.info(msg["log_message"])
+
+ dds_slot = get_slot_index_from_data_sub_id(ad)
+
+ deactivate_data_call = {}
+ deactivate_data_call_time_list = []
+ last_message_id = None
+
+ for line in logcat:
+ if line['message_id']:
+ if DEACTIVATE_DATA_CALL_REQUEST in line['log_message']:
+ phone = get_slot_from_logcat(line['log_message'])
+ if not phone:
+ continue
+
+ if str(dds_slot) not in phone:
+ continue
+
+ msg_id = line['message_id']
+ last_message_id = line['message_id']
+ if msg_id not in deactivate_data_call:
+ deactivate_data_call[msg_id] = {}
+
+ deactivate_data_call[msg_id]['request'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj'],
+ 'cid': None,
+ 'phone': dds_slot}
+
+ res = re.findall(r'cid = (\d+)', line['log_message'])
+ try:
+ cid = res[0]
+ deactivate_data_call[msg_id]['request']['cid'] = cid
+ except:
+ pass
+
+ if DEACTIVATE_DATA_CALL_RESPONSE in line['log_message']:
+ phone = get_slot_from_logcat(line['log_message'])
+ if not phone:
+ continue
+
+ if str(dds_slot) not in phone:
+ continue
+
+ msg_id = line['message_id']
+ if msg_id not in deactivate_data_call:
+ continue
+
+ if 'request' not in deactivate_data_call[msg_id]:
+ continue
+
+ last_message_id = line['message_id']
+
+ deactivate_data_call[msg_id]['response'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj'],
+ 'phone': dds_slot,
+ 'unsol_data_call_list_changed': None,
+ 'deactivate_data_call_time': None}
+
+ if UNSOL_DATA_CALL_LIST_CHANGED in line['log_message']:
+ if not last_message_id:
+ continue
+
+ phone = get_slot_from_logcat(line['log_message'])
+ if not phone:
+ continue
+
+ if str(dds_slot) not in phone:
+ continue
+
+ if 'request' not in deactivate_data_call[last_message_id]:
+ continue
+
+ if 'response' not in deactivate_data_call[last_message_id]:
+ continue
+
+ cid = deactivate_data_call[last_message_id]['request']['cid']
+ if 'cid = %s' % cid not in line['log_message']:
+ continue
+
+ deactivate_data_call_start_time = deactivate_data_call[
+ last_message_id]['request']['datetime_obj']
+ deactivate_data_call_end_time = line['datetime_obj']
+ deactivate_data_call[last_message_id]['response'][
+ 'unsol_data_call_list_changed'] = line['log_message']
+ deactivate_data_call_time = (
+ deactivate_data_call_end_time - deactivate_data_call_start_time)
+ deactivate_data_call[last_message_id]['response'][
+ 'deactivate_data_call_time'] = deactivate_data_call_time.total_seconds()
+ deactivate_data_call_time_list.append(
+ {'request': deactivate_data_call[last_message_id][
+ 'request']['message'],
+ 'response': deactivate_data_call[last_message_id][
+ 'response']['message'],
+ 'unsol_data_call_list_changed': deactivate_data_call[
+ last_message_id]['response'][
+ 'unsol_data_call_list_changed'],
+ 'start': deactivate_data_call_start_time,
+ 'end': deactivate_data_call_end_time,
+ 'duration': deactivate_data_call_time.total_seconds()})
+
+ last_message_id = None
+
+ duration_list = []
+ for item in deactivate_data_call_time_list:
+ if 'duration' in item:
+ duration_list.append(item['duration'])
+
+ try:
+ avg_deactivate_data_call_time = statistics.mean(duration_list)
+ except:
+ avg_deactivate_data_call_time = None
+
+ return (
+ deactivate_data_call,
+ deactivate_data_call_time_list,
+ avg_deactivate_data_call_time)
+
+
+def parse_deactivate_data_call_on_iwlan(ad):
+ """Search in logcat for lines containing data call deactivation procedure.
+ Calculate the data call deactivation time on iwlan.
+
+ Args:
+ ad: Android object
+
+ Returns:
+ deactivate_data_call: Dictionary containing data call deactivation
+ request and response messages for each data call. The format is
+ shown as below:
+ {
+ message_id:
+ {
+ 'request':
+ {
+ 'message': logcat message body of data call
+ deactivation request message
+ 'time_stamp': time stamp in text format
+ 'datetime_obj': datetime object of time stamp
+ }
+ 'response':
+ {
+ 'message': logcat message body of data call
+ deactivation response message
+ 'time_stamp': time stamp in text format
+ 'datetime_obj': datetime object of time stamp
+ 'send_ack_for_serial_time': time stamp of ACK
+ 'deactivate_data_call_time': time between data call
+ deactivation request and ACK
+ }
+ }
+ }
+
+ deactivate_data_call_time_list: List. This is a summary of necessary
+ messages of data call deactivation procedure The format is shown
+ as below:
+ [
+ {
+ 'request': logcat message body of data call
+ deactivation request message
+ 'response': logcat message body of data call
+ deactivation response message
+ 'start': time stamp of data call deactivation request
+ 'end': time stamp of the ACK
+ 'duration': time between data call deactivation
+ request and ACK
+ }
+ ]
+
+ avg_deactivate_data_call_time: average of data call deactivation time
+ """
+ ad.log.info('====== Start to search logcat ====== ')
+ logcat = ad.search_logcat(r'%s\|%s' % (
+ IWLAN_DATA_SERVICE, WHI_IWLAN_DATA_SERVICE))
+
+ found_iwlan_data_service = 1
+ if not logcat:
+ found_iwlan_data_service = 0
+
+ if not found_iwlan_data_service:
+ (
+ deactivate_data_call,
+ deactivate_data_call_time_list,
+ avg_deactivate_data_call_time) = parse_deactivate_data_call(ad)
+
+ return (
+ deactivate_data_call,
+ deactivate_data_call_time_list,
+ avg_deactivate_data_call_time)
+
+ for msg in logcat:
+ ad.log.info(msg["log_message"])
+
+ deactivate_data_call = {}
+ deactivate_data_call_time_list = []
+ last_message_id = None
+
+ whi_msg_index = None
+ for line in logcat:
+ serial = None
+ if IWLAN_DEACTIVATE_DATA_CALL_REQUEST in line['log_message']:
+ match_res = re.findall(
+ r'%s:\s(\d+)' % IWLAN_DATA_SERVICE, line['log_message'])
+ if match_res:
+ try:
+ serial = match_res[0]
+ except:
+ serial = None
+
+ if not serial:
+ continue
+
+ msg_id = serial
+ last_message_id = serial
+ if msg_id not in deactivate_data_call:
+ deactivate_data_call[msg_id] = {}
+
+ deactivate_data_call[msg_id]['request'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj']}
+ else:
+ if re.search(WHI_IWLAN_DEACTIVATE_DATA_CALL_REQUEST, line[
+ 'log_message']):
+ if whi_msg_index is None:
+ whi_msg_index = 0
+ else:
+ whi_msg_index = whi_msg_index + 1
+
+ if str(whi_msg_index) not in deactivate_data_call:
+ deactivate_data_call[str(whi_msg_index)] = {}
+
+ deactivate_data_call[str(whi_msg_index)]['request'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj']}
+
+ if IWLAN_DEACTIVATE_DATA_CALL_RESPONSE in line['log_message']:
+ if 'response' not in deactivate_data_call[last_message_id]:
+ deactivate_data_call[msg_id]['response'] = {}
+
+ deactivate_data_call[msg_id]['response'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj'],
+ 'send_ack_for_serial_time': None,
+ 'deactivate_data_call_time': None}
+
+ else:
+ if re.search(WHI_IWLAN_DEACTIVATE_DATA_CALL_RESPONSE, line[
+ 'log_message']):
+ if whi_msg_index is None:
+ continue
+
+ if 'response' in deactivate_data_call[str(whi_msg_index)]:
+ ad.log.error('Duplicated deactivate data call response'
+ 'is found or the request message is lost.')
+ continue
+
+ deactivate_data_call[str(whi_msg_index)]['response'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj'],
+ 'deactivate_data_call_time': None}
+
+ deactivate_data_call_start_time = deactivate_data_call[
+ str(whi_msg_index)]['request']['datetime_obj']
+ deactivate_data_call_end_time = line['datetime_obj']
+ deactivate_data_call_time = (
+ deactivate_data_call_end_time - deactivate_data_call_start_time)
+ deactivate_data_call[str(whi_msg_index)]['response'][
+ 'deactivate_data_call_time'] = deactivate_data_call_time.total_seconds()
+ deactivate_data_call_time_list.append(
+ {'request': deactivate_data_call[str(whi_msg_index)][
+ 'request']['message'],
+ 'response': deactivate_data_call[str(whi_msg_index)][
+ 'response']['message'],
+ 'start': deactivate_data_call_start_time,
+ 'end': deactivate_data_call_end_time,
+ 'duration': deactivate_data_call_time.total_seconds()})
+
+ if IWLAN_SEND_ACK in line['log_message']:
+ match_res = re.findall(
+ r'%s:\s(\d+)' % IWLAN_DATA_SERVICE, line['log_message'])
+ if match_res:
+ try:
+ serial = match_res[0]
+ except:
+ serial = None
+
+ if not serial:
+ continue
+
+ msg_id = serial
+
+ if msg_id not in deactivate_data_call:
+ continue
+
+ if 'response' not in deactivate_data_call[msg_id]:
+ continue
+
+ deactivate_data_call[msg_id]['response'][
+ 'send_ack_for_serial_time'] = line['datetime_obj']
+
+ deactivate_data_call_start_time = deactivate_data_call[msg_id][
+ 'request']['datetime_obj']
+ deactivate_data_call_end_time = line['datetime_obj']
+ deactivate_data_call_time = (
+ deactivate_data_call_end_time - deactivate_data_call_start_time)
+ deactivate_data_call[msg_id]['response'][
+ 'deactivate_data_call_time'] = deactivate_data_call_time.total_seconds()
+ deactivate_data_call_time_list.append(
+ {'request': deactivate_data_call[msg_id]['request'][
+ 'message'],
+ 'response': deactivate_data_call[msg_id]['response'][
+ 'message'],
+ 'start': deactivate_data_call_start_time,
+ 'end': deactivate_data_call_end_time,
+ 'duration': deactivate_data_call_time.total_seconds()})
+
+ last_message_id = None
+
+ duration_list = []
+ for item in deactivate_data_call_time_list:
+ if 'duration' in item:
+ duration_list.append(item['duration'])
+
+ try:
+ avg_deactivate_data_call_time = statistics.mean(duration_list)
+ except:
+ avg_deactivate_data_call_time = None
+
+ return (
+ deactivate_data_call,
+ deactivate_data_call_time_list,
+ avg_deactivate_data_call_time)
+
+
+def parse_ims_reg(
+ ad,
+ search_intervals=None,
+ rat='4g',
+ reboot_or_apm='reboot',
+ slot=None):
+ """Search in logcat for lines containing messages about IMS registration.
+
+ Args:
+ ad: Android object
+ search_intervals: List. Only lines with time stamp in given time
+ intervals will be parsed.
+ E.g., [(begin_time1, end_time1), (begin_time2, end_time2)]
+ Both begin_time and end_time should be datetime object.
+ rat: "4g" for IMS over LTE or "iwlan" for IMS over Wi-Fi
+ reboot_or_apm: specify the scenario "reboot" or "apm"
+ slot: 0 for pSIM and 1 for eSIM
+
+ Returns:
+ (ims_reg, parsing_fail, avg_ims_reg_duration)
+
+ ims_reg: List of dictionaries containing found lines for start and
+ end time stamps. Each dict represents a cycle of the test.
+
+ [
+ {'start': message on start time stamp,
+ 'end': message on end time stamp,
+ 'duration': time difference between start and end}
+ ]
+ parsing_fail: List of dictionaries containing the cycle number and
+ missing messages of each failed cycle
+
+ [
+ 'attempt': failed cycle number
+ 'missing_msg' missing messages which should be found
+ ]
+ avg_ims_reg_duration: average of the duration in ims_reg
+
+ """
+ if slot is None:
+ slot = get_slot_index_from_voice_sub_id(ad)
+ ad.log.info('Default voice slot: %s', slot)
+ else:
+ if get_subid_from_slot_index(ad.log, ad, slot) == INVALID_SUB_ID:
+ ad.log.error('Slot %s is invalid.', slot)
+ raise signals.TestFailure('Failed',
+ extras={'fail_reason': 'Slot %s is invalid.' % slot})
+
+ ad.log.info('Assigned slot: %s', slot)
+
+ start_command = {
+ 'reboot': {
+ '0': {'4g': ON_ENABLE_APN_IMS_SLOT0,
+ 'iwlan': ON_ENABLE_APN_IMS_HANDOVER_SLOT0 + '\|' + ON_ENABLE_APN_IMS_SLOT0},
+ '1': {'4g': ON_ENABLE_APN_IMS_SLOT1,
+ 'iwlan': ON_ENABLE_APN_IMS_HANDOVER_SLOT1 + '\|' + ON_ENABLE_APN_IMS_SLOT1}
+ },
+ 'apm':{
+ '0': {'4g': RADIO_ON_4G_SLOT0, 'iwlan': RADIO_ON_IWLAN},
+ '1': {'4g': RADIO_ON_4G_SLOT1, 'iwlan': RADIO_ON_IWLAN}
+ },
+ 'wifi_off':{
+ '0': {'4g': WIFI_OFF, 'iwlan': WIFI_OFF},
+ '1': {'4g': WIFI_OFF, 'iwlan': WIFI_OFF}
+ },
+ }
+
+ end_command = {
+ '0': {'4g': ON_IMS_MM_TEL_CONNECTED_4G_SLOT0,
+ 'iwlan': ON_IMS_MM_TEL_CONNECTED_IWLAN_SLOT0},
+ '1': {'4g': ON_IMS_MM_TEL_CONNECTED_4G_SLOT1,
+ 'iwlan': ON_IMS_MM_TEL_CONNECTED_IWLAN_SLOT1}
+ }
+
+ ad.log.info('====== Start to search logcat ======')
+ logcat = ad.search_logcat('%s\|%s' % (
+ start_command[reboot_or_apm][str(slot)][rat],
+ end_command[str(slot)][rat]))
+
+ if not logcat:
+ raise signals.TestFailure('Failed',
+ extras={'fail_reason': 'No line matching the given pattern can '
+ 'be found in logcat.'})
+
+ for msg in logcat:
+ ad.log.info(msg["log_message"])
+
+ ims_reg = []
+ ims_reg_duration_list = []
+ parsing_fail = []
+
+ start_command['reboot'] = {
+ '0': {'4g': ON_ENABLE_APN_IMS_SLOT0,
+ 'iwlan': ON_ENABLE_APN_IMS_HANDOVER_SLOT0 + '|' + ON_ENABLE_APN_IMS_SLOT0},
+ '1': {'4g': ON_ENABLE_APN_IMS_SLOT1,
+ 'iwlan': ON_ENABLE_APN_IMS_HANDOVER_SLOT1 + '|' + ON_ENABLE_APN_IMS_SLOT1}
+ }
+
+ keyword_dict = {
+ 'start': start_command[reboot_or_apm][str(slot)][rat],
+ 'end': end_command[str(slot)][rat]
+ }
+
+ for attempt, interval in enumerate(search_intervals):
+ if isinstance(interval, list):
+ try:
+ begin_time, end_time = interval
+ except Exception as e:
+ ad.log.error(e)
+ continue
+
+ ad.log.info('Parsing begin time: %s', begin_time)
+ ad.log.info('Parsing end time: %s', end_time)
+
+ temp_keyword_dict = copy.deepcopy(keyword_dict)
+ for line in logcat:
+ if begin_time and line['datetime_obj'] < begin_time:
+ continue
+
+ if end_time and line['datetime_obj'] > end_time:
+ break
+
+ for key in temp_keyword_dict:
+ if temp_keyword_dict[key] and not isinstance(
+ temp_keyword_dict[key], dict):
+ res = re.findall(
+ temp_keyword_dict[key], line['log_message'])
+ if res:
+ ad.log.info('Found: %s', line['log_message'])
+ temp_keyword_dict[key] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['datetime_obj']}
+ break
+
+ for key in temp_keyword_dict:
+ if temp_keyword_dict[key] == keyword_dict[key]:
+ ad.log.error(
+ '"%s" is missing in cycle %s.',
+ keyword_dict[key],
+ attempt)
+ parsing_fail.append({
+ 'attempt': attempt,
+ 'missing_msg': keyword_dict[key]})
+ try:
+ ims_reg_duration = (
+ temp_keyword_dict['end'][
+ 'time_stamp'] - temp_keyword_dict[
+ 'start'][
+ 'time_stamp']).total_seconds()
+ ims_reg_duration_list.append(ims_reg_duration)
+ ims_reg.append({
+ 'start': temp_keyword_dict['start'][
+ 'message'],
+ 'end': temp_keyword_dict['end'][
+ 'message'],
+ 'duration': ims_reg_duration})
+ except Exception as e:
+ ad.log.error(e)
+
+ try:
+ avg_ims_reg_duration = statistics.mean(ims_reg_duration_list)
+ except:
+ avg_ims_reg_duration = None
+
+ return ims_reg, parsing_fail, avg_ims_reg_duration
+
+
+def parse_mo_sms(logcat):
+ """Search in logcat for lines containing messages about SMS sending on
+ LTE.
+
+ Args:
+ logcat: List containing lines of logcat
+
+ Returns:
+ send_sms: Dictionary containing found lines for each SMS
+ request and response messages together with their time stamps.
+ {
+ 'message_id':{
+ 'request':{
+ 'message': logcat message body of SMS request
+ 'time_stamp': time stamp in text format
+ 'datetime_obj': datetime object of the time stamp
+ },
+ 'response':{
+ 'message': logcat message body of SMS response
+ 'time_stamp': time stamp in text format
+ 'datetime_obj': datetime object of the time stamp
+ 'sms_delivery_time': time between SMS request and
+ response
+ }
+ }
+ }
+
+ summary: the format is listed below:
+ {
+ 'request': logcat message body of SMS request
+ 'response': logcat message body of SMS response
+ 'unsol_response_new_sms': unsolicited response message upon
+ SMS receiving on MT UE
+ 'sms_body': message body of SMS
+ 'mo_start': time stamp of MO SMS request message
+ 'mo_end': time stamp of MO SMS response message
+ 'mo_signal_duration': time between MO SMS request and response
+ 'delivery_time': time between MO SMS request and
+ unsol_response_new_sms on MT UE
+ }
+
+ avg_setup_time: average of mo_signal_duration
+ """
+ send_sms = {}
+ summary = []
+ sms_body = DEFAULT_MO_SMS_BODY
+ msg_id = None
+ if not logcat:
+ return False
+
+ for line in logcat:
+ res = re.findall(MO_SMS_LOGCAT_PATTERN, line['log_message'])
+ if res:
+ try:
+ sms_body = res[0]
+ except:
+ sms_body = 'Cannot find MO SMS body'
+
+ if line['message_id']:
+ msg_id = line['message_id']
+ if SEND_SMS_REQUEST in line[
+ 'log_message'] and SEND_SMS_EXPECT_MORE not in line[
+ 'log_message']:
+ if msg_id not in send_sms:
+ send_sms[msg_id] = {}
+
+ send_sms[msg_id]['sms_body'] = sms_body
+ sms_body = DEFAULT_MO_SMS_BODY
+ send_sms[msg_id]['request'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj']}
+
+ if SEND_SMS_RESPONSE in line[
+ 'log_message'] and SEND_SMS_EXPECT_MORE not in line[
+ 'log_message']:
+ if msg_id not in send_sms:
+ continue
+
+ if 'request' not in send_sms[msg_id]:
+ continue
+
+ if "error" in line['log_message']:
+ continue
+
+ send_sms[msg_id]['response'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj'],
+ 'sms_delivery_time': None}
+
+ mo_sms_start_time = send_sms[msg_id]['request'][
+ 'datetime_obj']
+ mo_sms_end_time = line['datetime_obj']
+ sms_delivery_time = mo_sms_end_time - mo_sms_start_time
+ send_sms[msg_id]['response'][
+ 'sms_delivery_time'] = sms_delivery_time.total_seconds()
+ summary.append(
+ {'request': send_sms[msg_id]['request']['message'],
+ 'response': send_sms[msg_id]['response']['message'],
+ 'unsol_response_new_sms': None,
+ 'sms_body': send_sms[msg_id]['sms_body'],
+ 'mo_start': mo_sms_start_time,
+ 'mo_end': mo_sms_end_time,
+ 'mo_signal_duration': sms_delivery_time.total_seconds(),
+ 'delivery_time': None})
+
+ duration_list = []
+ for item in summary:
+ if 'mo_signal_duration' in item:
+ duration_list.append(item['mo_signal_duration'])
+
+ try:
+ avg_setup_time = statistics.mean(duration_list)
+ except:
+ avg_setup_time = None
+
+ return send_sms, summary, avg_setup_time
+
+
+def parse_mo_sms_iwlan(logcat):
+ """Search in logcat for lines containing messages about SMS sending on
+ iwlan.
+
+ Args:
+ logcat: List containing lines of logcat
+
+ Returns:
+ send_sms: Dictionary containing found lines for each SMS
+ request and response messages together with their time stamps.
+ {
+ 'message_id':{
+ 'request':{
+ 'message': logcat message body of SMS request
+ 'time_stamp': time stamp in text format
+ 'datetime_obj': datetime object of the time stamp
+ },
+ 'response':{
+ 'message': logcat message body of SMS response
+ 'time_stamp': time stamp in text format
+ 'datetime_obj': datetime object of the time stamp
+ 'sms_delivery_time': time between SMS request and
+ response
+ }
+ }
+ }
+
+ summary: List containing dictionaries for each SMS. The format is
+ listed below:
+ [
+ {
+ 'request': logcat message body of SMS request
+ 'response': logcat message body of SMS response
+ 'sms_body': message body of SMS
+ 'mo_start': time stamp of MO SMS request message
+ 'mo_end': time stamp of MO SMS response message
+ 'mo_signal_duration': time between MO SMS request and
+ response
+ 'delivery_time': time between MO SMS request and
+ MT SMS received message
+ }
+ ]
+
+ avg_setup_time: average of mo_signal_duration
+ """
+ send_sms = {}
+ summary = []
+ sms_body = DEFAULT_MO_SMS_BODY
+ msg_id = None
+
+ if not logcat:
+ return False
+
+ for line in logcat:
+ res = re.findall(MO_SMS_LOGCAT_PATTERN, line['log_message'])
+ if res:
+ try:
+ sms_body = res[0]
+ except:
+ sms_body = 'Cannot find MO SMS body'
+
+ if SEND_SMS_REQUEST_OVER_IMS in line['log_message']:
+ if msg_id is None:
+ msg_id = '0'
+ else:
+ msg_id = str(int(msg_id) + 1)
+
+ if msg_id not in send_sms:
+ send_sms[msg_id] = {}
+
+ send_sms[msg_id]['sms_body'] = sms_body
+ sms_body = DEFAULT_MO_SMS_BODY
+ send_sms[msg_id]['request'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj']}
+
+ if SEND_SMS_RESPONSE_OVER_IMS in line['log_message']:
+
+ if msg_id not in send_sms:
+ continue
+
+ if 'request' not in send_sms[msg_id]:
+ continue
+
+ if "error" in line['log_message']:
+ continue
+
+ send_sms[msg_id]['response'] = {
+ 'message': line['log_message'],
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj'],
+ 'sms_delivery_time': None}
+
+ mo_sms_start_time = send_sms[msg_id]['request'][
+ 'datetime_obj']
+ mo_sms_end_time = line['datetime_obj']
+ sms_delivery_time = mo_sms_end_time - mo_sms_start_time
+ send_sms[msg_id]['response'][
+ 'sms_delivery_time'] = sms_delivery_time.total_seconds()
+ summary.append(
+ {'request': send_sms[msg_id]['request']['message'],
+ 'response': send_sms[msg_id]['response']['message'],
+ 'unsol_response_new_sms': None,
+ 'sms_body': send_sms[msg_id]['sms_body'],
+ 'mo_start': mo_sms_start_time,
+ 'mo_end': mo_sms_end_time,
+ 'mo_signal_duration': sms_delivery_time.total_seconds(),
+ 'delivery_time': None})
+
+ duration_list = []
+ for item in summary:
+ if 'mo_signal_duration' in item:
+ duration_list.append(item['mo_signal_duration'])
+
+ try:
+ avg_setup_time = statistics.mean(duration_list)
+ except:
+ avg_setup_time = None
+
+ return send_sms, summary, avg_setup_time
+
+
+def parse_mt_sms(logcat):
+ """Search in logcat for lines containing messages about SMS receiving on
+ LTE.
+
+ Args:
+ logcat: List containing lines of logcat
+
+ Returns:
+ received_sms_list: List containing dictionaries for each received
+ SMS. The format is listed below:
+ [
+ {
+ 'message': logcat message body of unsolicited response
+ message
+ 'sms_body': message body of SMS
+ 'time_stamp': time stamp of unsolicited response message in
+ text format
+ 'datetime_obj': datetime object of the time stamp
+ 'sms_delivery_time': time between SMS request and
+ response
+ }
+ ]
+ """
+ received_sms_list = []
+ if not logcat:
+ return False
+
+ for line in logcat:
+ if UNSOL_RESPONSE_NEW_SMS in line['log_message']:
+
+ # if received_sms_list:
+ # if received_sms_list[-1]['sms_body'] is None:
+ # del received_sms_list[-1]
+
+ received_sms_list.append(
+ {'message': line['log_message'],
+ 'sms_body': DEFAULT_MT_SMS_BODY,
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj']})
+ else:
+ res = re.findall(MT_SMS_CONTENT_PATTERN, line['log_message'])
+
+ if res:
+ try:
+ sms_body = res[0]
+ except:
+ sms_body = 'Cannot find MT SMS body'
+
+ if received_sms_list[-1]['sms_body'] == DEFAULT_MT_SMS_BODY:
+ received_sms_list[-1]['sms_body'] = sms_body
+ continue
+
+ return received_sms_list
+
+
+def parse_mt_sms_iwlan(logcat):
+ """Search in logcat for lines containing messages about SMS receiving on
+ iwlan.
+
+ Args:
+ logcat: List containing lines of logcat
+
+ Returns:
+ received_sms_list: List containing dictionaries for each received
+ SMS. The format is listed below:
+ [
+ {
+ 'message': logcat message body of SMS received message
+ 'sms_body': message body of SMS
+ 'time_stamp': time stamp of SMS received message in
+ text format
+ 'datetime_obj': datetime object of the time stamp
+ }
+ ]
+ """
+ received_sms_list = []
+ if not logcat:
+ return False
+
+ for line in logcat:
+ if re.findall(
+ SMS_RECEIVED_OVER_IMS_SLOT0 + '|' + SMS_RECEIVED_OVER_IMS_SLOT1,
+ line['log_message']):
+ received_sms_list.append(
+ {'message': line['log_message'],
+ 'sms_body': DEFAULT_MT_SMS_BODY,
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj']})
+ else:
+ res = re.findall(MT_SMS_CONTENT_PATTERN, line['log_message'])
+
+ if res:
+ try:
+ sms_body = res[0]
+ except:
+ sms_body = 'Cannot find MT SMS body'
+
+ if received_sms_list[-1]['sms_body'] == DEFAULT_MT_SMS_BODY:
+ received_sms_list[-1]['sms_body'] = sms_body
+ continue
+
+ return received_sms_list
+
+
+def parse_sms_delivery_time(log, ad_mo, ad_mt, rat='4g'):
+ """Calculate the SMS delivery time (time between MO SMS request and MT
+ unsolicited response message or MT SMS received message) from logcat
+ of both MO and MT UE.
+
+ Args:
+ ad_mo: MO Android object
+ ad_mt: MT Android object
+ rat: '4g' for LTE and 'iwlan' for iwlan
+
+ Returns:
+ None
+ """
+ ad_mo.log.info('====== Start to search logcat ====== ')
+ mo_logcat = ad_mo.search_logcat(
+ r'%s\|%s\|%s\|%s' % (
+ SMS_SEND_TEXT_MESSAGE,
+ SEND_SMS,
+ SEND_SMS_REQUEST_OVER_IMS,
+ SEND_SMS_RESPONSE_OVER_IMS))
+ ad_mt.log.info('====== Start to search logcat ====== ')
+ mt_logcat = ad_mt.search_logcat(
+ r'%s\|%s\|%s' % (
+ UNSOL_RESPONSE_NEW_SMS, SMS_RECEIVED, SMS_RECEIVED_OVER_IMS))
+
+ for msg in mo_logcat:
+ ad_mo.log.info(msg["log_message"])
+ for msg in mt_logcat:
+ ad_mt.log.info(msg["log_message"])
+
+ if rat == 'iwlan':
+ _, mo_sms_summary, avg = parse_mo_sms_iwlan(mo_logcat)
+ received_sms_list = parse_mt_sms_iwlan(mt_logcat)
+ else:
+ _, mo_sms_summary, avg = parse_mo_sms(mo_logcat)
+ received_sms_list = parse_mt_sms(mt_logcat)
+
+ sms_delivery_time = []
+ for mo_sms in mo_sms_summary:
+ for mt_sms in received_sms_list:
+ if mo_sms['sms_body'] == mt_sms['sms_body']:
+ mo_sms['delivery_time'] = (
+ mt_sms['datetime_obj'] - mo_sms['mo_start']).total_seconds()
+ mo_sms['unsol_response_new_sms'] = mt_sms['message']
+ sms_delivery_time.append(mo_sms['delivery_time'])
+
+ try:
+ avg_sms_delivery_time = statistics.mean(sms_delivery_time)
+ except:
+ avg_sms_delivery_time = None
+
+ ad_mo.log.info('====== MO SMS summary ======')
+ for item in mo_sms_summary:
+ ad_mo.log.info('------------------')
+ print_nested_dict(ad_mo, item)
+ ad_mt.log.info('====== Received SMS list ======')
+ for item in received_sms_list:
+ ad_mt.log.info('------------------')
+ print_nested_dict(ad_mt, item)
+
+ ad_mo.log.info('%s SMS were actually sent.', len(mo_sms_summary))
+ ad_mt.log.info('%s SMS were actually received.', len(received_sms_list))
+ ad_mo.log.info('Average MO SMS setup time: %.2f sec.', avg)
+ log.info(
+ 'Average SMS delivery time: %.2f sec.', avg_sms_delivery_time)
+
+
+def parse_mms(ad_mo, ad_mt):
+ """Search in logcat for lines containing messages about SMS sending and
+ receiving. Calculate MO & MT MMS setup time.
+
+ Args:
+ ad_mo: MO Android object
+ ad_mt: MT Android object
+
+ Returns:
+ send_mms: Dictionary containing each sent MMS. The format is shown
+ as below:
+ {
+ mms_msg_id:
+ {
+ MMS_START_NEW_NW_REQUEST:
+ {
+ 'time_stamp': time stamp of MMS request on MO UE in
+ text format
+ 'datetime_obj': datetime object of time stamp
+ },
+ MMS_200_OK:
+ {
+ 'time_stamp': time stamp of '200 OK' for MMS request
+ in text format
+ 'datetime_obj': datetime object of time stamp
+ 'setup_time': MO MMS setup time. Time between MMS
+ request and 200 OK
+ }
+ }
+
+ }
+
+ mo_avg_setup_time: average of MO MMS setup time
+
+ receive_mms: Dictionary containing each received MMS. The format is
+ shown as below:
+ {
+ mms_msg_id:
+ {
+ MMS_START_NEW_NW_REQUEST:
+ {
+ 'time_stamp': time stamp of MMS request on MT UE in
+ text format
+ 'datetime_obj': datetime object of time stamp
+ },
+ MMS_200_OK:
+ {
+ 'time_stamp': time stamp of '200 OK' for MMS request
+ in text format
+ 'datetime_obj': datetime object of time stamp
+ 'setup_time': MT MMS setup time. Time between MMS
+ request and 200 OK
+ }
+ }
+
+ }
+
+ mt_avg_setup_time: average of MT MMS setup time
+ """
+ send_mms = {}
+ receive_mms = {}
+ mo_setup_time_list = []
+ mt_setup_time_list = []
+
+ ad_mo.log.info('====== Start to search logcat ====== ')
+ mo_logcat = ad_mo.search_logcat(MMS_SERVICE)
+ for msg in mo_logcat:
+ ad_mo.log.info(msg["log_message"])
+
+ ad_mt.log.info('====== Start to search logcat ====== ')
+ mt_logcat = ad_mt.search_logcat(MMS_SERVICE)
+ for msg in mt_logcat:
+ ad_mt.log.info(msg["log_message"])
+
+ if not mo_logcat or not mt_logcat:
+ return False
+
+ for line in mo_logcat:
+ find_res = re.findall(
+ MMS_SEND_REQUEST_ID_PATTERN, line['log_message'])
+
+ message_id = None
+ try:
+ message_id = find_res[0]
+ except:
+ pass
+
+ if message_id:
+ mms_msg_id = message_id
+ if mms_msg_id not in send_mms:
+ send_mms[mms_msg_id] = {}
+ if MMS_START_NEW_NW_REQUEST in line['log_message']:
+ send_mms[mms_msg_id][MMS_START_NEW_NW_REQUEST] = {
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj']}
+
+ if MMS_200_OK in line['log_message']:
+ send_mms[mms_msg_id][MMS_200_OK] = {
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj'],
+ 'setup_time': None}
+
+ if MMS_START_NEW_NW_REQUEST in send_mms[mms_msg_id]:
+ setup_time = line['datetime_obj'] - send_mms[mms_msg_id][
+ MMS_START_NEW_NW_REQUEST]['datetime_obj']
+ send_mms[mms_msg_id][MMS_200_OK][
+ 'setup_time'] = setup_time.total_seconds()
+ mo_setup_time_list.append(setup_time.total_seconds())
+
+ for line in mt_logcat:
+ find_res = re.findall(
+ MMS_DOWNLOAD_REQUEST_ID_PATTERN, line['log_message'])
+
+ message_id = None
+ try:
+ message_id = find_res[0]
+ except:
+ pass
+
+ if message_id:
+ mms_msg_id = message_id
+ if mms_msg_id not in receive_mms:
+ receive_mms[mms_msg_id] = {}
+ if MMS_START_NEW_NW_REQUEST in line['log_message']:
+ receive_mms[mms_msg_id][MMS_START_NEW_NW_REQUEST] = {
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj']}
+
+ if MMS_200_OK in line['log_message']:
+ receive_mms[mms_msg_id][MMS_200_OK] = {
+ 'time_stamp': line['time_stamp'],
+ 'datetime_obj': line['datetime_obj'],
+ 'setup_time': None}
+
+ if MMS_START_NEW_NW_REQUEST in receive_mms[mms_msg_id]:
+ setup_time = line['datetime_obj'] - receive_mms[
+ mms_msg_id][MMS_START_NEW_NW_REQUEST]['datetime_obj']
+ receive_mms[mms_msg_id][MMS_200_OK][
+ 'setup_time'] = setup_time.total_seconds()
+ mt_setup_time_list.append(setup_time.total_seconds())
+
+ try:
+ mo_avg_setup_time = statistics.mean(mo_setup_time_list)
+ except:
+ mo_avg_setup_time = None
+
+ try:
+ mt_avg_setup_time = statistics.mean(mt_setup_time_list)
+ except:
+ mt_avg_setup_time = None
+
+ return send_mms, mo_avg_setup_time, receive_mms, mt_avg_setup_time
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_phone_setup_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_phone_setup_utils.py
new file mode 100644
index 0000000..6077d9c
--- /dev/null
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_phone_setup_utils.py
@@ -0,0 +1,1758 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - Google
+#
+# 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_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE
+from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC
+from acts_contrib.test_utils.tel.tel_defines import CARRIER_FRE
+from acts_contrib.test_utils.tel.tel_defines import CARRIER_TMO
+from acts_contrib.test_utils.tel.tel_defines import GEN_2G
+from acts_contrib.test_utils.tel.tel_defines import GEN_3G
+from acts_contrib.test_utils.tel.tel_defines import GEN_4G
+from acts_contrib.test_utils.tel.tel_defines import GEN_5G
+from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_DROP
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOLTE_ENABLED
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_CDMA
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GSM_ONLY
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GSM_UMTS
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_CDMA_EVDO
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_GSM_WCDMA
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_ONLY
+from acts_contrib.test_utils.tel.tel_defines import RAT_1XRTT
+from acts_contrib.test_utils.tel.tel_defines import RAT_5G
+from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_CDMA2000
+from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
+from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
+from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_WCDMA
+from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_WLAN
+from acts_contrib.test_utils.tel.tel_defines import RAT_UNKNOWN
+from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_IDLE
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_1XRTT_VOICE_ATTACH
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
+from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte_for_subscription
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode_for_subscription
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_enhanced_4g_lte_setting
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_volte_enabled
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_enabled
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_disabled
+from acts_contrib.test_utils.tel.tel_lookup_tables import network_preference_for_generation
+from acts_contrib.test_utils.tel.tel_lookup_tables import rat_families_for_network_preference
+from acts_contrib.test_utils.tel.tel_lookup_tables import rat_family_for_generation
+from acts_contrib.test_utils.tel.tel_lookup_tables import rat_family_from_rat
+from acts_contrib.test_utils.tel.tel_lookup_tables import rat_generation_from_rat
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id
+from acts_contrib.test_utils.tel.tel_test_utils import _is_attached
+from acts_contrib.test_utils.tel.tel_test_utils import _is_attached_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import _wait_for_droid_in_state
+from acts_contrib.test_utils.tel.tel_test_utils import _wait_for_droid_in_state_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import get_capability_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import get_cell_data_roaming_state_by_adb
+from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
+from acts_contrib.test_utils.tel.tel_test_utils import get_telephony_signal_strength
+from acts_contrib.test_utils.tel.tel_test_utils import is_droid_in_network_generation_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import is_droid_in_rat_family_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import is_droid_in_rat_family_list_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import reset_preferred_network_type_to_allowable_range
+from acts_contrib.test_utils.tel.tel_test_utils import set_cell_data_roaming_state_by_adb
+from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_network_mode_pref
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
+from acts_contrib.test_utils.tel.tel_test_utils import wait_for_data_attach_for_subscription
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import set_wifi_to_default
+from acts.libs.utils.multithread import multithread_func
+
+
+def phone_setup_iwlan(log,
+ ad,
+ is_airplane_mode,
+ wfc_mode,
+ wifi_ssid=None,
+ wifi_pwd=None,
+ nw_gen=None):
+ """Phone setup function for epdg call test.
+ Set WFC mode according to wfc_mode.
+ Set airplane mode according to is_airplane_mode.
+ 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.
+ is_airplane_mode: True to turn on airplane mode. False to turn off airplane mode.
+ wfc_mode: WFC mode to set to.
+ 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.
+ nw_gen: network type selection. This is optional.
+ GEN_4G for 4G, GEN_5G for 5G or None for doing nothing.
+ Returns:
+ True if success. False if fail.
+ """
+ return phone_setup_iwlan_for_subscription(log, ad,
+ get_outgoing_voice_sub_id(ad),
+ is_airplane_mode, wfc_mode,
+ wifi_ssid, wifi_pwd, nw_gen)
+
+
+def phone_setup_iwlan_for_subscription(log,
+ ad,
+ sub_id,
+ is_airplane_mode,
+ wfc_mode,
+ wifi_ssid=None,
+ wifi_pwd=None,
+ nw_gen=None,
+ nr_type=None):
+ """Phone setup function for epdg call test for subscription id.
+ Set WFC mode according to wfc_mode.
+ Set airplane mode according to is_airplane_mode.
+ 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.
+ sub_id: subscription id.
+ is_airplane_mode: True to turn on airplane mode. False to turn off airplane mode.
+ wfc_mode: WFC mode to set to.
+ 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.
+ nw_gen: network type selection. This is optional.
+ GEN_4G for 4G, GEN_5G for 5G or None for doing nothing.
+ nr_type: NR network type
+ 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.")
+
+ if nw_gen:
+ if not ensure_network_generation_for_subscription(
+ log, ad, sub_id, nw_gen, voice_or_data=NETWORK_SERVICE_DATA,
+ nr_type=nr_type):
+ ad.log.error("Failed to set to %s data.", nw_gen)
+ return False
+ toggle_airplane_mode(log, ad, is_airplane_mode, strict_checking=False)
+
+ # Pause at least for 4 seconds is necessary after airplane mode was turned
+ # on due to the mechanism of deferring Wi-Fi (b/191481736)
+ if is_airplane_mode:
+ time.sleep(5)
+
+ # 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)
+ return False
+ else:
+ 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_for_subscription(ad, wfc_mode, sub_id):
+ ad.log.error("Unable to set WFC mode to %s.", wfc_mode)
+ return False
+
+ if wfc_mode != WFC_MODE_DISABLED:
+ if not wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED):
+ ad.log.error("WFC is not enabled")
+ return False
+
+ return True
+
+
+def phone_setup_iwlan_cellular_preferred(log,
+ ad,
+ wifi_ssid=None,
+ wifi_pwd=None):
+ """Phone setup function for iwlan Non-APM CELLULAR_PREFERRED test.
+ Set WFC mode according to CELLULAR_PREFERRED.
+ Set airplane mode according to False.
+ Make sure phone connect to WiFi. (If wifi_ssid is not None.)
+ Make sure phone don't report iwlan data network type.
+ Make sure phone don't report wfc enabled flag to be true.
+
+ Args:
+ log: Log object.
+ ad: Android device object.
+ 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.
+ """
+ toggle_airplane_mode(log, ad, False, strict_checking=False)
+ try:
+ toggle_volte(log, ad, True)
+ if not wait_for_network_generation(
+ log, ad, GEN_4G, voice_or_data=NETWORK_SERVICE_DATA):
+ if not ensure_network_generation(
+ log, ad, GEN_4G, voice_or_data=NETWORK_SERVICE_DATA):
+ ad.log.error("Fail to ensure data in 4G")
+ return False
+ except Exception as e:
+ ad.log.error(e)
+ ad.droid.telephonyToggleDataConnection(True)
+ if wifi_ssid is not None:
+ if not ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd):
+ ad.log.error("Connect to WiFi failed.")
+ return False
+ if not set_wfc_mode(log, ad, WFC_MODE_CELLULAR_PREFERRED):
+ ad.log.error("Set WFC mode failed.")
+ return False
+ if not wait_for_not_network_rat(
+ log, ad, RAT_FAMILY_WLAN, voice_or_data=NETWORK_SERVICE_DATA):
+ ad.log.error("Data rat in iwlan mode.")
+ return False
+ elif not wait_for_wfc_disabled(log, ad, MAX_WAIT_TIME_WFC_ENABLED):
+ ad.log.error("Should report wifi calling disabled within %s.",
+ MAX_WAIT_TIME_WFC_ENABLED)
+ return False
+ return True
+
+
+def phone_setup_data_for_subscription(log, ad, sub_id, network_generation,
+ nr_type=None):
+ """Setup Phone <sub_id> Data to <network_generation>
+
+ Args:
+ log: log object
+ ad: android device object
+ sub_id: subscription id
+ network_generation: network generation, e.g. GEN_2G, GEN_3G, GEN_4G, GEN_5G
+ nr_type: NR network type e.g. NSA, SA, MMWAVE
+
+ Returns:
+ True if success, False if fail.
+ """
+ toggle_airplane_mode(log, ad, False, strict_checking=False)
+ set_wifi_to_default(log, ad)
+ if not set_wfc_mode(log, ad, WFC_MODE_DISABLED):
+ ad.log.error("Disable WFC failed.")
+ return False
+ if not ensure_network_generation_for_subscription(
+ log,
+ ad,
+ sub_id,
+ network_generation,
+ voice_or_data=NETWORK_SERVICE_DATA,
+ nr_type=nr_type):
+ get_telephony_signal_strength(ad)
+ return False
+ return True
+
+
+def phone_setup_5g(log, ad, nr_type=None):
+ """Setup Phone default data sub_id data to 5G.
+
+ Args:
+ log: log object
+ ad: android device object
+
+ Returns:
+ True if success, False if fail.
+ """
+ return phone_setup_5g_for_subscription(log, ad,
+ get_default_data_sub_id(ad), nr_type=nr_type)
+
+
+def phone_setup_5g_for_subscription(log, ad, sub_id, nr_type=None):
+ """Setup Phone <sub_id> Data to 5G.
+
+ Args:
+ log: log object
+ ad: android device object
+ sub_id: subscription id
+ nr_type: NR network type e.g. NSA, SA, MMWAVE
+
+ Returns:
+ True if success, False if fail.
+ """
+ return phone_setup_data_for_subscription(log, ad, sub_id, GEN_5G,
+ nr_type=nr_type)
+
+
+def phone_setup_4g(log, ad):
+ """Setup Phone default data sub_id data to 4G.
+
+ Args:
+ log: log object
+ ad: android device object
+
+ Returns:
+ True if success, False if fail.
+ """
+ return phone_setup_4g_for_subscription(log, ad,
+ get_default_data_sub_id(ad))
+
+
+def phone_setup_4g_for_subscription(log, ad, sub_id):
+ """Setup Phone <sub_id> Data to 4G.
+
+ Args:
+ log: log object
+ ad: android device object
+ sub_id: subscription id
+
+ Returns:
+ True if success, False if fail.
+ """
+ return phone_setup_data_for_subscription(log, ad, sub_id, GEN_4G)
+
+
+def phone_setup_3g(log, ad):
+ """Setup Phone default data sub_id data to 3G.
+
+ Args:
+ log: log object
+ ad: android device object
+
+ Returns:
+ True if success, False if fail.
+ """
+ return phone_setup_3g_for_subscription(log, ad,
+ get_default_data_sub_id(ad))
+
+
+def phone_setup_3g_for_subscription(log, ad, sub_id):
+ """Setup Phone <sub_id> Data to 3G.
+
+ Args:
+ log: log object
+ ad: android device object
+ sub_id: subscription id
+
+ Returns:
+ True if success, False if fail.
+ """
+ return phone_setup_data_for_subscription(log, ad, sub_id, GEN_3G)
+
+
+def phone_setup_2g(log, ad):
+ """Setup Phone default data sub_id data to 2G.
+
+ Args:
+ log: log object
+ ad: android device object
+
+ Returns:
+ True if success, False if fail.
+ """
+ return phone_setup_2g_for_subscription(log, ad,
+ get_default_data_sub_id(ad))
+
+
+def phone_setup_2g_for_subscription(log, ad, sub_id):
+ """Setup Phone <sub_id> Data to 3G.
+
+ Args:
+ log: log object
+ ad: android device object
+ sub_id: subscription id
+
+ Returns:
+ True if success, False if fail.
+ """
+ return phone_setup_data_for_subscription(log, ad, sub_id, GEN_2G)
+
+
+def phone_setup_csfb(log, ad, nw_gen=GEN_4G, nr_type=None):
+ """Setup phone for CSFB call test.
+
+ Setup Phone to be in 4G mode.
+ Disabled VoLTE.
+
+ Args:
+ log: log object
+ ad: Android device object.
+ nw_gen: GEN_4G or GEN_5G
+
+ Returns:
+ True if setup successfully.
+ False for errors.
+ """
+ return phone_setup_csfb_for_subscription(log, ad,
+ get_outgoing_voice_sub_id(ad), nw_gen, nr_type=nr_type)
+
+
+def phone_setup_csfb_for_subscription(log, ad, sub_id, nw_gen=GEN_4G, nr_type=None):
+ """Setup phone for CSFB call test for subscription id.
+
+ Setup Phone to be in 4G mode.
+ Disabled VoLTE.
+
+ Args:
+ log: log object
+ ad: Android device object.
+ sub_id: subscription id.
+ nw_gen: GEN_4G or GEN_5G
+ nr_type: NR network type e.g. NSA, SA, MMWAVE
+
+ Returns:
+ True if setup successfully.
+ False for errors.
+ """
+ capabilities = ad.telephony["subscription"][sub_id].get("capabilities", [])
+ if capabilities:
+ if "hide_enhanced_4g_lte" in capabilities:
+ show_enhanced_4g_lte_mode = getattr(ad, "show_enhanced_4g_lte_mode", False)
+ if show_enhanced_4g_lte_mode in ["false", "False", False]:
+ ad.log.warning("'VoLTE' option is hidden. Test will be skipped.")
+ raise signals.TestSkip("'VoLTE' option is hidden. Test will be skipped.")
+
+ if nw_gen == GEN_4G:
+ if not phone_setup_4g_for_subscription(log, ad, sub_id):
+ ad.log.error("Failed to set to 4G data.")
+ return False
+ elif nw_gen == GEN_5G:
+ if not phone_setup_5g_for_subscription(log, ad, sub_id, nr_type=nr_type):
+ ad.log.error("Failed to set to 5G data.")
+ return False
+
+ if not toggle_volte_for_subscription(log, ad, sub_id, False):
+ return False
+
+ if not wait_for_voice_attach_for_subscription(log, ad, sub_id,
+ MAX_WAIT_TIME_NW_SELECTION):
+ return False
+
+ return phone_idle_csfb_for_subscription(log, ad, sub_id, nw_gen)
+
+
+def phone_setup_volte(log, ad, nw_gen=GEN_4G, nr_type=None):
+ """Setup VoLTE enable.
+
+ Args:
+ log: log object
+ ad: android device object.
+ nw_gen: GEN_4G or GEN_5G
+
+ 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.")
+ return phone_setup_volte_for_subscription(log, ad,
+ get_outgoing_voice_sub_id(ad), nw_gen, nr_type= nr_type)
+
+
+def phone_setup_volte_for_subscription(log, ad, sub_id, nw_gen=GEN_4G,
+ nr_type=None):
+ """Setup VoLTE enable for subscription id.
+ Args:
+ log: log object
+ ad: android device object.
+ sub_id: subscription id.
+ nw_gen: GEN_4G or GEN_5G.
+ nr_type: NR network type.
+
+ 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 nw_gen == GEN_4G:
+ if not phone_setup_4g_for_subscription(log, ad, sub_id):
+ ad.log.error("Failed to set to 4G data.")
+ return False
+ elif nw_gen == GEN_5G:
+ if not phone_setup_5g_for_subscription(log, ad, sub_id,
+ nr_type=nr_type):
+ ad.log.error("Failed to set to 5G data.")
+ return False
+ operator_name = get_operator_name(log, ad, sub_id)
+ if operator_name == CARRIER_TMO:
+ return True
+ else:
+ 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)
+ return phone_idle_volte_for_subscription(log, ad, sub_id, nw_gen,
+ nr_type=nr_type)
+
+
+def phone_setup_voice_3g(log, ad):
+ """Setup phone voice to 3G.
+
+ Args:
+ log: log object
+ ad: Android device object.
+
+ Returns:
+ True if setup successfully.
+ False for errors.
+ """
+ return phone_setup_voice_3g_for_subscription(log, ad,
+ get_outgoing_voice_sub_id(ad))
+
+
+def phone_setup_voice_3g_for_subscription(log, ad, sub_id):
+ """Setup phone voice to 3G for subscription id.
+
+ Args:
+ log: log object
+ ad: Android device object.
+ sub_id: subscription id.
+
+ Returns:
+ True if setup successfully.
+ False for errors.
+ """
+ if not phone_setup_3g_for_subscription(log, ad, sub_id):
+ ad.log.error("Failed to set to 3G data.")
+ return False
+ if not wait_for_voice_attach_for_subscription(log, ad, sub_id,
+ MAX_WAIT_TIME_NW_SELECTION):
+ return False
+ return phone_idle_3g_for_subscription(log, ad, sub_id)
+
+
+def phone_setup_voice_2g(log, ad):
+ """Setup phone voice to 2G.
+
+ Args:
+ log: log object
+ ad: Android device object.
+
+ Returns:
+ True if setup successfully.
+ False for errors.
+ """
+ return phone_setup_voice_2g_for_subscription(log, ad,
+ get_outgoing_voice_sub_id(ad))
+
+
+def phone_setup_voice_2g_for_subscription(log, ad, sub_id):
+ """Setup phone voice to 2G for subscription id.
+
+ Args:
+ log: log object
+ ad: Android device object.
+ sub_id: subscription id.
+
+ Returns:
+ True if setup successfully.
+ False for errors.
+ """
+ if not phone_setup_2g_for_subscription(log, ad, sub_id):
+ ad.log.error("Failed to set to 2G data.")
+ return False
+ if not wait_for_voice_attach_for_subscription(log, ad, sub_id,
+ MAX_WAIT_TIME_NW_SELECTION):
+ return False
+ return phone_idle_2g_for_subscription(log, ad, sub_id)
+
+
+def phone_setup_voice_general(log, ad):
+ """Setup phone for voice general call test.
+
+ Make sure phone attached to voice.
+ Make necessary delay.
+
+ Args:
+ ad: Android device object.
+
+ Returns:
+ True if setup successfully.
+ False for errors.
+ """
+ return phone_setup_voice_general_for_subscription(
+ log, ad, get_outgoing_voice_sub_id(ad))
+
+
+def phone_setup_voice_general_for_slot(log,ad,slot_id):
+ return phone_setup_voice_general_for_subscription(
+ log, ad, get_subid_from_slot_index(log,ad,slot_id))
+
+
+def phone_setup_voice_general_for_subscription(log, ad, sub_id):
+ """Setup phone for voice general call test for subscription id.
+
+ Make sure phone attached to voice.
+ Make necessary delay.
+
+ Args:
+ ad: Android device object.
+ sub_id: subscription id.
+
+ Returns:
+ True if setup successfully.
+ False for errors.
+ """
+ toggle_airplane_mode(log, ad, False, strict_checking=False)
+ if not wait_for_voice_attach_for_subscription(log, ad, sub_id,
+ MAX_WAIT_TIME_NW_SELECTION):
+ # if phone can not attach voice, try phone_setup_voice_3g
+ return phone_setup_voice_3g_for_subscription(log, ad, sub_id)
+ return True
+
+
+def phone_setup_data_general(log, ad):
+ """Setup phone for data general test.
+
+ Make sure phone attached to data.
+ Make necessary delay.
+
+ Args:
+ ad: Android device object.
+
+ Returns:
+ True if setup successfully.
+ False for errors.
+ """
+ return phone_setup_data_general_for_subscription(
+ log, ad, ad.droid.subscriptionGetDefaultDataSubId())
+
+
+def phone_setup_data_general_for_subscription(log, ad, sub_id):
+ """Setup phone for data general test for subscription id.
+
+ Make sure phone attached to data.
+ Make necessary delay.
+
+ Args:
+ ad: Android device object.
+ sub_id: subscription id.
+
+ Returns:
+ True if setup successfully.
+ False for errors.
+ """
+ toggle_airplane_mode(log, ad, False, strict_checking=False)
+ if not wait_for_data_attach_for_subscription(log, ad, sub_id,
+ MAX_WAIT_TIME_NW_SELECTION):
+ # if phone can not attach data, try reset network preference settings
+ reset_preferred_network_type_to_allowable_range(log, ad)
+
+ return wait_for_data_attach_for_subscription(log, ad, sub_id,
+ MAX_WAIT_TIME_NW_SELECTION)
+
+
+def phone_setup_rat_for_subscription(log, ad, sub_id, network_preference,
+ rat_family):
+ toggle_airplane_mode(log, ad, False, strict_checking=False)
+ set_wifi_to_default(log, ad)
+ if not set_wfc_mode(log, ad, WFC_MODE_DISABLED):
+ ad.log.error("Disable WFC failed.")
+ return False
+ return ensure_network_rat_for_subscription(log, ad, sub_id,
+ network_preference, rat_family)
+
+
+def phone_setup_lte_gsm_wcdma(log, ad):
+ return phone_setup_lte_gsm_wcdma_for_subscription(
+ log, ad, ad.droid.subscriptionGetDefaultSubId())
+
+
+def phone_setup_lte_gsm_wcdma_for_subscription(log, ad, sub_id):
+ return phone_setup_rat_for_subscription(
+ log, ad, sub_id, NETWORK_MODE_LTE_GSM_WCDMA, RAT_FAMILY_LTE)
+
+
+def phone_setup_gsm_umts(log, ad):
+ return phone_setup_gsm_umts_for_subscription(
+ log, ad, ad.droid.subscriptionGetDefaultSubId())
+
+
+def phone_setup_gsm_umts_for_subscription(log, ad, sub_id):
+ return phone_setup_rat_for_subscription(
+ log, ad, sub_id, NETWORK_MODE_GSM_UMTS, RAT_FAMILY_WCDMA)
+
+
+def phone_setup_gsm_only(log, ad):
+ return phone_setup_gsm_only_for_subscription(
+ log, ad, ad.droid.subscriptionGetDefaultSubId())
+
+
+def phone_setup_gsm_only_for_subscription(log, ad, sub_id):
+ return phone_setup_rat_for_subscription(
+ log, ad, sub_id, NETWORK_MODE_GSM_ONLY, RAT_FAMILY_GSM)
+
+
+def phone_setup_lte_cdma_evdo(log, ad):
+ return phone_setup_lte_cdma_evdo_for_subscription(
+ log, ad, ad.droid.subscriptionGetDefaultSubId())
+
+
+def phone_setup_lte_cdma_evdo_for_subscription(log, ad, sub_id):
+ return phone_setup_rat_for_subscription(
+ log, ad, sub_id, NETWORK_MODE_LTE_CDMA_EVDO, RAT_FAMILY_LTE)
+
+
+def phone_setup_cdma(log, ad):
+ return phone_setup_cdma_for_subscription(
+ log, ad, ad.droid.subscriptionGetDefaultSubId())
+
+
+def phone_setup_cdma_for_subscription(log, ad, sub_id):
+ return phone_setup_rat_for_subscription(log, ad, sub_id, NETWORK_MODE_CDMA,
+ RAT_FAMILY_CDMA2000)
+
+
+def phone_idle_volte(log, ad):
+ """Return if phone is idle for VoLTE call test.
+
+ Args:
+ ad: Android device object.
+ """
+ return phone_idle_volte_for_subscription(log, ad,
+ get_outgoing_voice_sub_id(ad))
+
+
+def phone_idle_volte_for_subscription(log, ad, sub_id, nw_gen=GEN_4G,
+ nr_type=None):
+ """Return if phone is idle for VoLTE call test for subscription id.
+ Args:
+ ad: Android device object.
+ sub_id: subscription id.
+ nw_gen: GEN_4G or GEN_5G.
+ nr_type: NR network type e.g. NSA, SA, MMWAVE
+ """
+ if nw_gen == GEN_5G:
+ if not is_current_network_5g(ad, sub_id=sub_id, nr_type=nr_type):
+ ad.log.error("Not in 5G coverage.")
+ return False
+ else:
+ if not wait_for_network_rat_for_subscription(
+ log, ad, sub_id, RAT_FAMILY_LTE,
+ 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, sub_id):
+ ad.log.error(
+ "Failed to <report volte enabled true> within %s seconds.",
+ MAX_WAIT_TIME_VOLTE_ENABLED)
+ return False
+ return True
+
+
+def phone_idle_iwlan(log, ad):
+ """Return if phone is idle for WiFi calling call test.
+
+ Args:
+ ad: Android device object.
+ """
+ return phone_idle_iwlan_for_subscription(log, ad,
+ get_outgoing_voice_sub_id(ad))
+
+
+def phone_idle_iwlan_for_subscription(log, ad, sub_id):
+ """Return if phone is idle for WiFi calling call test for subscription id.
+
+ Args:
+ ad: Android device object.
+ sub_id: subscription id.
+ """
+ if not wait_for_wfc_enabled(log, ad, MAX_WAIT_TIME_WFC_ENABLED):
+ ad.log.error("Failed to <report wfc enabled true> within %s seconds.",
+ MAX_WAIT_TIME_WFC_ENABLED)
+ return False
+ return True
+
+
+def phone_idle_not_iwlan(log, ad):
+ """Return if phone is idle for non WiFi calling call test.
+
+ Args:
+ ad: Android device object.
+ """
+ return phone_idle_not_iwlan_for_subscription(log, ad,
+ get_outgoing_voice_sub_id(ad))
+
+
+def phone_idle_not_iwlan_for_subscription(log, ad, sub_id):
+ """Return if phone is idle for non WiFi calling call test for sub id.
+
+ Args:
+ ad: Android device object.
+ sub_id: subscription id.
+ """
+ if not wait_for_not_network_rat_for_subscription(
+ log, ad, sub_id, RAT_FAMILY_WLAN,
+ voice_or_data=NETWORK_SERVICE_DATA):
+ log.error("{} data rat in iwlan mode.".format(ad.serial))
+ return False
+ return True
+
+
+def phone_idle_csfb(log, ad):
+ """Return if phone is idle for CSFB call test.
+
+ Args:
+ ad: Android device object.
+ """
+ return phone_idle_csfb_for_subscription(log, ad,
+ get_outgoing_voice_sub_id(ad))
+
+
+def phone_idle_csfb_for_subscription(log, ad, sub_id, nw_gen=GEN_4G, nr_type=None):
+ """Return if phone is idle for CSFB call test for subscription id.
+
+ Args:
+ ad: Android device object.
+ sub_id: subscription id.
+ nw_gen: GEN_4G or GEN_5G
+ """
+ if nw_gen == GEN_5G:
+ if not is_current_network_5g(ad, sub_id=sub_id, nr_type=nr_type):
+ ad.log.error("Not in 5G coverage.")
+ return False
+ else:
+ if not wait_for_network_rat_for_subscription(
+ log, ad, sub_id, RAT_FAMILY_LTE,
+ voice_or_data=NETWORK_SERVICE_DATA):
+ ad.log.error("Data rat not in lte mode.")
+ return False
+ return True
+
+
+def phone_idle_3g(log, ad):
+ """Return if phone is idle for 3G call test.
+
+ Args:
+ ad: Android device object.
+ """
+ return phone_idle_3g_for_subscription(log, ad,
+ get_outgoing_voice_sub_id(ad))
+
+
+def phone_idle_3g_for_subscription(log, ad, sub_id):
+ """Return if phone is idle for 3G call test for subscription id.
+
+ Args:
+ ad: Android device object.
+ sub_id: subscription id.
+ """
+ return wait_for_network_generation_for_subscription(
+ log, ad, sub_id, GEN_3G, voice_or_data=NETWORK_SERVICE_VOICE)
+
+
+def phone_idle_2g(log, ad):
+ """Return if phone is idle for 2G call test.
+
+ Args:
+ ad: Android device object.
+ """
+ return phone_idle_2g_for_subscription(log, ad,
+ get_outgoing_voice_sub_id(ad))
+
+
+def phone_idle_2g_for_subscription(log, ad, sub_id):
+ """Return if phone is idle for 2G call test for subscription id.
+
+ Args:
+ ad: Android device object.
+ sub_id: subscription id.
+ """
+ return wait_for_network_generation_for_subscription(
+ log, ad, sub_id, GEN_2G, voice_or_data=NETWORK_SERVICE_VOICE)
+
+
+def phone_setup_on_rat(
+ log,
+ ad,
+ rat='volte',
+ sub_id=None,
+ is_airplane_mode=False,
+ wfc_mode=None,
+ wifi_ssid=None,
+ wifi_pwd=None,
+ only_return_fn=None,
+ sub_id_type='voice',
+ nr_type='nsa'):
+
+ if sub_id is None:
+ if sub_id_type == 'sms':
+ sub_id = get_outgoing_message_sub_id(ad)
+ else:
+ sub_id = get_outgoing_voice_sub_id(ad)
+
+ if get_default_data_sub_id(ad) != sub_id and '5g' in rat.lower():
+ ad.log.warning('Default data sub ID is NOT given sub ID %s.', sub_id)
+ network_preference = network_preference_for_generation(
+ GEN_5G,
+ ad.telephony["subscription"][sub_id]["operator"],
+ ad.telephony["subscription"][sub_id]["phone_type"])
+
+ ad.log.info("Network preference for %s is %s", GEN_5G,
+ network_preference)
+
+ if not set_preferred_network_mode_pref(log, ad, sub_id,
+ network_preference):
+ return False
+
+ if not wait_for_network_generation_for_subscription(
+ log,
+ ad,
+ sub_id,
+ GEN_5G,
+ max_wait_time=30,
+ voice_or_data=NETWORK_SERVICE_DATA,
+ nr_type=nr_type):
+
+ ad.log.warning('Non-DDS slot (sub ID: %s) cannot attach 5G network.', sub_id)
+ ad.log.info('Check if sub ID %s can attach LTE network.', sub_id)
+
+ if not wait_for_network_generation_for_subscription(
+ log,
+ ad,
+ sub_id,
+ GEN_4G,
+ voice_or_data=NETWORK_SERVICE_DATA):
+ return False
+
+ if "volte" in rat.lower():
+ phone_setup_volte_for_subscription(log, ad, sub_id, None)
+ elif "wfc" in rat.lower():
+ return phone_setup_iwlan_for_subscription(
+ log,
+ ad,
+ sub_id,
+ is_airplane_mode,
+ wfc_mode,
+ wifi_ssid,
+ wifi_pwd)
+ elif "csfb" in rat.lower():
+ return phone_setup_csfb_for_subscription(log, ad, sub_id, None)
+ return True
+
+ if rat.lower() == '5g_volte':
+ if only_return_fn:
+ return phone_setup_volte_for_subscription
+ else:
+ return phone_setup_volte_for_subscription(log, ad, sub_id, GEN_5G, nr_type='nsa')
+
+ elif rat.lower() == '5g_nsa_mmw_volte':
+ if only_return_fn:
+ return phone_setup_volte_for_subscription
+ else:
+ return phone_setup_volte_for_subscription(log, ad, sub_id, GEN_5G,
+ nr_type='mmwave')
+
+ elif rat.lower() == '5g_csfb':
+ if only_return_fn:
+ return phone_setup_csfb_for_subscription
+ else:
+ return phone_setup_csfb_for_subscription(log, ad, sub_id, GEN_5G, nr_type='nsa')
+
+ elif rat.lower() == '5g_wfc':
+ if only_return_fn:
+ return phone_setup_iwlan_for_subscription
+ else:
+ return phone_setup_iwlan_for_subscription(
+ log,
+ ad,
+ sub_id,
+ is_airplane_mode,
+ wfc_mode,
+ wifi_ssid,
+ wifi_pwd,
+ GEN_5G,
+ nr_type='nsa')
+
+ elif rat.lower() == '5g_nsa_mmw_wfc':
+ if only_return_fn:
+ return phone_setup_iwlan_for_subscription
+ else:
+ return phone_setup_iwlan_for_subscription(
+ log,
+ ad,
+ sub_id,
+ is_airplane_mode,
+ wfc_mode,
+ wifi_ssid,
+ wifi_pwd,
+ GEN_5G,
+ nr_type='mmwave')
+
+ elif rat.lower() == 'volte':
+ if only_return_fn:
+ return phone_setup_volte_for_subscription
+ else:
+ return phone_setup_volte_for_subscription(log, ad, sub_id)
+
+ elif rat.lower() == 'csfb':
+ if only_return_fn:
+ return phone_setup_csfb_for_subscription
+ else:
+ return phone_setup_csfb_for_subscription(log, ad, sub_id)
+
+ elif rat.lower() == '5g':
+ if only_return_fn:
+ return phone_setup_5g_for_subscription
+ else:
+ return phone_setup_5g_for_subscription(log, ad, sub_id, nr_type='nsa')
+
+ elif rat.lower() == '5g_nsa_mmwave':
+ if only_return_fn:
+ return phone_setup_5g_for_subscription
+ else:
+ return phone_setup_5g_for_subscription(log, ad, sub_id,
+ nr_type='mmwave')
+
+ elif rat.lower() == '3g':
+ if only_return_fn:
+ return phone_setup_voice_3g_for_subscription
+ else:
+ return phone_setup_voice_3g_for_subscription(log, ad, sub_id)
+
+ elif rat.lower() == '2g':
+ if only_return_fn:
+ return phone_setup_voice_2g_for_subscription
+ else:
+ return phone_setup_voice_2g_for_subscription(log, ad, sub_id)
+
+ elif rat.lower() == 'wfc':
+ if only_return_fn:
+ return phone_setup_iwlan_for_subscription
+ else:
+ return phone_setup_iwlan_for_subscription(
+ log,
+ ad,
+ sub_id,
+ is_airplane_mode,
+ wfc_mode,
+ wifi_ssid,
+ wifi_pwd)
+ elif rat.lower() == 'default':
+ if only_return_fn:
+ return ensure_phone_default_state
+ else:
+ return ensure_phone_default_state(log, ad)
+ else:
+ if only_return_fn:
+ return phone_setup_voice_general_for_subscription
+ else:
+ return phone_setup_voice_general_for_subscription(log, ad, sub_id)
+
+
+def wait_for_network_idle(
+ log,
+ ad,
+ rat,
+ sub_id,
+ nr_type='nsa'):
+ """Wait for attaching to network with assigned RAT and IMS/WFC registration
+
+ This function can be used right after network service recovery after turning
+ off airplane mode or switching DDS. It will ensure DUT has attached to the
+ network with assigned RAT, and VoLTE/WFC has been ready.
+
+ Args:
+ log: log object
+ ad: Android object
+ rat: following RAT are supported:
+ - 5g
+ - 5g_volte
+ - 5g_csfb
+ - 5g_wfc
+ - 4g (LTE)
+ - volte (LTE)
+ - csfb (LTE)
+ - wfc (LTE)
+
+ Returns:
+ True or False
+ """
+ if get_default_data_sub_id(ad) != sub_id and '5g' in rat.lower():
+ ad.log.warning('Default data sub ID is NOT given sub ID %s.', sub_id)
+ network_preference = network_preference_for_generation(
+ GEN_5G,
+ ad.telephony["subscription"][sub_id]["operator"],
+ ad.telephony["subscription"][sub_id]["phone_type"])
+
+ ad.log.info("Network preference for %s is %s", GEN_5G,
+ network_preference)
+
+ if not set_preferred_network_mode_pref(log, ad, sub_id,
+ network_preference):
+ return False
+
+ if not wait_for_network_generation_for_subscription(
+ log,
+ ad,
+ sub_id,
+ GEN_5G,
+ max_wait_time=30,
+ voice_or_data=NETWORK_SERVICE_DATA,
+ nr_type=nr_type):
+
+ ad.log.warning('Non-DDS slot (sub ID: %s) cannot attach 5G network.', sub_id)
+ ad.log.info('Check if sub ID %s can attach LTE network.', sub_id)
+
+ if not wait_for_network_generation_for_subscription(
+ log,
+ ad,
+ sub_id,
+ GEN_4G,
+ voice_or_data=NETWORK_SERVICE_DATA):
+ return False
+
+ if rat.lower() == '5g':
+ rat = '4g'
+ elif rat.lower() == '5g_volte':
+ rat = 'volte'
+ elif rat.lower() == '5g_wfc':
+ rat = 'wfc'
+ elif rat.lower() == '5g_csfb':
+ rat = 'csfb'
+
+ if rat.lower() == '5g_volte':
+ if not phone_idle_volte_for_subscription(log, ad, sub_id, GEN_5G, nr_type=nr_type):
+ return False
+ elif rat.lower() == '5g_csfb':
+ if not phone_idle_csfb_for_subscription(log, ad, sub_id, GEN_5G, nr_type=nr_type):
+ return False
+ elif rat.lower() == '5g_wfc':
+ if not wait_for_network_generation_for_subscription(
+ log,
+ ad,
+ sub_id,
+ GEN_5G,
+ voice_or_data=NETWORK_SERVICE_DATA,
+ nr_type=nr_type):
+ return False
+ if not wait_for_wfc_enabled(log, ad):
+ return False
+ elif rat.lower() == '5g':
+ if not wait_for_network_generation_for_subscription(
+ log,
+ ad,
+ sub_id,
+ GEN_5G,
+ voice_or_data=NETWORK_SERVICE_DATA,
+ nr_type=nr_type):
+ return False
+ elif rat.lower() == 'volte':
+ if not phone_idle_volte_for_subscription(log, ad, sub_id, GEN_4G):
+ return False
+ elif rat.lower() == 'csfb':
+ if not phone_idle_csfb_for_subscription(log, ad, sub_id, GEN_4G):
+ return False
+ elif rat.lower() == 'wfc':
+ if not wait_for_network_generation_for_subscription(
+ log,
+ ad,
+ sub_id,
+ GEN_4G,
+ voice_or_data=NETWORK_SERVICE_DATA):
+ return False
+ if not wait_for_wfc_enabled(log, ad):
+ return False
+ elif rat.lower() == '4g':
+ if not wait_for_network_generation_for_subscription(
+ log,
+ ad,
+ sub_id,
+ GEN_4G,
+ voice_or_data=NETWORK_SERVICE_DATA):
+ return False
+ return True
+
+
+def ensure_preferred_network_type_for_subscription(
+ ad,
+ network_preference
+ ):
+ sub_id = ad.droid.subscriptionGetDefaultSubId()
+ if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
+ network_preference, sub_id):
+ ad.log.error("Set sub_id %s Preferred Networks Type %s failed.",
+ sub_id, network_preference)
+ return True
+
+
+def ensure_network_rat(log,
+ ad,
+ network_preference,
+ rat_family,
+ voice_or_data=None,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ toggle_apm_after_setting=False):
+ """Ensure ad's current network is in expected rat_family.
+ """
+ return ensure_network_rat_for_subscription(
+ log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
+ rat_family, voice_or_data, max_wait_time, toggle_apm_after_setting)
+
+
+def ensure_network_rat_for_subscription(
+ log,
+ ad,
+ sub_id,
+ network_preference,
+ rat_family,
+ voice_or_data=None,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ toggle_apm_after_setting=False):
+ """Ensure ad's current network is in expected rat_family.
+ """
+ if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
+ network_preference, sub_id):
+ ad.log.error("Set sub_id %s Preferred Networks Type %s failed.",
+ sub_id, network_preference)
+ return False
+ if is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family,
+ voice_or_data):
+ ad.log.info("Sub_id %s in RAT %s for %s", sub_id, rat_family,
+ voice_or_data)
+ return True
+
+ if toggle_apm_after_setting:
+ toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+ toggle_airplane_mode(log, ad, new_state=None, strict_checking=False)
+
+ result = wait_for_network_rat_for_subscription(
+ log, ad, sub_id, rat_family, max_wait_time, voice_or_data)
+
+ log.info(
+ "End of ensure_network_rat_for_subscription for %s. "
+ "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
+ "data: %s(family: %s)", ad.serial, network_preference, rat_family,
+ voice_or_data,
+ ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
+ rat_family_from_rat(
+ ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
+ sub_id)),
+ ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
+ rat_family_from_rat(
+ ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
+ sub_id)))
+ return result
+
+
+def ensure_network_preference(log,
+ ad,
+ network_preference,
+ voice_or_data=None,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ toggle_apm_after_setting=False):
+ """Ensure that current rat is within the device's preferred network rats.
+ """
+ return ensure_network_preference_for_subscription(
+ log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
+ voice_or_data, max_wait_time, toggle_apm_after_setting)
+
+
+def ensure_network_preference_for_subscription(
+ log,
+ ad,
+ sub_id,
+ network_preference,
+ voice_or_data=None,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ toggle_apm_after_setting=False):
+ """Ensure ad's network preference is <network_preference> for sub_id.
+ """
+ rat_family_list = rat_families_for_network_preference(network_preference)
+ if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
+ network_preference, sub_id):
+ log.error("Set Preferred Networks failed.")
+ return False
+ if is_droid_in_rat_family_list_for_subscription(
+ log, ad, sub_id, rat_family_list, voice_or_data):
+ return True
+
+ if toggle_apm_after_setting:
+ toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+ toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)
+
+ result = wait_for_preferred_network_for_subscription(
+ log, ad, sub_id, network_preference, max_wait_time, voice_or_data)
+
+ ad.log.info(
+ "End of ensure_network_preference_for_subscription. "
+ "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
+ "data: %s(family: %s)", network_preference, rat_family_list,
+ voice_or_data,
+ ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
+ rat_family_from_rat(
+ ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
+ sub_id)),
+ ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
+ rat_family_from_rat(
+ ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
+ sub_id)))
+ return result
+
+
+def ensure_network_generation(log,
+ ad,
+ generation,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ voice_or_data=None,
+ toggle_apm_after_setting=False,
+ nr_type=None):
+ """Ensure ad's network is <network generation> for default subscription ID.
+
+ Set preferred network generation to <generation>.
+ Toggle ON/OFF airplane mode if necessary.
+ Wait for ad in expected network type.
+ """
+ return ensure_network_generation_for_subscription(
+ log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
+ max_wait_time, voice_or_data, toggle_apm_after_setting, nr_type=nr_type)
+
+
+def ensure_network_generation_for_subscription(
+ log,
+ ad,
+ sub_id,
+ generation,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ voice_or_data=None,
+ toggle_apm_after_setting=False,
+ nr_type=None):
+ """Ensure ad's network is <network generation> for specified subscription ID.
+
+ Set preferred network generation to <generation>.
+ Toggle ON/OFF airplane mode if necessary.
+ Wait for ad in expected network type.
+
+ Args:
+ log: log object.
+ ad: android device object.
+ sub_id: subscription id.
+ generation: network generation, e.g. GEN_2G, GEN_3G, GEN_4G, GEN_5G.
+ max_wait_time: the time to wait for NW selection.
+ voice_or_data: check voice network generation or data network generation
+ This parameter is optional. If voice_or_data is None, then if
+ either voice or data in expected generation, function will return True.
+ toggle_apm_after_setting: Cycle airplane mode if True, otherwise do nothing.
+
+ Returns:
+ True if success, False if fail.
+ """
+ ad.log.info(
+ "RAT network type voice: %s, data: %s",
+ ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
+ ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id))
+
+ try:
+ ad.log.info("Finding the network preference for generation %s for "
+ "operator %s phone type %s", generation,
+ ad.telephony["subscription"][sub_id]["operator"],
+ ad.telephony["subscription"][sub_id]["phone_type"])
+ network_preference = network_preference_for_generation(
+ generation, ad.telephony["subscription"][sub_id]["operator"],
+ ad.telephony["subscription"][sub_id]["phone_type"])
+ if ad.telephony["subscription"][sub_id]["operator"] == CARRIER_FRE \
+ and generation == GEN_4G:
+ network_preference = NETWORK_MODE_LTE_ONLY
+ ad.log.info("Network preference for %s is %s", generation,
+ network_preference)
+ rat_family = rat_family_for_generation(
+ generation, ad.telephony["subscription"][sub_id]["operator"],
+ ad.telephony["subscription"][sub_id]["phone_type"])
+ except KeyError as e:
+ ad.log.error("Failed to find a rat_family entry for generation %s"
+ " for subscriber id %s with error %s", generation,
+ sub_id, e)
+ return False
+
+ if not set_preferred_network_mode_pref(log, ad, sub_id,
+ network_preference):
+ return False
+
+ if hasattr(ad, "dsds") and voice_or_data == "data" and sub_id != get_default_data_sub_id(ad):
+ ad.log.info("MSIM - Non DDS, ignore data RAT")
+ return True
+
+ if (generation == GEN_5G) or (generation == RAT_5G):
+ if is_current_network_5g(ad, sub_id=sub_id, nr_type=nr_type):
+ ad.log.info("Current network type is 5G.")
+ return True
+ else:
+ ad.log.error("Not in 5G coverage for Sub %s.", sub_id)
+ return False
+
+ if is_droid_in_network_generation_for_subscription(
+ log, ad, sub_id, generation, voice_or_data):
+ return True
+
+ if toggle_apm_after_setting:
+ toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+ toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)
+
+ result = wait_for_network_generation_for_subscription(
+ log, ad, sub_id, generation, max_wait_time, voice_or_data)
+
+ ad.log.info(
+ "Ensure network %s %s %s. With network preference %s, "
+ "current: voice: %s(family: %s), data: %s(family: %s)", generation,
+ voice_or_data, result, network_preference,
+ ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
+ rat_generation_from_rat(
+ ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
+ sub_id)),
+ ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
+ rat_generation_from_rat(
+ ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
+ sub_id)))
+ if not result:
+ get_telephony_signal_strength(ad)
+ return result
+
+
+def wait_for_network_rat(log,
+ ad,
+ rat_family,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ voice_or_data=None):
+ return wait_for_network_rat_for_subscription(
+ log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
+ max_wait_time, voice_or_data)
+
+
+def wait_for_network_rat_for_subscription(
+ log,
+ ad,
+ sub_id,
+ rat_family,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ voice_or_data=None):
+ return _wait_for_droid_in_state_for_subscription(
+ log, ad, sub_id, max_wait_time,
+ is_droid_in_rat_family_for_subscription, rat_family, voice_or_data)
+
+
+def wait_for_not_network_rat(log,
+ ad,
+ rat_family,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ voice_or_data=None):
+ return wait_for_not_network_rat_for_subscription(
+ log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
+ max_wait_time, voice_or_data)
+
+
+def wait_for_not_network_rat_for_subscription(
+ log,
+ ad,
+ sub_id,
+ rat_family,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ voice_or_data=None):
+ return _wait_for_droid_in_state_for_subscription(
+ log, ad, sub_id, max_wait_time,
+ lambda log, ad, sub_id, *args, **kwargs: not is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family, voice_or_data)
+ )
+
+
+def wait_for_preferred_network(log,
+ ad,
+ network_preference,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ voice_or_data=None):
+ return wait_for_preferred_network_for_subscription(
+ log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
+ max_wait_time, voice_or_data)
+
+
+def wait_for_preferred_network_for_subscription(
+ log,
+ ad,
+ sub_id,
+ network_preference,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ voice_or_data=None):
+ rat_family_list = rat_families_for_network_preference(network_preference)
+ return _wait_for_droid_in_state_for_subscription(
+ log, ad, sub_id, max_wait_time,
+ is_droid_in_rat_family_list_for_subscription, rat_family_list,
+ voice_or_data)
+
+
+def wait_for_network_generation(log,
+ ad,
+ generation,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ voice_or_data=None):
+ return wait_for_network_generation_for_subscription(
+ log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
+ max_wait_time, voice_or_data)
+
+
+def wait_for_network_generation_for_subscription(
+ log,
+ ad,
+ sub_id,
+ generation,
+ max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
+ voice_or_data=None,
+ nr_type=None):
+
+ if generation == GEN_5G:
+ if is_current_network_5g(ad, sub_id=sub_id, nr_type=nr_type):
+ ad.log.info("Current network type is 5G.")
+ return True
+ else:
+ ad.log.error("Not in 5G coverage for Sub %s.", sub_id)
+ return False
+
+ return _wait_for_droid_in_state_for_subscription(
+ log, ad, sub_id, max_wait_time,
+ is_droid_in_network_generation_for_subscription, generation,
+ voice_or_data)
+
+
+def ensure_phones_idle(log, ads, max_time=MAX_WAIT_TIME_CALL_DROP):
+ """Ensure ads idle (not in call).
+ """
+ result = True
+ for ad in ads:
+ if not ensure_phone_idle(log, ad, max_time=max_time):
+ result = False
+ return result
+
+
+def ensure_phone_idle(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP, retry=2):
+ """Ensure ad idle (not in call).
+ """
+ while ad.droid.telecomIsInCall() and retry > 0:
+ ad.droid.telecomEndCall()
+ time.sleep(3)
+ retry -= 1
+ if not wait_for_droid_not_in_call(log, ad, max_time=max_time):
+ ad.log.error("Failed to end call")
+ return False
+ return True
+
+
+def ensure_phone_subscription(log, ad):
+ """Ensure Phone Subscription.
+ """
+ #check for sim and service
+ duration = 0
+ while duration < MAX_WAIT_TIME_NW_SELECTION:
+ subInfo = ad.droid.subscriptionGetAllSubInfoList()
+ if subInfo and len(subInfo) >= 1:
+ ad.log.debug("Find valid subcription %s", subInfo)
+ break
+ else:
+ ad.log.info("Did not find any subscription")
+ time.sleep(5)
+ duration += 5
+ else:
+ ad.log.error("Unable to find a valid subscription!")
+ return False
+ while duration < MAX_WAIT_TIME_NW_SELECTION:
+ data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
+ voice_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
+ if data_sub_id > INVALID_SUB_ID or voice_sub_id > INVALID_SUB_ID:
+ ad.log.debug("Find valid voice or data sub id")
+ break
+ else:
+ ad.log.info("Did not find valid data or voice sub id")
+ time.sleep(5)
+ duration += 5
+ else:
+ ad.log.error("Unable to find valid data or voice sub id")
+ return False
+ while duration < MAX_WAIT_TIME_NW_SELECTION:
+ data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
+ if data_sub_id > INVALID_SUB_ID:
+ data_rat = get_network_rat_for_subscription(
+ log, ad, data_sub_id, NETWORK_SERVICE_DATA)
+ else:
+ data_rat = RAT_UNKNOWN
+ if voice_sub_id > INVALID_SUB_ID:
+ voice_rat = get_network_rat_for_subscription(
+ log, ad, voice_sub_id, NETWORK_SERVICE_VOICE)
+ else:
+ voice_rat = RAT_UNKNOWN
+ if data_rat != RAT_UNKNOWN or voice_rat != RAT_UNKNOWN:
+ ad.log.info("Data sub_id %s in %s, voice sub_id %s in %s",
+ data_sub_id, data_rat, voice_sub_id, voice_rat)
+ return True
+ else:
+ ad.log.info("Did not attach for data or voice service")
+ time.sleep(5)
+ duration += 5
+ else:
+ ad.log.error("Did not attach for voice or data service")
+ return False
+
+
+def ensure_phone_default_state(log, ad, check_subscription=True, retry=2):
+ """Ensure ad in default state.
+ Phone not in call.
+ Phone have no stored WiFi network and WiFi disconnected.
+ Phone not in airplane mode.
+ """
+ result = True
+ if not toggle_airplane_mode(log, ad, False, False):
+ ad.log.error("Fail to turn off airplane mode")
+ result = False
+ try:
+ set_wifi_to_default(log, ad)
+ while ad.droid.telecomIsInCall() and retry > 0:
+ ad.droid.telecomEndCall()
+ time.sleep(3)
+ retry -= 1
+ if not wait_for_droid_not_in_call(log, ad):
+ ad.log.error("Failed to end call")
+ #ad.droid.telephonyFactoryReset()
+ data_roaming = getattr(ad, 'roaming', False)
+ if get_cell_data_roaming_state_by_adb(ad) != data_roaming:
+ set_cell_data_roaming_state_by_adb(ad, data_roaming)
+ #remove_mobile_data_usage_limit(ad)
+ if not wait_for_not_network_rat(
+ log, ad, RAT_FAMILY_WLAN, voice_or_data=NETWORK_SERVICE_DATA):
+ ad.log.error("%s still in %s", NETWORK_SERVICE_DATA,
+ RAT_FAMILY_WLAN)
+ result = False
+
+ if check_subscription and not ensure_phone_subscription(log, ad):
+ ad.log.error("Unable to find a valid subscription!")
+ result = False
+ except Exception as e:
+ ad.log.error("%s failure, toggle APM instead", e)
+ toggle_airplane_mode_by_adb(log, ad, True)
+ toggle_airplane_mode_by_adb(log, ad, False)
+ ad.send_keycode("ENDCALL")
+ ad.adb.shell("settings put global wfc_ims_enabled 0")
+ ad.adb.shell("settings put global mobile_data 1")
+
+ return result
+
+
+def ensure_phones_default_state(log, ads, check_subscription=True):
+ """Ensure ads in default state.
+ Phone not in call.
+ Phone have no stored WiFi network and WiFi disconnected.
+ Phone not in airplane mode.
+
+ Returns:
+ True if all steps of restoring default state succeed.
+ False if any of the steps to restore default state fails.
+ """
+ tasks = []
+ for ad in ads:
+ tasks.append((ensure_phone_default_state, (log, ad,
+ check_subscription)))
+ if not multithread_func(log, tasks):
+ log.error("Ensure_phones_default_state Fail.")
+ return False
+ return True
+
+
+def is_phone_not_in_call(log, ad):
+ """Return True if phone not in call.
+
+ Args:
+ log: log object.
+ ad: android device.
+ """
+ in_call = ad.droid.telecomIsInCall()
+ call_state = ad.droid.telephonyGetCallState()
+ if in_call:
+ ad.log.info("Device is In Call")
+ if call_state != TELEPHONY_STATE_IDLE:
+ ad.log.info("Call_state is %s, not %s", call_state,
+ TELEPHONY_STATE_IDLE)
+ return ((not in_call) and (call_state == TELEPHONY_STATE_IDLE))
+
+
+def wait_for_droid_not_in_call(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP):
+ """Wait for android to be not in call state.
+
+ Args:
+ log: log object.
+ ad: android device.
+ max_time: maximal wait time.
+
+ Returns:
+ If phone become not in call state within max_time, return True.
+ Return False if timeout.
+ """
+ return _wait_for_droid_in_state(log, ad, max_time, is_phone_not_in_call)
+
+
+def wait_for_voice_attach(log, ad, max_time=MAX_WAIT_TIME_NW_SELECTION):
+ """Wait for android device to attach on voice.
+
+ Args:
+ log: log object.
+ ad: android device.
+ max_time: maximal wait time.
+
+ Returns:
+ Return True if device attach voice within max_time.
+ Return False if timeout.
+ """
+ return _wait_for_droid_in_state(log, ad, max_time, _is_attached,
+ NETWORK_SERVICE_VOICE)
+
+
+def wait_for_voice_attach_for_subscription(
+ log, ad, sub_id, max_time=MAX_WAIT_TIME_NW_SELECTION):
+ """Wait for android device to attach on voice in subscription id.
+
+ Args:
+ log: log object.
+ ad: android device.
+ sub_id: subscription id.
+ max_time: maximal wait time.
+
+ Returns:
+ Return True if device attach voice within max_time.
+ Return False if timeout.
+ """
+ if not _wait_for_droid_in_state_for_subscription(
+ log, ad, sub_id, max_time, _is_attached_for_subscription,
+ NETWORK_SERVICE_VOICE):
+ return False
+
+ # TODO: b/26295983 if pone attach to 1xrtt from unknown, phone may not
+ # receive incoming call immediately.
+ if ad.droid.telephonyGetCurrentVoiceNetworkType() == RAT_1XRTT:
+ time.sleep(WAIT_TIME_1XRTT_VOICE_ATTACH)
+ return True
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_sms_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_sms_utils.py
index dc68671..891e6b1 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_sms_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_sms_utils.py
@@ -17,14 +17,14 @@
import time
from acts.utils import rand_ascii_str
-from acts_contrib.test_utils.tel.tel_test_utils import sms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
-
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
message_lengths = (50, 160, 180)
+
def _sms_test(log, ads):
"""Test SMS between two phones.
Returns:
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_ss_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_ss_utils.py
new file mode 100644
index 0000000..dafd078
--- /dev/null
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_ss_utils.py
@@ -0,0 +1,1701 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - Google
+#
+# 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 signals
+import re
+import time
+
+from acts.utils import get_current_epoch_time
+from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED
+from acts_contrib.test_utils.tel.tel_defines import NOT_CHECK_MCALLFORWARDING_OPERATOR_LIST
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_REG_AND_CALL
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_enabled
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_subid
+from acts_contrib.test_utils.tel.tel_test_utils import _phone_number_remove_prefix
+from acts_contrib.test_utils.tel.tel_test_utils import check_call_state_ring_by_adb
+from acts_contrib.test_utils.tel.tel_test_utils import check_call_state_idle_by_adb
+from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
+from acts_contrib.test_utils.tel.tel_test_utils import get_user_config_profile
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_msim
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown_for_subscription
+from acts_contrib.test_utils.tel.tel_voice_utils import dial_phone_number
+from acts_contrib.test_utils.tel.tel_voice_utils import disconnect_call_by_id
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call
+from acts_contrib.test_utils.tel.tel_voice_utils import last_call_drop_reason
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call_for_subscription
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_call_id_clearing
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_call_offhook_for_subscription
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_in_call_active
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_ringing_call_for_subscription
+
+
+def call_setup_teardown_for_call_forwarding(
+ log,
+ ad_caller,
+ ad_callee,
+ forwarded_callee,
+ ad_hangup=None,
+ verify_callee_func=None,
+ verify_after_cf_disabled=None,
+ wait_time_in_call=WAIT_TIME_IN_CALL,
+ incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
+ dialing_number_length=None,
+ video_state=None,
+ call_forwarding_type="unconditional"):
+ """ Call process for call forwarding, including make a phone call from
+ caller, forward from callee, accept from the forwarded callee and hang up.
+ The call is on default voice subscription
+
+ In call process, call from <ad_caller> to <ad_callee>, forwarded to
+ <forwarded_callee>, accept the call, (optional) and then hang up from
+ <ad_hangup>.
+
+ Args:
+ ad_caller: Caller Android Device Object.
+ ad_callee: Callee Android Device Object which forwards the call.
+ forwarded_callee: Callee Android Device Object which answers the call.
+ ad_hangup: Android Device Object end the phone call.
+ Optional. Default value is None, and phone call will continue.
+ verify_callee_func: func_ptr to verify callee in correct mode
+ Optional. Default is None
+ verify_after_cf_disabled: If True the test of disabling call forwarding
+ will be appended.
+ wait_time_in_call: the call duration of a connected call
+ incall_ui_display: after answer the call, bring in-call UI to foreground
+ or background.
+ Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
+ if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
+ if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
+ else, do nothing.
+ dialing_number_length: the number of digits used for dialing
+ video_state: video call or voice call. Default is voice call.
+ call_forwarding_type: type of call forwarding listed below:
+ - unconditional
+ - busy
+ - not_answered
+ - not_reachable
+
+ Returns:
+ True if call process without any error.
+ False if error happened.
+
+ """
+ subid_caller = get_outgoing_voice_sub_id(ad_caller)
+ subid_callee = get_incoming_voice_sub_id(ad_callee)
+ subid_forwarded_callee = get_incoming_voice_sub_id(forwarded_callee)
+ return call_setup_teardown_for_call_forwarding_for_subscription(
+ log,
+ ad_caller,
+ ad_callee,
+ forwarded_callee,
+ subid_caller,
+ subid_callee,
+ subid_forwarded_callee,
+ ad_hangup,
+ verify_callee_func,
+ wait_time_in_call,
+ incall_ui_display,
+ dialing_number_length,
+ video_state,
+ call_forwarding_type,
+ verify_after_cf_disabled)
+
+
+def call_setup_teardown_for_call_forwarding_for_subscription(
+ log,
+ ad_caller,
+ ad_callee,
+ forwarded_callee,
+ subid_caller,
+ subid_callee,
+ subid_forwarded_callee,
+ ad_hangup=None,
+ verify_callee_func=None,
+ wait_time_in_call=WAIT_TIME_IN_CALL,
+ incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
+ dialing_number_length=None,
+ video_state=None,
+ call_forwarding_type="unconditional",
+ verify_after_cf_disabled=None):
+ """ Call process for call forwarding, including make a phone call from caller,
+ forward from callee, accept from the forwarded callee and hang up.
+ The call is on specified subscription
+
+ In call process, call from <ad_caller> to <ad_callee>, forwarded to
+ <forwarded_callee>, accept the call, (optional) and then hang up from
+ <ad_hangup>.
+
+ Args:
+ ad_caller: Caller Android Device Object.
+ ad_callee: Callee Android Device Object which forwards the call.
+ forwarded_callee: Callee Android Device Object which answers the call.
+ subid_caller: Caller subscription ID
+ subid_callee: Callee subscription ID
+ subid_forwarded_callee: Forwarded callee subscription ID
+ ad_hangup: Android Device Object end the phone call.
+ Optional. Default value is None, and phone call will continue.
+ verify_callee_func: func_ptr to verify callee in correct mode
+ Optional. Default is None
+ wait_time_in_call: the call duration of a connected call
+ incall_ui_display: after answer the call, bring in-call UI to foreground
+ or background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
+ if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
+ if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
+ else, do nothing.
+ dialing_number_length: the number of digits used for dialing
+ video_state: video call or voice call. Default is voice call.
+ call_forwarding_type: type of call forwarding listed below:
+ - unconditional
+ - busy
+ - not_answered
+ - not_reachable
+ verify_after_cf_disabled: If True the call forwarding will not be
+ enabled. This argument is used to verify if the call can be received
+ successfully after call forwarding was disabled.
+
+ Returns:
+ True if call process without any error.
+ False if error happened.
+
+ """
+ CHECK_INTERVAL = 5
+ begin_time = get_current_epoch_time()
+ verify_caller_func = is_phone_in_call
+ if not verify_callee_func:
+ verify_callee_func = is_phone_in_call
+ verify_forwarded_callee_func = is_phone_in_call
+
+ caller_number = ad_caller.telephony['subscription'][subid_caller][
+ 'phone_num']
+ callee_number = ad_callee.telephony['subscription'][subid_callee][
+ 'phone_num']
+ forwarded_callee_number = forwarded_callee.telephony['subscription'][
+ subid_forwarded_callee]['phone_num']
+
+ if dialing_number_length:
+ skip_test = False
+ trunc_position = 0 - int(dialing_number_length)
+ try:
+ caller_area_code = caller_number[:trunc_position]
+ callee_area_code = callee_number[:trunc_position]
+ callee_dial_number = callee_number[trunc_position:]
+ except:
+ skip_test = True
+ if caller_area_code != callee_area_code:
+ skip_test = True
+ if skip_test:
+ msg = "Cannot make call from %s to %s by %s digits" % (
+ caller_number, callee_number, dialing_number_length)
+ ad_caller.log.info(msg)
+ raise signals.TestSkip(msg)
+ else:
+ callee_number = callee_dial_number
+
+ result = True
+ msg = "Call from %s to %s (forwarded to %s)" % (
+ caller_number, callee_number, forwarded_callee_number)
+ if video_state:
+ msg = "Video %s" % msg
+ video = True
+ else:
+ video = False
+ if ad_hangup:
+ msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
+ ad_caller.log.info(msg)
+
+ for ad in (ad_caller, forwarded_callee):
+ call_ids = ad.droid.telecomCallGetCallIds()
+ setattr(ad, "call_ids", call_ids)
+ if call_ids:
+ ad.log.info("Pre-exist CallId %s before making call", call_ids)
+
+ if not verify_after_cf_disabled:
+ if not set_call_forwarding_by_mmi(
+ log,
+ ad_callee,
+ forwarded_callee,
+ call_forwarding_type=call_forwarding_type):
+ raise signals.TestFailure(
+ "Failed to register or activate call forwarding.",
+ extras={"fail_reason": "Failed to register or activate call"
+ " forwarding."})
+
+ if call_forwarding_type == "not_reachable":
+ if not toggle_airplane_mode_msim(
+ log,
+ ad_callee,
+ new_state=True,
+ strict_checking=True):
+ return False
+
+ if call_forwarding_type == "busy":
+ ad_callee.log.info("Callee is making a phone call to 0000000000 to make"
+ " itself busy.")
+ ad_callee.droid.telecomCallNumber("0000000000", False)
+ time.sleep(2)
+
+ if check_call_state_idle_by_adb(ad_callee):
+ ad_callee.log.error("Call state of the callee is idle.")
+ if not verify_after_cf_disabled:
+ erase_call_forwarding_by_mmi(
+ log,
+ ad_callee,
+ call_forwarding_type=call_forwarding_type)
+ return False
+
+ try:
+ if not initiate_call(
+ log,
+ ad_caller,
+ callee_number,
+ incall_ui_display=incall_ui_display,
+ video=video):
+
+ ad_caller.log.error("Caller failed to initiate the call.")
+ result = False
+
+ if call_forwarding_type == "not_reachable":
+ if toggle_airplane_mode_msim(
+ log,
+ ad_callee,
+ new_state=False,
+ strict_checking=True):
+ time.sleep(10)
+ elif call_forwarding_type == "busy":
+ hangup_call(log, ad_callee)
+
+ if not verify_after_cf_disabled:
+ erase_call_forwarding_by_mmi(
+ log,
+ ad_callee,
+ call_forwarding_type=call_forwarding_type)
+ return False
+ else:
+ ad_caller.log.info("Caller initated the call successfully.")
+
+ if call_forwarding_type == "not_answered":
+ if not wait_for_ringing_call_for_subscription(
+ log,
+ ad_callee,
+ subid_callee,
+ incoming_number=caller_number,
+ caller=ad_caller,
+ event_tracking_started=True):
+ ad.log.info("Incoming call ringing check failed.")
+ return False
+
+ _timeout = 30
+ while check_call_state_ring_by_adb(ad_callee) == 1 and _timeout >= 0:
+ time.sleep(1)
+ _timeout = _timeout - 1
+
+ if not wait_and_answer_call_for_subscription(
+ log,
+ forwarded_callee,
+ subid_forwarded_callee,
+ incoming_number=caller_number,
+ caller=ad_caller,
+ incall_ui_display=incall_ui_display,
+ video_state=video_state):
+
+ if not verify_after_cf_disabled:
+ forwarded_callee.log.error("Forwarded callee failed to receive"
+ "or answer the call.")
+ result = False
+ else:
+ forwarded_callee.log.info("Forwarded callee did not receive or"
+ " answer the call.")
+
+ if call_forwarding_type == "not_reachable":
+ if toggle_airplane_mode_msim(
+ log,
+ ad_callee,
+ new_state=False,
+ strict_checking=True):
+ time.sleep(10)
+ elif call_forwarding_type == "busy":
+ hangup_call(log, ad_callee)
+
+ if not verify_after_cf_disabled:
+ erase_call_forwarding_by_mmi(
+ log,
+ ad_callee,
+ call_forwarding_type=call_forwarding_type)
+ return False
+
+ else:
+ if not verify_after_cf_disabled:
+ forwarded_callee.log.info("Forwarded callee answered the call"
+ " successfully.")
+ else:
+ forwarded_callee.log.error("Forwarded callee should not be able"
+ " to answer the call.")
+ hangup_call(log, ad_caller)
+ result = False
+
+ for ad, subid, call_func in zip(
+ [ad_caller, forwarded_callee],
+ [subid_caller, subid_forwarded_callee],
+ [verify_caller_func, verify_forwarded_callee_func]):
+ call_ids = ad.droid.telecomCallGetCallIds()
+ new_call_ids = set(call_ids) - set(ad.call_ids)
+ if not new_call_ids:
+ if not verify_after_cf_disabled:
+ ad.log.error(
+ "No new call ids are found after call establishment")
+ ad.log.error("telecomCallGetCallIds returns %s",
+ ad.droid.telecomCallGetCallIds())
+ result = False
+ for new_call_id in new_call_ids:
+ if not verify_after_cf_disabled:
+ if not wait_for_in_call_active(ad, call_id=new_call_id):
+ result = False
+ else:
+ ad.log.info("callProperties = %s",
+ ad.droid.telecomCallGetProperties(new_call_id))
+ else:
+ ad.log.error("No new call id should be found.")
+
+ if not ad.droid.telecomCallGetAudioState():
+ if not verify_after_cf_disabled:
+ ad.log.error("Audio is not in call state")
+ result = False
+
+ if call_func(log, ad):
+ if not verify_after_cf_disabled:
+ ad.log.info("Call is in %s state", call_func.__name__)
+ else:
+ ad.log.error("Call is in %s state", call_func.__name__)
+ else:
+ if not verify_after_cf_disabled:
+ ad.log.error(
+ "Call is not in %s state, voice in RAT %s",
+ call_func.__name__,
+ ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
+ result = False
+
+ if not result:
+ if call_forwarding_type == "not_reachable":
+ if toggle_airplane_mode_msim(
+ log,
+ ad_callee,
+ new_state=False,
+ strict_checking=True):
+ time.sleep(10)
+ elif call_forwarding_type == "busy":
+ hangup_call(log, ad_callee)
+
+ if not verify_after_cf_disabled:
+ erase_call_forwarding_by_mmi(
+ log,
+ ad_callee,
+ call_forwarding_type=call_forwarding_type)
+ return False
+
+ elapsed_time = 0
+ while (elapsed_time < wait_time_in_call):
+ CHECK_INTERVAL = min(CHECK_INTERVAL,
+ wait_time_in_call - elapsed_time)
+ time.sleep(CHECK_INTERVAL)
+ elapsed_time += CHECK_INTERVAL
+ time_message = "at <%s>/<%s> second." % (elapsed_time,
+ wait_time_in_call)
+ for ad, subid, call_func in [
+ (ad_caller, subid_caller, verify_caller_func),
+ (forwarded_callee, subid_forwarded_callee,
+ verify_forwarded_callee_func)]:
+ if not call_func(log, ad):
+ if not verify_after_cf_disabled:
+ ad.log.error(
+ "NOT in correct %s state at %s, voice in RAT %s",
+ call_func.__name__, time_message,
+ ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
+ result = False
+ else:
+ if not verify_after_cf_disabled:
+ ad.log.info("In correct %s state at %s",
+ call_func.__name__, time_message)
+ else:
+ ad.log.error("In correct %s state at %s",
+ call_func.__name__, time_message)
+
+ if not ad.droid.telecomCallGetAudioState():
+ if not verify_after_cf_disabled:
+ ad.log.error("Audio is not in call state at %s",
+ time_message)
+ result = False
+
+ if not result:
+ if call_forwarding_type == "not_reachable":
+ if toggle_airplane_mode_msim(
+ log,
+ ad_callee,
+ new_state=False,
+ strict_checking=True):
+ time.sleep(10)
+ elif call_forwarding_type == "busy":
+ hangup_call(log, ad_callee)
+
+ if not verify_after_cf_disabled:
+ erase_call_forwarding_by_mmi(
+ log,
+ ad_callee,
+ call_forwarding_type=call_forwarding_type)
+ return False
+
+ if ad_hangup:
+ if not hangup_call(log, ad_hangup):
+ ad_hangup.log.info("Failed to hang up the call")
+ result = False
+ if call_forwarding_type == "not_reachable":
+ if toggle_airplane_mode_msim(
+ log,
+ ad_callee,
+ new_state=False,
+ strict_checking=True):
+ time.sleep(10)
+ elif call_forwarding_type == "busy":
+ hangup_call(log, ad_callee)
+
+ if not verify_after_cf_disabled:
+ erase_call_forwarding_by_mmi(
+ log,
+ ad_callee,
+ call_forwarding_type=call_forwarding_type)
+ return False
+ finally:
+ if not result:
+ if verify_after_cf_disabled:
+ result = True
+ else:
+ for ad in (ad_caller, forwarded_callee):
+ last_call_drop_reason(ad, begin_time)
+ try:
+ if ad.droid.telecomIsInCall():
+ ad.log.info("In call. End now.")
+ ad.droid.telecomEndCall()
+ except Exception as e:
+ log.error(str(e))
+
+ if ad_hangup or not result:
+ for ad in (ad_caller, forwarded_callee):
+ if not wait_for_call_id_clearing(
+ ad, getattr(ad, "caller_ids", [])):
+ result = False
+
+ if call_forwarding_type == "not_reachable":
+ if toggle_airplane_mode_msim(
+ log,
+ ad_callee,
+ new_state=False,
+ strict_checking=True):
+ time.sleep(10)
+ elif call_forwarding_type == "busy":
+ hangup_call(log, ad_callee)
+
+ if not verify_after_cf_disabled:
+ erase_call_forwarding_by_mmi(
+ log,
+ ad_callee,
+ call_forwarding_type=call_forwarding_type)
+
+ if not result:
+ return result
+
+ ad_caller.log.info(
+ "Make a normal call to callee to ensure the call can be connected after"
+ " call forwarding was disabled")
+ return call_setup_teardown_for_subscription(
+ log, ad_caller, ad_callee, subid_caller, subid_callee, ad_caller,
+ verify_caller_func, verify_callee_func, wait_time_in_call,
+ incall_ui_display, dialing_number_length, video_state)
+
+
+def get_call_forwarding_by_adb(log, ad, call_forwarding_type="unconditional"):
+ """ Get call forwarding status by adb shell command
+ 'dumpsys telephony.registry'.
+
+ Args:
+ log: log object
+ ad: android object
+ call_forwarding_type:
+ - "unconditional"
+ - "busy" (todo)
+ - "not_answered" (todo)
+ - "not_reachable" (todo)
+ Returns:
+ - "true": if call forwarding unconditional is enabled.
+ - "false": if call forwarding unconditional is disabled.
+ - "unknown": if the type is other than 'unconditional'.
+ - False: any case other than above 3 cases.
+ """
+ if call_forwarding_type != "unconditional":
+ return "unknown"
+
+ slot_index_of_default_voice_subid = get_slot_index_from_subid(ad,
+ get_incoming_voice_sub_id(ad))
+ output = ad.adb.shell("dumpsys telephony.registry | grep mCallForwarding")
+ if "mCallForwarding" in output:
+ result_list = re.findall(r"mCallForwarding=(true|false)", output)
+ if result_list:
+ result = result_list[slot_index_of_default_voice_subid]
+ ad.log.info("mCallForwarding is %s", result)
+
+ if re.search("false", result, re.I):
+ return "false"
+ elif re.search("true", result, re.I):
+ return "true"
+ else:
+ return False
+ else:
+ return False
+ else:
+ ad.log.error("'mCallForwarding' cannot be found in dumpsys.")
+ return False
+
+
+def erase_call_forwarding_by_mmi(
+ log,
+ ad,
+ retry=2,
+ call_forwarding_type="unconditional"):
+ """ Erase setting of call forwarding (erase the number and disable call
+ forwarding) by MMI code.
+
+ Args:
+ log: log object
+ ad: android object
+ retry: times of retry if the erasure failed.
+ call_forwarding_type:
+ - "unconditional"
+ - "busy"
+ - "not_answered"
+ - "not_reachable"
+ Returns:
+ True by successful erasure. Otherwise False.
+ """
+ operator_name = get_operator_name(log, ad)
+
+ run_get_call_forwarding_by_adb = 1
+ if operator_name in NOT_CHECK_MCALLFORWARDING_OPERATOR_LIST:
+ run_get_call_forwarding_by_adb = 0
+
+ if run_get_call_forwarding_by_adb:
+ res = get_call_forwarding_by_adb(log, ad,
+ call_forwarding_type=call_forwarding_type)
+ if res == "false":
+ return True
+
+ user_config_profile = get_user_config_profile(ad)
+ is_airplane_mode = user_config_profile["Airplane Mode"]
+ is_wfc_enabled = user_config_profile["WFC Enabled"]
+ wfc_mode = user_config_profile["WFC Mode"]
+ is_wifi_on = user_config_profile["WiFi State"]
+
+ if is_airplane_mode:
+ if not toggle_airplane_mode(log, ad, False):
+ ad.log.error("Failed to disable airplane mode.")
+ return False
+
+ code_dict = {
+ "Verizon": {
+ "unconditional": "73",
+ "busy": "73",
+ "not_answered": "73",
+ "not_reachable": "73",
+ "mmi": "*%s"
+ },
+ "Sprint": {
+ "unconditional": "720",
+ "busy": "740",
+ "not_answered": "730",
+ "not_reachable": "720",
+ "mmi": "*%s"
+ },
+ "Far EasTone": {
+ "unconditional": "142",
+ "busy": "143",
+ "not_answered": "144",
+ "not_reachable": "144",
+ "mmi": "*%s*2"
+ },
+ 'Generic': {
+ "unconditional": "21",
+ "busy": "67",
+ "not_answered": "61",
+ "not_reachable": "62",
+ "mmi": "##%s#"
+ }
+ }
+
+ if operator_name in code_dict:
+ code = code_dict[operator_name][call_forwarding_type]
+ mmi = code_dict[operator_name]["mmi"]
+ else:
+ code = code_dict['Generic'][call_forwarding_type]
+ mmi = code_dict['Generic']["mmi"]
+
+ result = False
+ while retry >= 0:
+ if run_get_call_forwarding_by_adb:
+ res = get_call_forwarding_by_adb(
+ log, ad, call_forwarding_type=call_forwarding_type)
+ if res == "false":
+ ad.log.info("Call forwarding is already disabled.")
+ result = True
+ break
+
+ ad.log.info("Erasing and deactivating call forwarding %s..." %
+ call_forwarding_type)
+
+ ad.droid.telecomDialNumber(mmi % code)
+
+ time.sleep(3)
+ ad.send_keycode("ENTER")
+ time.sleep(15)
+
+ # To dismiss the pop-out dialog
+ ad.send_keycode("BACK")
+ time.sleep(5)
+ ad.send_keycode("BACK")
+
+ if run_get_call_forwarding_by_adb:
+ res = get_call_forwarding_by_adb(
+ log, ad, call_forwarding_type=call_forwarding_type)
+ if res == "false" or res == "unknown":
+ result = True
+ break
+ else:
+ ad.log.error("Failed to erase and deactivate call forwarding by "
+ "MMI code ##%s#." % code)
+ retry = retry - 1
+ time.sleep(30)
+ else:
+ result = True
+ break
+
+ if is_airplane_mode:
+ if not toggle_airplane_mode(log, ad, True):
+ ad.log.error("Failed to enable airplane mode again.")
+ else:
+ if is_wifi_on:
+ ad.droid.wifiToggleState(True)
+ if is_wfc_enabled:
+ if not wait_for_wfc_enabled(
+ log, ad,max_time=MAX_WAIT_TIME_WFC_ENABLED):
+ ad.log.error("WFC is not enabled")
+
+ return result
+
+def set_call_forwarding_by_mmi(
+ log,
+ ad,
+ ad_forwarded,
+ call_forwarding_type="unconditional",
+ retry=2):
+ """ Set up the forwarded number and enable call forwarding by MMI code.
+
+ Args:
+ log: log object
+ ad: android object of the device forwarding the call (primary device)
+ ad_forwarded: android object of the device receiving forwarded call.
+ retry: times of retry if the erasure failed.
+ call_forwarding_type:
+ - "unconditional"
+ - "busy"
+ - "not_answered"
+ - "not_reachable"
+ Returns:
+ True by successful erasure. Otherwise False.
+ """
+
+ res = get_call_forwarding_by_adb(log, ad,
+ call_forwarding_type=call_forwarding_type)
+ if res == "true":
+ return True
+
+ if ad.droid.connectivityCheckAirplaneMode():
+ ad.log.warning("%s is now in airplane mode.", ad.serial)
+ return True
+
+ operator_name = get_operator_name(log, ad)
+
+ code_dict = {
+ "Verizon": {
+ "unconditional": "72",
+ "busy": "71",
+ "not_answered": "71",
+ "not_reachable": "72",
+ "mmi": "*%s%s"
+ },
+ "Sprint": {
+ "unconditional": "72",
+ "busy": "74",
+ "not_answered": "73",
+ "not_reachable": "72",
+ "mmi": "*%s%s"
+ },
+ "Far EasTone": {
+ "unconditional": "142",
+ "busy": "143",
+ "not_answered": "144",
+ "not_reachable": "144",
+ "mmi": "*%s*%s"
+ },
+ 'Generic': {
+ "unconditional": "21",
+ "busy": "67",
+ "not_answered": "61",
+ "not_reachable": "62",
+ "mmi": "*%s*%s#",
+ "mmi_for_plus_sign": "*%s*"
+ }
+ }
+
+ if operator_name in code_dict:
+ code = code_dict[operator_name][call_forwarding_type]
+ mmi = code_dict[operator_name]["mmi"]
+ if "mmi_for_plus_sign" in code_dict[operator_name]:
+ mmi_for_plus_sign = code_dict[operator_name]["mmi_for_plus_sign"]
+ else:
+ code = code_dict['Generic'][call_forwarding_type]
+ mmi = code_dict['Generic']["mmi"]
+ mmi_for_plus_sign = code_dict['Generic']["mmi_for_plus_sign"]
+
+ while retry >= 0:
+ if not erase_call_forwarding_by_mmi(
+ log, ad, call_forwarding_type=call_forwarding_type):
+ retry = retry - 1
+ continue
+
+ forwarded_number = ad_forwarded.telephony['subscription'][
+ ad_forwarded.droid.subscriptionGetDefaultVoiceSubId()][
+ 'phone_num']
+ ad.log.info("Registering and activating call forwarding %s to %s..." %
+ (call_forwarding_type, forwarded_number))
+
+ (forwarded_number_no_prefix, _) = _phone_number_remove_prefix(
+ forwarded_number)
+
+ if operator_name == "Far EasTone":
+ forwarded_number_no_prefix = "0" + forwarded_number_no_prefix
+
+ run_get_call_forwarding_by_adb = 1
+ if operator_name in NOT_CHECK_MCALLFORWARDING_OPERATOR_LIST:
+ run_get_call_forwarding_by_adb = 0
+
+ _found_plus_sign = 0
+ if re.search("^\+", forwarded_number):
+ _found_plus_sign = 1
+ forwarded_number.replace("+", "")
+
+ if operator_name in code_dict:
+ ad.droid.telecomDialNumber(mmi % (code, forwarded_number_no_prefix))
+ else:
+ if _found_plus_sign == 0:
+ ad.droid.telecomDialNumber(mmi % (code, forwarded_number))
+ else:
+ ad.droid.telecomDialNumber(mmi_for_plus_sign % code)
+ ad.send_keycode("PLUS")
+
+ if "#" in mmi:
+ dial_phone_number(ad, forwarded_number + "#")
+ else:
+ dial_phone_number(ad, forwarded_number)
+
+ time.sleep(3)
+ ad.send_keycode("ENTER")
+ time.sleep(15)
+
+ # To dismiss the pop-out dialog
+ ad.send_keycode("BACK")
+ time.sleep(5)
+ ad.send_keycode("BACK")
+
+ if not run_get_call_forwarding_by_adb:
+ return True
+
+ result = get_call_forwarding_by_adb(
+ log, ad, call_forwarding_type=call_forwarding_type)
+ if result == "false":
+ retry = retry - 1
+ elif result == "true":
+ return True
+ elif result == "unknown":
+ return True
+ else:
+ retry = retry - 1
+
+ if retry >= 0:
+ ad.log.warning("Failed to register or activate call forwarding %s "
+ "to %s. Retry after 15 seconds." % (call_forwarding_type,
+ forwarded_number))
+ time.sleep(15)
+
+ ad.log.error("Failed to register or activate call forwarding %s to %s." %
+ (call_forwarding_type, forwarded_number))
+ return False
+
+
+def call_setup_teardown_for_call_waiting(log,
+ ad_caller,
+ ad_callee,
+ ad_caller2,
+ ad_hangup=None,
+ ad_hangup2=None,
+ verify_callee_func=None,
+ end_first_call_before_answering_second_call=True,
+ wait_time_in_call=WAIT_TIME_IN_CALL,
+ incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
+ dialing_number_length=None,
+ video_state=None,
+ call_waiting=True):
+ """ Call process for call waiting, including make the 1st phone call from
+ caller, answer the call by the callee, and receive the 2nd call from the
+ caller2. The call is on default voice subscription
+
+ In call process, 1st call from <ad_caller> to <ad_callee>, 2nd call from
+ <ad_caller2> to <ad_callee>, hang up the existing call or reject the
+ incoming call according to the test scenario.
+
+ Args:
+ ad_caller: Caller Android Device Object.
+ ad_callee: Callee Android Device Object.
+ ad_caller2: Caller2 Android Device Object.
+ ad_hangup: Android Device Object end the 1st phone call.
+ Optional. Default value is None, and phone call will continue.
+ ad_hangup2: Android Device Object end the 2nd phone call.
+ Optional. Default value is None, and phone call will continue.
+ verify_callee_func: func_ptr to verify callee in correct mode
+ Optional. Default is None
+ end_first_call_before_answering_second_call: If True the 2nd call will
+ be rejected on the ringing stage.
+ wait_time_in_call: the call duration of a connected call
+ incall_ui_display: after answer the call, bring in-call UI to foreground
+ or background.
+ Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
+ if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
+ if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
+ else, do nothing.
+ dialing_number_length: the number of digits used for dialing
+ video_state: video call or voice call. Default is voice call.
+ call_waiting: True to enable call waiting and False to disable.
+
+ Returns:
+ True if call process without any error.
+ False if error happened.
+
+ """
+ subid_caller = get_outgoing_voice_sub_id(ad_caller)
+ subid_callee = get_incoming_voice_sub_id(ad_callee)
+ subid_caller2 = get_incoming_voice_sub_id(ad_caller2)
+ return call_setup_teardown_for_call_waiting_for_subscription(
+ log,
+ ad_caller,
+ ad_callee,
+ ad_caller2,
+ subid_caller,
+ subid_callee,
+ subid_caller2,
+ ad_hangup, ad_hangup2,
+ verify_callee_func,
+ end_first_call_before_answering_second_call,
+ wait_time_in_call,
+ incall_ui_display,
+ dialing_number_length,
+ video_state,
+ call_waiting)
+
+
+def call_setup_teardown_for_call_waiting_for_subscription(
+ log,
+ ad_caller,
+ ad_callee,
+ ad_caller2,
+ subid_caller,
+ subid_callee,
+ subid_caller2,
+ ad_hangup=None,
+ ad_hangup2=None,
+ verify_callee_func=None,
+ end_first_call_before_answering_second_call=True,
+ wait_time_in_call=WAIT_TIME_IN_CALL,
+ incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
+ dialing_number_length=None,
+ video_state=None,
+ call_waiting=True):
+ """ Call process for call waiting, including make the 1st phone call from
+ caller, answer the call by the callee, and receive the 2nd call from the
+ caller2. The call is on specified subscription.
+
+ In call process, 1st call from <ad_caller> to <ad_callee>, 2nd call from
+ <ad_caller2> to <ad_callee>, hang up the existing call or reject the
+ incoming call according to the test scenario.
+
+ Args:
+ ad_caller: Caller Android Device Object.
+ ad_callee: Callee Android Device Object.
+ ad_caller2: Caller2 Android Device Object.
+ subid_caller: Caller subscription ID.
+ subid_callee: Callee subscription ID.
+ subid_caller2: Caller2 subscription ID.
+ ad_hangup: Android Device Object end the 1st phone call.
+ Optional. Default value is None, and phone call will continue.
+ ad_hangup2: Android Device Object end the 2nd phone call.
+ Optional. Default value is None, and phone call will continue.
+ verify_callee_func: func_ptr to verify callee in correct mode
+ Optional. Default is None
+ end_first_call_before_answering_second_call: If True the 2nd call will
+ be rejected on the ringing stage.
+ wait_time_in_call: the call duration of a connected call
+ incall_ui_display: after answer the call, bring in-call UI to foreground
+ or background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
+ if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
+ if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
+ else, do nothing.
+ dialing_number_length: the number of digits used for dialing
+ video_state: video call or voice call. Default is voice call.
+ call_waiting: True to enable call waiting and False to disable.
+
+ Returns:
+ True if call process without any error.
+ False if error happened.
+
+ """
+
+ CHECK_INTERVAL = 5
+ begin_time = get_current_epoch_time()
+ verify_caller_func = is_phone_in_call
+ if not verify_callee_func:
+ verify_callee_func = is_phone_in_call
+ verify_caller2_func = is_phone_in_call
+
+ caller_number = ad_caller.telephony['subscription'][subid_caller][
+ 'phone_num']
+ callee_number = ad_callee.telephony['subscription'][subid_callee][
+ 'phone_num']
+ caller2_number = ad_caller2.telephony['subscription'][subid_caller2][
+ 'phone_num']
+ if dialing_number_length:
+ skip_test = False
+ trunc_position = 0 - int(dialing_number_length)
+ try:
+ caller_area_code = caller_number[:trunc_position]
+ callee_area_code = callee_number[:trunc_position]
+ callee_dial_number = callee_number[trunc_position:]
+ except:
+ skip_test = True
+ if caller_area_code != callee_area_code:
+ skip_test = True
+ if skip_test:
+ msg = "Cannot make call from %s to %s by %s digits" % (
+ caller_number, callee_number, dialing_number_length)
+ ad_caller.log.info(msg)
+ raise signals.TestSkip(msg)
+ else:
+ callee_number = callee_dial_number
+
+ result = True
+ msg = "Call from %s to %s" % (caller_number, callee_number)
+ if video_state:
+ msg = "Video %s" % msg
+ video = True
+ else:
+ video = False
+ if ad_hangup:
+ msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
+ ad_caller.log.info(msg)
+
+ for ad in (ad_caller, ad_callee, ad_caller2):
+ call_ids = ad.droid.telecomCallGetCallIds()
+ setattr(ad, "call_ids", call_ids)
+ if call_ids:
+ ad.log.info("Pre-exist CallId %s before making call", call_ids)
+
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=0)
+ else:
+ set_call_waiting(log, ad_callee, enable=1)
+
+ first_call_ids = []
+ try:
+ if not initiate_call(
+ log,
+ ad_caller,
+ callee_number,
+ incall_ui_display=incall_ui_display,
+ video=video):
+ ad_caller.log.error("Initiate call failed.")
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ result = False
+ return False
+ else:
+ ad_caller.log.info("Caller initate call successfully")
+ if not wait_and_answer_call_for_subscription(
+ log,
+ ad_callee,
+ subid_callee,
+ incoming_number=caller_number,
+ caller=ad_caller,
+ incall_ui_display=incall_ui_display,
+ video_state=video_state):
+ ad_callee.log.error("Answer call fail.")
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ result = False
+ return False
+ else:
+ ad_callee.log.info("Callee answered the call successfully")
+
+ for ad, subid, call_func in zip(
+ [ad_caller, ad_callee],
+ [subid_caller, subid_callee],
+ [verify_caller_func, verify_callee_func]):
+ call_ids = ad.droid.telecomCallGetCallIds()
+ new_call_ids = set(call_ids) - set(ad.call_ids)
+ if not new_call_ids:
+ ad.log.error(
+ "No new call ids are found after call establishment")
+ ad.log.error("telecomCallGetCallIds returns %s",
+ ad.droid.telecomCallGetCallIds())
+ result = False
+ for new_call_id in new_call_ids:
+ first_call_ids.append(new_call_id)
+ if not wait_for_in_call_active(ad, call_id=new_call_id):
+ result = False
+ else:
+ ad.log.info("callProperties = %s",
+ ad.droid.telecomCallGetProperties(new_call_id))
+
+ if not ad.droid.telecomCallGetAudioState():
+ ad.log.error("Audio is not in call state")
+ result = False
+
+ if call_func(log, ad):
+ ad.log.info("Call is in %s state", call_func.__name__)
+ else:
+ ad.log.error("Call is not in %s state, voice in RAT %s",
+ call_func.__name__,
+ ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
+ result = False
+ if not result:
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ return False
+
+ time.sleep(3)
+ if not call_waiting:
+ if not initiate_call(
+ log,
+ ad_caller2,
+ callee_number,
+ incall_ui_display=incall_ui_display,
+ video=video):
+ ad_caller2.log.info("Initiate call failed.")
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ result = False
+ return False
+ else:
+ ad_caller2.log.info("Caller 2 initate 2nd call successfully")
+
+ if not wait_and_answer_call_for_subscription(
+ log,
+ ad_callee,
+ subid_callee,
+ incoming_number=caller2_number,
+ caller=ad_caller2,
+ incall_ui_display=incall_ui_display,
+ video_state=video_state):
+ ad_callee.log.info(
+ "Answering 2nd call fail due to call waiting deactivate.")
+ else:
+ ad_callee.log.error("Callee should not be able to answer the"
+ " 2nd call due to call waiting deactivated.")
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ result = False
+ return False
+
+ time.sleep(3)
+ if not hangup_call(log, ad_caller2):
+ ad_caller2.log.info("Failed to hang up the 2nd call")
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ result = False
+ return False
+
+ else:
+
+ for ad in (ad_callee, ad_caller2):
+ call_ids = ad.droid.telecomCallGetCallIds()
+ setattr(ad, "call_ids", call_ids)
+ if call_ids:
+ ad.log.info("Current existing CallId %s before making the"
+ " second call.", call_ids)
+
+ if not initiate_call(
+ log,
+ ad_caller2,
+ callee_number,
+ incall_ui_display=incall_ui_display,
+ video=video):
+ ad_caller2.log.info("Initiate 2nd call failed.")
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ result = False
+ return False
+ else:
+ ad_caller2.log.info("Caller 2 initate 2nd call successfully")
+
+ if end_first_call_before_answering_second_call:
+ try:
+ if not wait_for_ringing_call_for_subscription(
+ log,
+ ad_callee,
+ subid_callee,
+ incoming_number=caller2_number,
+ caller=ad_caller2,
+ event_tracking_started=True):
+ ad_callee.log.info(
+ "2nd incoming call ringing check failed.")
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ return False
+
+ time.sleep(3)
+
+ ad_hangup.log.info("Disconnecting first call...")
+ for call_id in first_call_ids:
+ disconnect_call_by_id(log, ad_hangup, call_id)
+ time.sleep(3)
+
+ ad_callee.log.info("Answering the 2nd ring call...")
+ ad_callee.droid.telecomAcceptRingingCall(video_state)
+
+ if wait_for_call_offhook_for_subscription(
+ log,
+ ad_callee,
+ subid_callee,
+ event_tracking_started=True):
+ ad_callee.log.info(
+ "Callee answered the 2nd call successfully.")
+ else:
+ ad_callee.log.error("Could not answer the 2nd call.")
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ return False
+ except Exception as e:
+ log.error(e)
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ return False
+
+ else:
+ if not wait_and_answer_call_for_subscription(
+ log,
+ ad_callee,
+ subid_callee,
+ incoming_number=caller2_number,
+ caller=ad_caller2,
+ incall_ui_display=incall_ui_display,
+ video_state=video_state):
+ ad_callee.log.error("Failed to answer 2nd call.")
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ result = False
+ return False
+ else:
+ ad_callee.log.info(
+ "Callee answered the 2nd call successfully.")
+
+ for ad, subid, call_func in zip(
+ [ad_callee, ad_caller2],
+ [subid_callee, subid_caller2],
+ [verify_callee_func, verify_caller2_func]):
+ call_ids = ad.droid.telecomCallGetCallIds()
+ new_call_ids = set(call_ids) - set(ad.call_ids)
+ if not new_call_ids:
+ ad.log.error(
+ "No new call ids are found after 2nd call establishment")
+ ad.log.error("telecomCallGetCallIds returns %s",
+ ad.droid.telecomCallGetCallIds())
+ result = False
+ for new_call_id in new_call_ids:
+ if not wait_for_in_call_active(ad, call_id=new_call_id):
+ result = False
+ else:
+ ad.log.info("callProperties = %s",
+ ad.droid.telecomCallGetProperties(new_call_id))
+
+ if not ad.droid.telecomCallGetAudioState():
+ ad.log.error("Audio is not in 2nd call state")
+ result = False
+
+ if call_func(log, ad):
+ ad.log.info("2nd call is in %s state", call_func.__name__)
+ else:
+ ad.log.error("2nd call is not in %s state, voice in RAT %s",
+ call_func.__name__,
+ ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
+ result = False
+ if not result:
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ return False
+
+ elapsed_time = 0
+ while (elapsed_time < wait_time_in_call):
+ CHECK_INTERVAL = min(CHECK_INTERVAL,
+ wait_time_in_call - elapsed_time)
+ time.sleep(CHECK_INTERVAL)
+ elapsed_time += CHECK_INTERVAL
+ time_message = "at <%s>/<%s> second." % (elapsed_time,
+ wait_time_in_call)
+
+ if not end_first_call_before_answering_second_call or \
+ not call_waiting:
+ for ad, subid, call_func in [
+ (ad_caller, subid_caller, verify_caller_func),
+ (ad_callee, subid_callee, verify_callee_func)]:
+ if not call_func(log, ad):
+ ad.log.error(
+ "The first call NOT in correct %s state at %s,"
+ " voice in RAT %s",
+ call_func.__name__, time_message,
+ ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
+ result = False
+ else:
+ ad.log.info("The first call in correct %s state at %s",
+ call_func.__name__, time_message)
+ if not ad.droid.telecomCallGetAudioState():
+ ad.log.error(
+ "The first call audio is not in call state at %s",
+ time_message)
+ result = False
+ if not result:
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ return False
+
+ if call_waiting:
+ for ad, call_func in [(ad_caller2, verify_caller2_func),
+ (ad_callee, verify_callee_func)]:
+ if not call_func(log, ad):
+ ad.log.error(
+ "The 2nd call NOT in correct %s state at %s,"
+ " voice in RAT %s",
+ call_func.__name__, time_message,
+ ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
+ result = False
+ else:
+ ad.log.info("The 2nd call in correct %s state at %s",
+ call_func.__name__, time_message)
+ if not ad.droid.telecomCallGetAudioState():
+ ad.log.error(
+ "The 2nd call audio is not in call state at %s",
+ time_message)
+ result = False
+ if not result:
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ return False
+
+ if not end_first_call_before_answering_second_call or not call_waiting:
+ ad_hangup.log.info("Hanging up the first call...")
+ for call_id in first_call_ids:
+ disconnect_call_by_id(log, ad_hangup, call_id)
+ time.sleep(5)
+
+ if ad_hangup2 and call_waiting:
+ if not hangup_call(log, ad_hangup2):
+ ad_hangup2.log.info("Failed to hang up the 2nd call")
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ result = False
+ return False
+ finally:
+ if not result:
+ for ad in (ad_caller, ad_callee, ad_caller2):
+ last_call_drop_reason(ad, begin_time)
+ try:
+ if ad.droid.telecomIsInCall():
+ ad.log.info("In call. End now.")
+ ad.droid.telecomEndCall()
+ except Exception as e:
+ log.error(str(e))
+
+ if ad_hangup or not result:
+ for ad in (ad_caller, ad_callee):
+ if not wait_for_call_id_clearing(
+ ad, getattr(ad, "caller_ids", [])):
+ result = False
+
+ if call_waiting:
+ if ad_hangup2 or not result:
+ for ad in (ad_caller2, ad_callee):
+ if not wait_for_call_id_clearing(
+ ad, getattr(ad, "caller_ids", [])):
+ result = False
+ if not call_waiting:
+ set_call_waiting(log, ad_callee, enable=1)
+ return result
+
+
+def get_call_waiting_status(log, ad):
+ """ (Todo) Get call waiting status (activated or deactivated) when there is
+ any proper method available.
+ """
+ return True
+
+
+def set_call_waiting(log, ad, enable=1, retry=1):
+ """ Activate/deactivate call waiting by dialing MMI code.
+
+ Args:
+ log: log object.
+ ad: android object.
+ enable: 1 for activation and 0 fir deactivation
+ retry: times of retry if activation/deactivation fails
+
+ Returns:
+ True by successful activation/deactivation; otherwise False.
+ """
+ operator_name = get_operator_name(log, ad)
+
+ if operator_name in ["Verizon", "Sprint"]:
+ return True
+
+ while retry >= 0:
+ if enable:
+ ad.log.info("Activating call waiting...")
+ ad.droid.telecomDialNumber("*43#")
+ else:
+ ad.log.info("Deactivating call waiting...")
+ ad.droid.telecomDialNumber("#43#")
+
+ time.sleep(3)
+ ad.send_keycode("ENTER")
+ time.sleep(15)
+
+ ad.send_keycode("BACK")
+ time.sleep(5)
+ ad.send_keycode("BACK")
+
+ if get_call_waiting_status(log, ad):
+ return True
+ else:
+ retry = retry + 1
+
+ return False
+
+
+def three_phone_call_forwarding_short_seq(log,
+ phone_a,
+ phone_a_idle_func,
+ phone_a_in_call_check_func,
+ phone_b,
+ phone_c,
+ wait_time_in_call=WAIT_TIME_IN_CALL,
+ call_forwarding_type="unconditional",
+ retry=2):
+ """Short sequence of call process with call forwarding.
+ Test steps:
+ 1. Ensure all phones are initially in idle state.
+ 2. Enable call forwarding on Phone A.
+ 3. Make a call from Phone B to Phone A, The call should be forwarded to
+ PhoneC. Accept the call on Phone C.
+ 4. Ensure the call is connected and in correct phone state.
+ 5. Hang up the call on Phone B.
+ 6. Ensure all phones are in idle state.
+ 7. Disable call forwarding on Phone A.
+ 7. Make a call from Phone B to Phone A, The call should NOT be forwarded
+ to PhoneC. Accept the call on Phone A.
+ 8. Ensure the call is connected and in correct phone state.
+ 9. Hang up the call on Phone B.
+
+ Args:
+ phone_a: android object of Phone A
+ phone_a_idle_func: function to check idle state on Phone A
+ phone_a_in_call_check_func: function to check in-call state on Phone A
+ phone_b: android object of Phone B
+ phone_c: android object of Phone C
+ wait_time_in_call: time to wait in call.
+ This is optional, default is WAIT_TIME_IN_CALL
+ call_forwarding_type:
+ - "unconditional"
+ - "busy"
+ - "not_answered"
+ - "not_reachable"
+ retry: times of retry
+
+ Returns:
+ True: if call sequence succeed.
+ False: for errors
+ """
+ ads = [phone_a, phone_b, phone_c]
+
+ call_params = [
+ (ads[1], ads[0], ads[2], ads[1], phone_a_in_call_check_func, False)
+ ]
+
+ if call_forwarding_type != "unconditional":
+ call_params.append((
+ ads[1],
+ ads[0],
+ ads[2],
+ ads[1],
+ phone_a_in_call_check_func,
+ True))
+
+ for param in call_params:
+ ensure_phones_idle(log, ads)
+ if phone_a_idle_func and not phone_a_idle_func(log, phone_a):
+ phone_a.log.error("Phone A Failed to Reselect")
+ return False
+
+ time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL)
+
+ log.info(
+ "---> Call forwarding %s (caller: %s, callee: %s, callee forwarded:"
+ " %s) <---",
+ call_forwarding_type,
+ param[0].serial,
+ param[1].serial,
+ param[2].serial)
+ while not call_setup_teardown_for_call_forwarding(
+ log,
+ *param,
+ wait_time_in_call=wait_time_in_call,
+ call_forwarding_type=call_forwarding_type) and retry >= 0:
+
+ if retry <= 0:
+ log.error("Call forwarding %s failed." % call_forwarding_type)
+ return False
+ else:
+ log.info(
+ "RERUN the test case: 'Call forwarding %s'" %
+ call_forwarding_type)
+
+ retry = retry - 1
+
+ return True
+
+def three_phone_call_waiting_short_seq(log,
+ phone_a,
+ phone_a_idle_func,
+ phone_a_in_call_check_func,
+ phone_b,
+ phone_c,
+ wait_time_in_call=WAIT_TIME_IN_CALL,
+ call_waiting=True,
+ scenario=None,
+ retry=2):
+ """Short sequence of call process with call waiting.
+ Test steps:
+ 1. Ensure all phones are initially in idle state.
+ 2. Enable call waiting on Phone A.
+ 3. Make the 1st call from Phone B to Phone A. Accept the call on Phone B.
+ 4. Ensure the call is connected and in correct phone state.
+ 5. Make the 2nd call from Phone C to Phone A. The call should be able to
+ income correctly. Whether or not the 2nd call should be answered by
+ Phone A depends on the scenario listed in the next step.
+ 6. Following 8 scenarios will be tested:
+ - 1st call ended first by Phone B during 2nd call incoming. 2nd call
+ ended by Phone C
+ - 1st call ended first by Phone B during 2nd call incoming. 2nd call
+ ended by Phone A
+ - 1st call ended first by Phone A during 2nd call incoming. 2nd call
+ ended by Phone C
+ - 1st call ended first by Phone A during 2nd call incoming. 2nd call
+ ended by Phone A
+ - 1st call ended by Phone B. 2nd call ended by Phone C
+ - 1st call ended by Phone B. 2nd call ended by Phone A
+ - 1st call ended by Phone A. 2nd call ended by Phone C
+ - 1st call ended by Phone A. 2nd call ended by Phone A
+ 7. Ensure all phones are in idle state.
+
+ Args:
+ phone_a: android object of Phone A
+ phone_a_idle_func: function to check idle state on Phone A
+ phone_a_in_call_check_func: function to check in-call state on Phone A
+ phone_b: android object of Phone B
+ phone_c: android object of Phone C
+ wait_time_in_call: time to wait in call.
+ This is optional, default is WAIT_TIME_IN_CALL
+ call_waiting: True for call waiting enabled and False for disabled
+ scenario: 1-8 for scenarios listed above
+ retry: times of retry
+
+ Returns:
+ True: if call sequence succeed.
+ False: for errors
+ """
+ ads = [phone_a, phone_b, phone_c]
+
+ sub_test_cases = [
+ {
+ "description": "1st call ended first by caller1 during 2nd call"
+ " incoming. 2nd call ended by caller2",
+ "params": (
+ ads[1],
+ ads[0],
+ ads[2],
+ ads[1],
+ ads[2],
+ phone_a_in_call_check_func,
+ True)},
+ {
+ "description": "1st call ended first by caller1 during 2nd call"
+ " incoming. 2nd call ended by callee",
+ "params": (
+ ads[1],
+ ads[0],
+ ads[2],
+ ads[1],
+ ads[0],
+ phone_a_in_call_check_func,
+ True)},
+ {
+ "description": "1st call ended first by callee during 2nd call"
+ " incoming. 2nd call ended by caller2",
+ "params": (
+ ads[1],
+ ads[0],
+ ads[2],
+ ads[0],
+ ads[2],
+ phone_a_in_call_check_func,
+ True)},
+ {
+ "description": "1st call ended first by callee during 2nd call"
+ " incoming. 2nd call ended by callee",
+ "params": (
+ ads[1],
+ ads[0],
+ ads[2],
+ ads[0],
+ ads[0],
+ phone_a_in_call_check_func,
+ True)},
+ {
+ "description": "1st call ended by caller1. 2nd call ended by"
+ " caller2",
+ "params": (
+ ads[1],
+ ads[0],
+ ads[2],
+ ads[1],
+ ads[2],
+ phone_a_in_call_check_func,
+ False)},
+ {
+ "description": "1st call ended by caller1. 2nd call ended by callee",
+ "params": (
+ ads[1],
+ ads[0],
+ ads[2],
+ ads[1],
+ ads[0],
+ phone_a_in_call_check_func,
+ False)},
+ {
+ "description": "1st call ended by callee. 2nd call ended by caller2",
+ "params": (
+ ads[1],
+ ads[0],
+ ads[2],
+ ads[0],
+ ads[2],
+ phone_a_in_call_check_func,
+ False)},
+ {
+ "description": "1st call ended by callee. 2nd call ended by callee",
+ "params": (
+ ads[1],
+ ads[0],
+ ads[2],
+ ads[0],
+ ads[0],
+ phone_a_in_call_check_func,
+ False)}
+ ]
+
+ if call_waiting:
+ if not scenario:
+ test_cases = sub_test_cases
+ else:
+ test_cases = [sub_test_cases[scenario-1]]
+ else:
+ test_cases = [
+ {
+ "description": "Call waiting deactivated",
+ "params": (
+ ads[1],
+ ads[0],
+ ads[2],
+ ads[0],
+ ads[0],
+ phone_a_in_call_check_func,
+ False)}
+ ]
+
+ results = []
+
+ for test_case in test_cases:
+ ensure_phones_idle(log, ads)
+ if phone_a_idle_func and not phone_a_idle_func(log, phone_a):
+ phone_a.log.error("Phone A Failed to Reselect")
+ return False
+
+ time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL)
+
+ log.info(
+ "---> %s (caller1: %s, caller2: %s, callee: %s) <---",
+ test_case["description"],
+ test_case["params"][1].serial,
+ test_case["params"][2].serial,
+ test_case["params"][0].serial)
+
+ while not call_setup_teardown_for_call_waiting(
+ log,
+ *test_case["params"],
+ wait_time_in_call=wait_time_in_call,
+ call_waiting=call_waiting) and retry >= 0:
+
+ if retry <= 0:
+ log.error("Call waiting sub-case: '%s' failed." % test_case[
+ "description"])
+ results.append(False)
+ else:
+ log.info("RERUN the sub-case: '%s'" % test_case["description"])
+
+ retry = retry - 1
+
+ for result in results:
+ if not result:
+ return False
+
+ return True
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_subscription_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_subscription_utils.py
index 953f3851..6fd9e90 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_subscription_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_subscription_utils.py
@@ -16,17 +16,19 @@
# This is test util for subscription setup.
# It will be deleted once we have better solution for subscription ids.
-from future import standard_library
-standard_library.install_aliases()
-from acts_contrib.test_utils.tel.tel_defines import CHIPSET_MODELS_LIST
-from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
-
+import re
import time
+from acts_contrib.test_utils.tel.tel_defines import CHIPSET_MODELS_LIST
+from acts_contrib.test_utils.tel.tel_defines import INVALID_SIM_SLOT_INDEX
+from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID
+from future import standard_library
-def initial_set_up_for_subid_infomation(log, ad):
+standard_library.install_aliases()
+
+
+def initial_set_up_for_subid_information(log, ad):
"""Initial subid setup for voice, message and data according to ad's
attribute.
@@ -157,6 +159,28 @@
return ad.droid.subscriptionGetDefaultSmsSubId()
+def get_subid_by_adb(ad, sim_slot_index):
+ """Get the subscription ID for a SIM at a particular slot via adb command.
+
+ Args:
+ ad: android device object.
+ sim_slot_index: slot 0 or slot 1.
+
+ Returns:
+ Subscription ID.
+ """
+ try:
+ output = ad.adb.shell("dumpsys isub | grep subIds")
+ pattern = re.compile(r"sSlotIndexToSubId\[%d\]:\s*subIds=%d=\[(\d)\]" %
+ (sim_slot_index, sim_slot_index))
+ sub_id = pattern.findall(output)
+ except Exception as e:
+ error_msg = "%s due to %s" % ("Failed to get the subid", e)
+ ad.log.error(error_msg)
+ return INVALID_SUB_ID
+ return int(sub_id[0]) if sub_id else INVALID_SUB_ID
+
+
def get_subid_from_slot_index(log, ad, sim_slot_index):
""" Get the subscription ID for a SIM at a particular slot
@@ -205,6 +229,7 @@
return info['carrierId']
return None
+
def get_isopportunistic_from_slot_index(ad, sim_slot_index):
""" Get the isOppotunistic field for a particular slot
@@ -221,6 +246,7 @@
return info['isOpportunistic']
return None
+
def set_subid_for_data(ad, sub_id, time_to_sleep=WAIT_TIME_CHANGE_DATA_SUB_ID):
"""Set subId for data
@@ -317,23 +343,6 @@
ad.outgoing_voice_sub_id = sub_id
-def set_voice_sub_id(ad, sub_id):
- """Set default subId for both incoming and outgoing voice calls
-
- Args:
- ad: android device object.
- sub_id: subscription id (integer)
-
- Returns:
- None
- """
- ad.droid.subscriptionSetDefaultVoiceSubId(sub_id)
- if hasattr(ad, "incoming_voice_sub_id"):
- ad.incoming_voice_sub_id = sub_id
- if hasattr(ad, "outgoing_voice_sub_id"):
- ad.outgoing_voice_sub_id = sub_id
-
-
def set_default_sub_for_all_services(ad, slot_id=0):
"""Set subId for all services
@@ -418,6 +427,34 @@
return False
+def set_dds_on_slot(ad, dds_slot):
+ """Switch DDS to given slot.
+
+ Args:
+ ad: android device object.
+ dds_slot: the slot which be set to DDS.
+
+ Returns:
+ True if success, False if fail.
+ """
+ sub_id = get_subid_from_slot_index(ad.log, ad, dds_slot)
+ if sub_id == INVALID_SUB_ID:
+ ad.log.warning("Invalid sub ID at slot %d", dds_slot)
+ return False
+ operator = get_operatorname_from_slot_index(ad, dds_slot)
+ if get_default_data_sub_id(ad) == sub_id:
+ ad.log.info("Current DDS is already on %s", operator)
+ return True
+ ad.log.info("Setting DDS on %s", operator)
+ set_subid_for_data(ad, sub_id)
+ ad.droid.telephonyToggleDataConnection(True)
+ time.sleep(WAIT_TIME_CHANGE_DATA_SUB_ID)
+ if get_default_data_sub_id(ad) == sub_id:
+ return True
+ else:
+ return False
+
+
def set_always_allow_mms_data(ad, sub_id, state=True):
"""Set always allow mms data on sub_id
@@ -525,3 +562,65 @@
p2_mnc = mnc
return host_sub_id, p1_sub_id, p2_sub_id
+
+
+def get_slot_index_from_subid(ad, sub_id):
+ try:
+ info = ad.droid.subscriptionGetSubInfoForSubscriber(sub_id)
+ return info['simSlotIndex']
+ except KeyError:
+ return INVALID_SIM_SLOT_INDEX
+
+
+def get_slot_index_from_data_sub_id(ad):
+ """Get slot index from given sub ID for data
+
+ Args:
+ ad: Android object
+
+ Returns:
+ 0 for pSIM or 1 for eSIM. Otherwise -1 will be returned.
+ """
+ data_sub_id = get_default_data_sub_id(ad)
+ sub_info = ad.droid.subscriptionGetAllSubInfoList()
+ for info in sub_info:
+ if info['subscriptionId'] == data_sub_id:
+ return info['simSlotIndex']
+ return INVALID_SUB_ID
+
+
+def get_slot_index_from_voice_sub_id(ad):
+ """Get slot index from the current voice sub ID.
+
+ Args:
+ ad: android object
+
+ Returns:
+ 0: pSIM
+ 1: eSIM
+ INVALID_SUB_ID (-1): if no sub ID is equal to current voice sub ID.
+ """
+ voice_sub_id = get_incoming_voice_sub_id(ad)
+ sub_info = ad.droid.subscriptionGetAllSubInfoList()
+ for info in sub_info:
+ if info['subscriptionId'] == voice_sub_id:
+ return info['simSlotIndex']
+ return INVALID_SUB_ID
+
+
+def get_all_sub_id(ad):
+ """Return all valid subscription IDs.
+
+ Args:
+ ad: Android object
+
+ Returns:
+ List containing all valid subscription IDs.
+ """
+ sub_id_list = []
+ sub_info = ad.droid.subscriptionGetAllSubInfoList()
+ for info in sub_info:
+ if info['simSlotIndex'] != INVALID_SUB_ID:
+ sub_id_list.append(info['subscriptionId'])
+
+ return sub_id_list
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_test_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_test_utils.py
index 31433b7..3d7e935 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_test_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_test_utils.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2016 - Google
+# Copyright 2022 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,11 +14,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from datetime import datetime
from future import standard_library
standard_library.install_aliases()
-import concurrent.futures
import json
import logging
import re
@@ -26,24 +24,18 @@
import urllib.parse
import time
import acts.controllers.iperf_server as ipf
-import shutil
import struct
from acts import signals
-from acts import utils
from queue import Empty
from acts.asserts import abort_all
-from acts.asserts import fail
-from acts.controllers.adb_lib.error import AdbError
+from acts.controllers.adb_lib.error import AdbCommandError, AdbError
from acts.controllers.android_device import list_adb_devices
from acts.controllers.android_device import list_fastboot_devices
-from acts.controllers.android_device import DEFAULT_QXDM_LOG_PATH
-from acts.controllers.android_device import DEFAULT_SDM_LOG_PATH
-from acts.controllers.android_device import SL4A_APK_NAME
-from acts.libs.proc import job
+
+from acts.libs.proc.job import TimeoutError
from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
-from acts_contrib.test_utils.tel.tel_defines import CarrierConfigs, CARRIER_NTT_DOCOMO, CARRIER_KDDI, CARRIER_RAKUTEN, \
- CARRIER_SBM
+from acts_contrib.test_utils.tel.tel_defines import CarrierConfigs
from acts_contrib.test_utils.tel.tel_defines import AOSP_PREFIX
from acts_contrib.test_utils.tel.tel_defines import CARD_POWER_DOWN
from acts_contrib.test_utils.tel.tel_defines import CARD_POWER_UP
@@ -56,57 +48,23 @@
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC_MODE_CHANGE
from acts_contrib.test_utils.tel.tel_defines import CARRIER_UNKNOWN
-from acts_contrib.test_utils.tel.tel_defines import CARRIER_FRE
from acts_contrib.test_utils.tel.tel_defines import COUNTRY_CODE_LIST
-from acts_contrib.test_utils.tel.tel_defines import NOT_CHECK_MCALLFORWARDING_OPERATOR_LIST
-from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_CONNECTED
-from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_DISCONNECTED
+from acts_contrib.test_utils.tel.tel_defines import DIALER_PACKAGE_NAME
from acts_contrib.test_utils.tel.tel_defines import DATA_ROAMING_ENABLE
from acts_contrib.test_utils.tel.tel_defines import DATA_ROAMING_DISABLE
from acts_contrib.test_utils.tel.tel_defines import GEN_4G
-from acts_contrib.test_utils.tel.tel_defines import GEN_5G
from acts_contrib.test_utils.tel.tel_defines import GEN_UNKNOWN
-from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND
-from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND
from acts_contrib.test_utils.tel.tel_defines import INVALID_SIM_SLOT_INDEX
from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
-from acts_contrib.test_utils.tel.tel_defines import MAX_SAVED_VOICE_MAIL
from acts_contrib.test_utils.tel.tel_defines import MAX_SCREEN_ON_TIME
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_AIRPLANEMODE_EVENT
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_DROP
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_INITIATION
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALLEE_RINGING
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_DATA_SUB_CHANGE
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_IDLE_EVENT
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_SENT_SUCCESS
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_SENT_SUCCESS_IN_COLLISION
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_TELECOM_RINGING
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOICE_MAIL_COUNT
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOLTE_ENABLED
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_DISABLED
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_DATA_STALL
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_NW_VALID_FAIL
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_DATA_STALL_RECOVERY
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_ONLY
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_CELL
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_WIFI
+from acts_contrib.test_utils.tel.tel_defines import MESSAGE_PACKAGE_NAME
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_7_DIGIT
from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_10_DIGIT
from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_11_DIGIT
from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_12_DIGIT
-from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
-from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
-from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_WLAN
-from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_WCDMA
-from acts_contrib.test_utils.tel.tel_defines import RAT_1XRTT
from acts_contrib.test_utils.tel.tel_defines import RAT_UNKNOWN
from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_EMERGENCY_ONLY
from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_IN_SERVICE
@@ -119,103 +77,49 @@
from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_PIN_REQUIRED
from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_READY
from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_UNKNOWN
-from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_IDLE
-from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_OFFHOOK
-from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_RINGING
-from acts_contrib.test_utils.tel.tel_defines import VOICEMAIL_DELETE_DIGIT
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_1XRTT_VOICE_ATTACH
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_FOR_STATE_CHANGE
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_LEAVE_VOICE_MAIL
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_REJECT_CALL
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
-from acts_contrib.test_utils.tel.tel_defines import TYPE_MOBILE
-from acts_contrib.test_utils.tel.tel_defines import TYPE_WIFI
-from acts_contrib.test_utils.tel.tel_defines import EventCallStateChanged
from acts_contrib.test_utils.tel.tel_defines import EventActiveDataSubIdChanged
from acts_contrib.test_utils.tel.tel_defines import EventDisplayInfoChanged
-from acts_contrib.test_utils.tel.tel_defines import EventConnectivityChanged
-from acts_contrib.test_utils.tel.tel_defines import EventDataConnectionStateChanged
-from acts_contrib.test_utils.tel.tel_defines import EventDataSmsReceived
-from acts_contrib.test_utils.tel.tel_defines import EventMessageWaitingIndicatorChanged
from acts_contrib.test_utils.tel.tel_defines import EventServiceStateChanged
-from acts_contrib.test_utils.tel.tel_defines import EventMmsSentFailure
-from acts_contrib.test_utils.tel.tel_defines import EventMmsSentSuccess
-from acts_contrib.test_utils.tel.tel_defines import EventMmsDownloaded
-from acts_contrib.test_utils.tel.tel_defines import EventSmsReceived
-from acts_contrib.test_utils.tel.tel_defines import EventSmsDeliverFailure
-from acts_contrib.test_utils.tel.tel_defines import EventSmsDeliverSuccess
-from acts_contrib.test_utils.tel.tel_defines import EventSmsSentFailure
-from acts_contrib.test_utils.tel.tel_defines import EventSmsSentSuccess
-from acts_contrib.test_utils.tel.tel_defines import CallStateContainer
-from acts_contrib.test_utils.tel.tel_defines import DataConnectionStateContainer
-from acts_contrib.test_utils.tel.tel_defines import MessageWaitingIndicatorContainer
from acts_contrib.test_utils.tel.tel_defines import NetworkCallbackContainer
from acts_contrib.test_utils.tel.tel_defines import ServiceStateContainer
from acts_contrib.test_utils.tel.tel_defines import DisplayInfoContainer
from acts_contrib.test_utils.tel.tel_defines import OverrideNetworkContainer
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_NR_LTE_GSM_WCDMA
-from acts_contrib.test_utils.tel.tel_defines import CARRIER_VZW, CARRIER_ATT, \
- CARRIER_BELL, CARRIER_ROGERS, CARRIER_KOODO, CARRIER_VIDEOTRON, CARRIER_TELUS
+from acts_contrib.test_utils.tel.tel_logging_utils import disable_qxdm_logger
+from acts_contrib.test_utils.tel.tel_logging_utils import get_screen_shot_log
+from acts_contrib.test_utils.tel.tel_logging_utils import log_screen_shot
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_logger
from acts_contrib.test_utils.tel.tel_lookup_tables import connection_type_from_type_string
from acts_contrib.test_utils.tel.tel_lookup_tables import is_valid_rat
from acts_contrib.test_utils.tel.tel_lookup_tables import get_allowable_network_preference
from acts_contrib.test_utils.tel.tel_lookup_tables import get_voice_mail_count_check_function
from acts_contrib.test_utils.tel.tel_lookup_tables import get_voice_mail_check_number
-from acts_contrib.test_utils.tel.tel_lookup_tables import get_voice_mail_delete_digit
from acts_contrib.test_utils.tel.tel_lookup_tables import network_preference_for_generation
from acts_contrib.test_utils.tel.tel_lookup_tables import operator_name_from_network_name
from acts_contrib.test_utils.tel.tel_lookup_tables import operator_name_from_plmn_id
-from acts_contrib.test_utils.tel.tel_lookup_tables import rat_families_for_network_preference
-from acts_contrib.test_utils.tel.tel_lookup_tables import rat_family_for_generation
from acts_contrib.test_utils.tel.tel_lookup_tables import rat_family_from_rat
from acts_contrib.test_utils.tel.tel_lookup_tables import rat_generation_from_rat
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id, get_subid_from_slot_index
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_subid
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_by_adb
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_message_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_outgoing_call
from acts_contrib.test_utils.tel.tel_subscription_utils import set_incoming_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_message
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_nsa_for_subscription
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_nsa
-from acts_contrib.test_utils.wifi import wifi_test_utils
-from acts_contrib.test_utils.wifi import wifi_constants
-from acts_contrib.test_utils.gnss import gnss_test_utils as gutils
from acts.utils import adb_shell_ping
from acts.utils import load_config
-from acts.utils import start_standing_subprocess
-from acts.utils import stop_standing_subprocess
from acts.logger import epoch_to_log_line_timestamp
-from acts.logger import normalize_log_line_timestamp
from acts.utils import get_current_epoch_time
from acts.utils import exe_cmd
-from acts.utils import rand_ascii_str
-
-WIFI_SSID_KEY = wifi_test_utils.WifiEnums.SSID_KEY
-WIFI_PWD_KEY = wifi_test_utils.WifiEnums.PWD_KEY
-WIFI_CONFIG_APBAND_2G = 1
-WIFI_CONFIG_APBAND_5G = 2
-WIFI_CONFIG_APBAND_AUTO = wifi_test_utils.WifiEnums.WIFI_CONFIG_APBAND_AUTO
log = logging
STORY_LINE = "+19523521350"
CallResult = TelephonyVoiceTestResult.CallResult.Value
-voice_call_type = {}
-result_dict ={}
-
-class TelTestUtilsError(Exception):
- pass
class TelResultWrapper(object):
@@ -311,9 +215,6 @@
return setup_droid_properties_by_adb(
log, ad, sim_filename=sim_filename)
refresh_droid_config(log, ad)
- device_props = {}
- device_props['subscription'] = {}
-
sim_data = {}
if sim_filename:
try:
@@ -392,6 +293,7 @@
droid = ad.droid
sub_info_list = droid.subscriptionGetAllSubInfoList()
ad.log.info("SubInfoList is %s", sub_info_list)
+ if not sub_info_list: return
active_sub_id = get_outgoing_voice_sub_id(ad)
for sub_info in sub_info_list:
sub_id = sub_info["subscriptionId"]
@@ -479,7 +381,6 @@
else:
sub_record["phone_num"] = phone_number_formatter(
sub_info["number"])
- #ad.telephony['subscription'][sub_id] = sub_record
ad.log.info("SubId %s info: %s", sub_id, sorted(
sub_record.items()))
@@ -533,14 +434,6 @@
}
-def get_slot_index_from_subid(log, ad, sub_id):
- try:
- info = ad.droid.subscriptionGetSubInfoForSubscriber(sub_id)
- return info['simSlotIndex']
- except KeyError:
- return INVALID_SIM_SLOT_INDEX
-
-
def get_num_active_sims(log, ad):
""" Get the number of active SIM cards by counting slots
@@ -629,12 +522,6 @@
return signal_strength
-def get_wifi_signal_strength(ad):
- signal_strength = ad.droid.wifiGetConnectionInfo()['rssi']
- ad.log.info("WiFi Signal Strength is %s" % signal_strength)
- return signal_strength
-
-
def get_lte_rsrp(ad):
try:
if ad.adb.getprop("ro.build.version.release")[0] in ("9", "P"):
@@ -659,66 +546,6 @@
return None
-def check_data_stall_detection(ad, wait_time=WAIT_TIME_FOR_DATA_STALL):
- data_stall_detected = False
- time_var = 1
- try:
- while (time_var < wait_time):
- out = ad.adb.shell("dumpsys network_stack " \
- "| grep \"Suspecting data stall\"",
- ignore_status=True)
- ad.log.debug("Output is %s", out)
- if out:
- ad.log.info("NetworkMonitor detected - %s", out)
- data_stall_detected = True
- break
- time.sleep(30)
- time_var += 30
- except Exception as e:
- ad.log.error(e)
- return data_stall_detected
-
-
-def check_network_validation_fail(ad, begin_time=None,
- wait_time=WAIT_TIME_FOR_NW_VALID_FAIL):
- network_validation_fail = False
- time_var = 1
- try:
- while (time_var < wait_time):
- time_var += 30
- nw_valid = ad.search_logcat("validation failed",
- begin_time)
- if nw_valid:
- ad.log.info("Validation Failed received here - %s",
- nw_valid[0]["log_message"])
- network_validation_fail = True
- break
- time.sleep(30)
- except Exception as e:
- ad.log.error(e)
- return network_validation_fail
-
-
-def check_data_stall_recovery(ad, begin_time=None,
- wait_time=WAIT_TIME_FOR_DATA_STALL_RECOVERY):
- data_stall_recovery = False
- time_var = 1
- try:
- while (time_var < wait_time):
- time_var += 30
- recovery = ad.search_logcat("doRecovery() cleanup all connections",
- begin_time)
- if recovery:
- ad.log.info("Recovery Performed here - %s",
- recovery[-1]["log_message"])
- data_stall_recovery = True
- break
- time.sleep(30)
- except Exception as e:
- ad.log.error(e)
- return data_stall_recovery
-
-
def break_internet_except_sl4a_port(ad, sl4a_port):
ad.log.info("Breaking internet using iptables rules")
ad.adb.shell("iptables -I INPUT 1 -p tcp --dport %s -j ACCEPT" % sl4a_port,
@@ -1011,434 +838,6 @@
return True
-def wait_and_answer_call(log,
- ad,
- incoming_number=None,
- incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
- caller=None,
- video_state=None):
- """Wait for an incoming call on default voice subscription and
- accepts the call.
-
- Args:
- ad: android device object.
- incoming_number: Expected incoming number.
- Optional. Default is None
- incall_ui_display: after answer the call, bring in-call UI to foreground or
- background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
- if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
- if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
- else, do nothing.
-
- Returns:
- True: if incoming call is received and answered successfully.
- False: for errors
- """
- return wait_and_answer_call_for_subscription(
- log,
- ad,
- get_incoming_voice_sub_id(ad),
- incoming_number,
- incall_ui_display=incall_ui_display,
- caller=caller,
- video_state=video_state)
-
-
-def _wait_for_ringing_event(log, ad, wait_time):
- """Wait for ringing event.
-
- Args:
- log: log object.
- ad: android device object.
- wait_time: max time to wait for ringing event.
-
- Returns:
- event_ringing if received ringing event.
- otherwise return None.
- """
- event_ringing = None
-
- try:
- event_ringing = ad.ed.wait_for_event(
- EventCallStateChanged,
- is_event_match,
- timeout=wait_time,
- field=CallStateContainer.CALL_STATE,
- value=TELEPHONY_STATE_RINGING)
- ad.log.info("Receive ringing event")
- except Empty:
- ad.log.info("No Ringing Event")
- finally:
- return event_ringing
-
-
-def wait_for_ringing_call(log, ad, incoming_number=None):
- """Wait for an incoming call on default voice subscription and
- accepts the call.
-
- Args:
- log: log object.
- ad: android device object.
- incoming_number: Expected incoming number.
- Optional. Default is None
-
- Returns:
- True: if incoming call is received and answered successfully.
- False: for errors
- """
- return wait_for_ringing_call_for_subscription(
- log, ad, get_incoming_voice_sub_id(ad), incoming_number)
-
-
-def wait_for_ringing_call_for_subscription(
- log,
- ad,
- sub_id,
- incoming_number=None,
- caller=None,
- event_tracking_started=False,
- timeout=MAX_WAIT_TIME_CALLEE_RINGING,
- interval=WAIT_TIME_BETWEEN_STATE_CHECK):
- """Wait for an incoming call on specified subscription.
-
- Args:
- log: log object.
- ad: android device object.
- sub_id: subscription ID
- incoming_number: Expected incoming number. Default is None
- event_tracking_started: True if event tracking already state outside
- timeout: time to wait for ring
- interval: checking interval
-
- Returns:
- True: if incoming call is received and answered successfully.
- False: for errors
- """
- if not event_tracking_started:
- ad.ed.clear_events(EventCallStateChanged)
- ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
- ring_event_received = False
- end_time = time.time() + timeout
- try:
- while time.time() < end_time:
- if not ring_event_received:
- event_ringing = _wait_for_ringing_event(log, ad, interval)
- if event_ringing:
- if incoming_number and not check_phone_number_match(
- event_ringing['data']
- [CallStateContainer.INCOMING_NUMBER], incoming_number):
- ad.log.error(
- "Incoming Number not match. Expected number:%s, actual number:%s",
- incoming_number, event_ringing['data'][
- CallStateContainer.INCOMING_NUMBER])
- return False
- ring_event_received = True
- telephony_state = ad.droid.telephonyGetCallStateForSubscription(
- sub_id)
- telecom_state = ad.droid.telecomGetCallState()
- if telephony_state == TELEPHONY_STATE_RINGING and (
- telecom_state == TELEPHONY_STATE_RINGING):
- ad.log.info("callee is in telephony and telecom RINGING state")
- if caller:
- if caller.droid.telecomIsInCall():
- caller.log.info("Caller telecom is in call state")
- return True
- else:
- caller.log.info("Caller telecom is NOT in call state")
- else:
- return True
- else:
- ad.log.info(
- "telephony in %s, telecom in %s, expecting RINGING state",
- telephony_state, telecom_state)
- time.sleep(interval)
- finally:
- if not event_tracking_started:
- ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
- sub_id)
-
-
-def wait_for_call_offhook_for_subscription(
- log,
- ad,
- sub_id,
- event_tracking_started=False,
- timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT,
- interval=WAIT_TIME_BETWEEN_STATE_CHECK):
- """Wait for an incoming call on specified subscription.
-
- Args:
- log: log object.
- ad: android device object.
- sub_id: subscription ID
- timeout: time to wait for ring
- interval: checking interval
-
- Returns:
- True: if incoming call is received and answered successfully.
- False: for errors
- """
- if not event_tracking_started:
- ad.ed.clear_events(EventCallStateChanged)
- ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
- offhook_event_received = False
- end_time = time.time() + timeout
- try:
- while time.time() < end_time:
- if not offhook_event_received:
- if wait_for_call_offhook_event(log, ad, sub_id, True,
- interval):
- offhook_event_received = True
- telephony_state = ad.droid.telephonyGetCallStateForSubscription(
- sub_id)
- telecom_state = ad.droid.telecomGetCallState()
- if telephony_state == TELEPHONY_STATE_OFFHOOK and (
- telecom_state == TELEPHONY_STATE_OFFHOOK):
- ad.log.info("telephony and telecom are in OFFHOOK state")
- return True
- else:
- ad.log.info(
- "telephony in %s, telecom in %s, expecting OFFHOOK state",
- telephony_state, telecom_state)
- if offhook_event_received:
- time.sleep(interval)
- finally:
- if not event_tracking_started:
- ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
- sub_id)
-
-
-def wait_for_call_offhook_event(
- log,
- ad,
- sub_id,
- event_tracking_started=False,
- timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT):
- """Wait for an incoming call on specified subscription.
-
- Args:
- log: log object.
- ad: android device object.
- event_tracking_started: True if event tracking already state outside
- timeout: time to wait for event
-
- Returns:
- True: if call offhook event is received.
- False: if call offhook event is not received.
- """
- if not event_tracking_started:
- ad.ed.clear_events(EventCallStateChanged)
- ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
- try:
- ad.ed.wait_for_event(
- EventCallStateChanged,
- is_event_match,
- timeout=timeout,
- field=CallStateContainer.CALL_STATE,
- value=TELEPHONY_STATE_OFFHOOK)
- ad.log.info("Got event %s", TELEPHONY_STATE_OFFHOOK)
- except Empty:
- ad.log.info("No event for call state change to OFFHOOK")
- return False
- finally:
- if not event_tracking_started:
- ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
- sub_id)
- return True
-
-
-def wait_and_answer_call_for_subscription(
- log,
- ad,
- sub_id,
- incoming_number=None,
- incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
- timeout=MAX_WAIT_TIME_CALLEE_RINGING,
- caller=None,
- video_state=None):
- """Wait for an incoming call on specified subscription and
- accepts the call.
-
- Args:
- log: log object.
- ad: android device object.
- sub_id: subscription ID
- incoming_number: Expected incoming number.
- Optional. Default is None
- incall_ui_display: after answer the call, bring in-call UI to foreground or
- background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
- if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
- if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
- else, do nothing.
-
- Returns:
- True: if incoming call is received and answered successfully.
- False: for errors
- """
- ad.ed.clear_events(EventCallStateChanged)
- ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
- try:
- if not wait_for_ringing_call_for_subscription(
- log,
- ad,
- sub_id,
- incoming_number=incoming_number,
- caller=caller,
- event_tracking_started=True,
- timeout=timeout):
- ad.log.info("Incoming call ringing check failed.")
- return False
- ad.log.info("Accept the ring call")
- ad.droid.telecomAcceptRingingCall(video_state)
-
- if wait_for_call_offhook_for_subscription(
- log, ad, sub_id, event_tracking_started=True):
- return True
- else:
- ad.log.error("Could not answer the call.")
- return False
- except Exception as e:
- log.error(e)
- return False
- finally:
- ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
- if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
- ad.droid.telecomShowInCallScreen()
- elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
- ad.droid.showHomeScreen()
-
-
-def wait_and_reject_call(log,
- ad,
- incoming_number=None,
- delay_reject=WAIT_TIME_REJECT_CALL,
- reject=True):
- """Wait for an incoming call on default voice subscription and
- reject the call.
-
- Args:
- log: log object.
- ad: android device object.
- incoming_number: Expected incoming number.
- Optional. Default is None
- delay_reject: time to wait before rejecting the call
- Optional. Default is WAIT_TIME_REJECT_CALL
-
- Returns:
- True: if incoming call is received and reject successfully.
- False: for errors
- """
- return wait_and_reject_call_for_subscription(log, ad,
- get_incoming_voice_sub_id(ad),
- incoming_number, delay_reject,
- reject)
-
-
-def wait_and_reject_call_for_subscription(log,
- ad,
- sub_id,
- incoming_number=None,
- delay_reject=WAIT_TIME_REJECT_CALL,
- reject=True):
- """Wait for an incoming call on specific subscription and
- reject the call.
-
- Args:
- log: log object.
- ad: android device object.
- sub_id: subscription ID
- incoming_number: Expected incoming number.
- Optional. Default is None
- delay_reject: time to wait before rejecting the call
- Optional. Default is WAIT_TIME_REJECT_CALL
-
- Returns:
- True: if incoming call is received and reject successfully.
- False: for errors
- """
-
- if not wait_for_ringing_call_for_subscription(log, ad, sub_id,
- incoming_number):
- ad.log.error(
- "Could not reject a call: incoming call in ringing check failed.")
- return False
-
- ad.ed.clear_events(EventCallStateChanged)
- ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
- if reject is True:
- # Delay between ringing and reject.
- time.sleep(delay_reject)
- is_find = False
- # Loop the call list and find the matched one to disconnect.
- for call in ad.droid.telecomCallGetCallIds():
- if check_phone_number_match(
- get_number_from_tel_uri(get_call_uri(ad, call)),
- incoming_number):
- ad.droid.telecomCallDisconnect(call)
- ad.log.info("Callee reject the call")
- is_find = True
- if is_find is False:
- ad.log.error("Callee did not find matching call to reject.")
- return False
- else:
- # don't reject on callee. Just ignore the incoming call.
- ad.log.info("Callee received incoming call. Ignore it.")
- try:
- ad.ed.wait_for_event(
- EventCallStateChanged,
- is_event_match_for_list,
- timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT,
- field=CallStateContainer.CALL_STATE,
- value_list=[TELEPHONY_STATE_IDLE, TELEPHONY_STATE_OFFHOOK])
- except Empty:
- ad.log.error("No onCallStateChangedIdle event received.")
- return False
- finally:
- ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
- return True
-
-
-def hangup_call(log, ad, is_emergency=False):
- """Hang up ongoing active call.
-
- Args:
- log: log object.
- ad: android device object.
-
- Returns:
- True: if all calls are cleared
- False: for errors
- """
- # short circuit in case no calls are active
- if not ad.droid.telecomIsInCall():
- ad.log.warning("No active call exists.")
- return True
- ad.ed.clear_events(EventCallStateChanged)
- ad.droid.telephonyStartTrackingCallState()
- ad.log.info("Hangup call.")
- if is_emergency:
- for call in ad.droid.telecomCallGetCallIds():
- ad.droid.telecomCallDisconnect(call)
- else:
- ad.droid.telecomEndCall()
-
- try:
- ad.ed.wait_for_event(
- EventCallStateChanged,
- is_event_match,
- timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT,
- field=CallStateContainer.CALL_STATE,
- value=TELEPHONY_STATE_IDLE)
- except Empty:
- ad.log.warning("Call state IDLE event is not received after hang up.")
- finally:
- ad.droid.telephonyStopTrackingCallStateChange()
- if not wait_for_state(ad.droid.telecomIsInCall, False, 15, 1):
- ad.log.error("Telecom is in call, hangup call failed.")
- return False
- return True
-
-
def wait_for_cbrs_data_active_sub_change_event(
ad,
event_tracking_started=False,
@@ -1528,12 +927,6 @@
ad.droid.telephonyStopTrackingDisplayInfoChange()
return -1
-def disconnect_call_by_id(log, ad, call_id):
- """Disconnect call by call id.
- """
- ad.droid.telecomCallDisconnect(call_id)
- return True
-
def _phone_number_remove_prefix(number):
"""Remove the country code and other prefix from the input phone number.
@@ -1604,88 +997,8 @@
return False
-def initiate_call(log,
- ad,
- callee_number,
- emergency=False,
- timeout=MAX_WAIT_TIME_CALL_INITIATION,
- checking_interval=5,
- incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
- video=False,
- voice_type_init=None,
- call_stats_check=False,
- result_info=result_dict,
- nsa_5g_for_stress=False):
- """Make phone call from caller to callee.
-
- Args:
- ad_caller: Caller android device object.
- callee_number: Callee phone number.
- emergency : specify the call is emergency.
- Optional. Default value is False.
- incall_ui_display: show the dialer UI foreground or backgroud
- video: whether to initiate as video call
-
- Returns:
- result: if phone call is placed successfully.
- """
- ad.ed.clear_events(EventCallStateChanged)
- sub_id = get_outgoing_voice_sub_id(ad)
- begin_time = get_device_epoch_time(ad)
- ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
- try:
- # Make a Call
- ad.log.info("Make a phone call to %s", callee_number)
- if emergency:
- ad.droid.telecomCallEmergencyNumber(callee_number)
- else:
- ad.droid.telecomCallNumber(callee_number, video)
-
- # Verify OFFHOOK state
- if not wait_for_call_offhook_for_subscription(
- log, ad, sub_id, event_tracking_started=True):
- ad.log.info("sub_id %s not in call offhook state", sub_id)
- last_call_drop_reason(ad, begin_time=begin_time)
- return False
- else:
- return True
-
- if call_stats_check:
- voice_type_in_call = ad.droid.telephonyGetCurrentVoiceNetworkType()
- phone_call_type = check_call_status(ad,
- voice_type_init,
- voice_type_in_call)
- result_info["Call Stats"] = phone_call_type
- ad.log.debug("Voice Call Type: %s", phone_call_type)
-
- finally:
- if hasattr(ad, "sdm_log") and getattr(ad, "sdm_log"):
- ad.adb.shell("i2cset -fy 3 64 6 1 b", ignore_status=True)
- ad.adb.shell("i2cset -fy 3 65 6 1 b", ignore_status=True)
- ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
-
- if nsa_5g_for_stress:
- if not is_current_network_5g_nsa(ad):
- ad.log.error("Phone is not attached on 5G NSA")
-
- if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
- ad.droid.telecomShowInCallScreen()
- elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
- ad.droid.showHomeScreen()
-
-
-def dial_phone_number(ad, callee_number):
- for number in str(callee_number):
- if number == "#":
- ad.send_keycode("POUND")
- elif number == "*":
- ad.send_keycode("STAR")
- elif number in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]:
- ad.send_keycode("%s" % number)
-
-
def get_call_state_by_adb(ad):
- slot_index_of_default_voice_subid = get_slot_index_from_subid(ad.log, ad,
+ slot_index_of_default_voice_subid = get_slot_index_from_subid(ad,
get_incoming_voice_sub_id(ad))
output = ad.adb.shell("dumpsys telephony.registry | grep mCallState")
if "mCallState" in output:
@@ -1712,78 +1025,6 @@
return re.search(r"mCallIncomingNumber=(.*)", output).group(1)
-def emergency_dialer_call_by_keyevent(ad, callee_number):
- for i in range(3):
- if "EmergencyDialer" in ad.get_my_current_focus_window():
- ad.log.info("EmergencyDialer is the current focus window")
- break
- elif i <= 2:
- ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL")
- time.sleep(1)
- else:
- ad.log.error("Unable to bring up EmergencyDialer")
- return False
- ad.log.info("Make a phone call to %s", callee_number)
- dial_phone_number(ad, callee_number)
- ad.send_keycode("CALL")
-
-
-def initiate_emergency_dialer_call_by_adb(
- log,
- ad,
- callee_number,
- timeout=MAX_WAIT_TIME_CALL_INITIATION,
- checking_interval=5):
- """Make emergency call by EmergencyDialer.
-
- Args:
- ad: Caller android device object.
- callee_number: Callee phone number.
- emergency : specify the call is emergency.
- Optional. Default value is False.
-
- Returns:
- result: if phone call is placed successfully.
- """
- try:
- # Make a Call
- ad.wakeup_screen()
- ad.send_keycode("MENU")
- ad.log.info("Call %s", callee_number)
- ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL")
- ad.adb.shell(
- "am start -a android.intent.action.CALL_EMERGENCY -d tel:%s" %
- callee_number)
- if not timeout: return True
- ad.log.info("Check call state")
- # Verify Call State
- elapsed_time = 0
- while elapsed_time < timeout:
- time.sleep(checking_interval)
- elapsed_time += checking_interval
- if check_call_state_connected_by_adb(ad):
- ad.log.info("Call to %s is connected", callee_number)
- return True
- if check_call_state_idle_by_adb(ad):
- ad.log.info("Call to %s failed", callee_number)
- return False
- ad.log.info("Make call to %s failed", callee_number)
- return False
- except Exception as e:
- ad.log.error("initiate emergency call failed with error %s", e)
-
-
-def hangup_call_by_adb(ad):
- """Make emergency call by EmergencyDialer.
-
- Args:
- ad: Caller android device object.
- callee_number: Callee phone number.
- """
- ad.log.info("End call by adb")
- ad.send_keycode("ENDCALL")
-
-
def dumpsys_all_call_info(ad):
""" Get call information by dumpsys telecom. """
output = ad.adb.shell("dumpsys telecom")
@@ -1807,49 +1048,6 @@
return calls_info
-def dumpsys_last_call_info(ad):
- """ Get call information by dumpsys telecom. """
- num = dumpsys_last_call_number(ad)
- output = ad.adb.shell("dumpsys telecom")
- result = re.search(r"Call TC@%s: {(.*?)}" % num, output, re.DOTALL)
- call_info = {"TC": num}
- if result:
- result = result.group(1)
- for attr in ("startTime", "endTime", "direction", "isInterrupted",
- "callTechnologies", "callTerminationsReason",
- "isVideoCall", "callProperties"):
- match = re.search(r"%s: (.*)" % attr, result)
- if match:
- if attr in ("startTime", "endTime"):
- call_info[attr] = epoch_to_log_line_timestamp(
- int(match.group(1)))
- else:
- call_info[attr] = match.group(1)
- ad.log.debug("call_info = %s", call_info)
- return call_info
-
-
-def dumpsys_last_call_number(ad):
- output = ad.adb.shell("dumpsys telecom")
- call_nums = re.findall("Call TC@(\d+):", output)
- if not call_nums:
- return 0
- else:
- return int(call_nums[-1])
-
-
-def dumpsys_new_call_info(ad, last_tc_number, retries=3, interval=5):
- for i in range(retries):
- if dumpsys_last_call_number(ad) > last_tc_number:
- call_info = dumpsys_last_call_info(ad)
- ad.log.info("New call info = %s", sorted(call_info.items()))
- return call_info
- else:
- time.sleep(interval)
- ad.log.error("New call is not in sysdump telecom")
- return {}
-
-
def dumpsys_carrier_config(ad):
output = ad.adb.shell("dumpsys carrier_config").split("\n")
output_phone_id_0 = []
@@ -2006,1602 +1204,6 @@
return False
-def call_reject(log, ad_caller, ad_callee, reject=True):
- """Caller call Callee, then reject on callee.
-
-
- """
- subid_caller = ad_caller.droid.subscriptionGetDefaultVoiceSubId()
- subid_callee = ad_callee.incoming_voice_sub_id
- ad_caller.log.info("Sub-ID Caller %s, Sub-ID Callee %s", subid_caller,
- subid_callee)
- return call_reject_for_subscription(log, ad_caller, ad_callee,
- subid_caller, subid_callee, reject)
-
-
-def call_reject_for_subscription(log,
- ad_caller,
- ad_callee,
- subid_caller,
- subid_callee,
- reject=True):
- """
- """
-
- caller_number = ad_caller.telephony['subscription'][subid_caller][
- 'phone_num']
- callee_number = ad_callee.telephony['subscription'][subid_callee][
- 'phone_num']
-
- ad_caller.log.info("Call from %s to %s", caller_number, callee_number)
- if not initiate_call(log, ad_caller, callee_number):
- ad_caller.log.error("Initiate call failed")
- return False
-
- if not wait_and_reject_call_for_subscription(
- log, ad_callee, subid_callee, caller_number, WAIT_TIME_REJECT_CALL,
- reject):
- ad_callee.log.error("Reject call fail.")
- return False
- # Check if incoming call is cleared on callee or not.
- if ad_callee.droid.telephonyGetCallStateForSubscription(
- subid_callee) == TELEPHONY_STATE_RINGING:
- ad_callee.log.error("Incoming call is not cleared")
- return False
- # Hangup on caller
- hangup_call(log, ad_caller)
- return True
-
-
-def call_reject_leave_message(log,
- ad_caller,
- ad_callee,
- verify_caller_func=None,
- wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL):
- """On default voice subscription, Call from caller to callee,
- reject on callee, caller leave a voice mail.
-
- 1. Caller call Callee.
- 2. Callee reject incoming call.
- 3. Caller leave a voice mail.
- 4. Verify callee received the voice mail notification.
-
- Args:
- ad_caller: caller android device object.
- ad_callee: callee android device object.
- verify_caller_func: function to verify caller is in correct state while in-call.
- This is optional, default is None.
- wait_time_in_call: time to wait when leaving a voice mail.
- This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL
-
- Returns:
- True: if voice message is received on callee successfully.
- False: for errors
- """
- subid_caller = get_outgoing_voice_sub_id(ad_caller)
- subid_callee = get_incoming_voice_sub_id(ad_callee)
- return call_reject_leave_message_for_subscription(
- log, ad_caller, ad_callee, subid_caller, subid_callee,
- verify_caller_func, wait_time_in_call)
-
-
-def check_reject_needed_for_voice_mail(log, ad_callee):
- """Check if the carrier requires reject call to receive voice mail or just keep ringing
- Requested in b//155935290
- Four Japan carriers do not need to reject
- SBM, KDDI, Ntt Docomo, Rakuten
- Args:
- log: log object
- ad_callee: android device object
- Returns:
- True if callee's carrier is not one of the four Japan carriers
- False if callee's carrier is one of the four Japan carriers
- """
-
- operators_no_reject = [CARRIER_NTT_DOCOMO,
- CARRIER_KDDI,
- CARRIER_RAKUTEN,
- CARRIER_SBM]
- operator_name = get_operator_name(log, ad_callee)
-
- return operator_name not in operators_no_reject
-
-
-def call_reject_leave_message_for_subscription(
- log,
- ad_caller,
- ad_callee,
- subid_caller,
- subid_callee,
- verify_caller_func=None,
- wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL):
- """On specific voice subscription, Call from caller to callee,
- reject on callee, caller leave a voice mail.
-
- 1. Caller call Callee.
- 2. Callee reject incoming call.
- 3. Caller leave a voice mail.
- 4. Verify callee received the voice mail notification.
-
- Args:
- ad_caller: caller android device object.
- ad_callee: callee android device object.
- subid_caller: caller's subscription id.
- subid_callee: callee's subscription id.
- verify_caller_func: function to verify caller is in correct state while in-call.
- This is optional, default is None.
- wait_time_in_call: time to wait when leaving a voice mail.
- This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL
-
- Returns:
- True: if voice message is received on callee successfully.
- False: for errors
- """
-
- # Currently this test utility only works for TMO and ATT and SPT.
- # It does not work for VZW (see b/21559800)
- # "with VVM TelephonyManager APIs won't work for vm"
-
- caller_number = ad_caller.telephony['subscription'][subid_caller][
- 'phone_num']
- callee_number = ad_callee.telephony['subscription'][subid_callee][
- 'phone_num']
-
- ad_caller.log.info("Call from %s to %s", caller_number, callee_number)
-
- try:
- voice_mail_count_before = ad_callee.droid.telephonyGetVoiceMailCountForSubscription(
- subid_callee)
- ad_callee.log.info("voice mail count is %s", voice_mail_count_before)
- # -1 means there are unread voice mail, but the count is unknown
- # 0 means either this API not working (VZW) or no unread voice mail.
- if voice_mail_count_before != 0:
- log.warning("--Pending new Voice Mail, please clear on phone.--")
-
- if not initiate_call(log, ad_caller, callee_number):
- ad_caller.log.error("Initiate call failed.")
- return False
- if check_reject_needed_for_voice_mail(log, ad_callee):
- carrier_specific_delay_reject = 30
- else:
- carrier_specific_delay_reject = 2
- carrier_reject_call = not check_reject_needed_for_voice_mail(log, ad_callee)
-
- if not wait_and_reject_call_for_subscription(
- log, ad_callee, subid_callee, incoming_number=caller_number, delay_reject=carrier_specific_delay_reject,
- reject=carrier_reject_call):
- ad_callee.log.error("Reject call fail.")
- return False
-
- ad_callee.droid.telephonyStartTrackingVoiceMailStateChangeForSubscription(
- subid_callee)
-
- # ensure that all internal states are updated in telecom
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ad_callee.ed.clear_events(EventCallStateChanged)
-
- if verify_caller_func and not verify_caller_func(log, ad_caller):
- ad_caller.log.error("Caller not in correct state!")
- return False
-
- # TODO: b/26293512 Need to play some sound to leave message.
- # Otherwise carrier voice mail server may drop this voice mail.
- time.sleep(wait_time_in_call)
-
- if not verify_caller_func:
- caller_state_result = ad_caller.droid.telecomIsInCall()
- else:
- caller_state_result = verify_caller_func(log, ad_caller)
- if not caller_state_result:
- ad_caller.log.error("Caller not in correct state after %s seconds",
- wait_time_in_call)
-
- if not hangup_call(log, ad_caller):
- ad_caller.log.error("Error in Hanging-Up Call")
- return False
-
- ad_callee.log.info("Wait for voice mail indicator on callee.")
- try:
- event = ad_callee.ed.wait_for_event(
- EventMessageWaitingIndicatorChanged,
- _is_on_message_waiting_event_true)
- ad_callee.log.info("Got event %s", event)
- except Empty:
- ad_callee.log.warning("No expected event %s",
- EventMessageWaitingIndicatorChanged)
- return False
- voice_mail_count_after = ad_callee.droid.telephonyGetVoiceMailCountForSubscription(
- subid_callee)
- ad_callee.log.info(
- "telephonyGetVoiceMailCount output - before: %s, after: %s",
- voice_mail_count_before, voice_mail_count_after)
-
- # voice_mail_count_after should:
- # either equals to (voice_mail_count_before + 1) [For ATT and SPT]
- # or equals to -1 [For TMO]
- # -1 means there are unread voice mail, but the count is unknown
- if not check_voice_mail_count(log, ad_callee, voice_mail_count_before,
- voice_mail_count_after):
- log.error("before and after voice mail count is not incorrect.")
- return False
- finally:
- ad_callee.droid.telephonyStopTrackingVoiceMailStateChangeForSubscription(
- subid_callee)
- return True
-
-
-def call_voicemail_erase_all_pending_voicemail(log, ad):
- """Script for phone to erase all pending voice mail.
- This script only works for TMO and ATT and SPT currently.
- This script only works if phone have already set up voice mail options,
- and phone should disable password protection for voice mail.
-
- 1. If phone don't have pending voice message, return True.
- 2. Dial voice mail number.
- For TMO, the number is '123'
- For ATT, the number is phone's number
- For SPT, the number is phone's number
- 3. Wait for voice mail connection setup.
- 4. Wait for voice mail play pending voice message.
- 5. Send DTMF to delete one message.
- The digit is '7'.
- 6. Repeat steps 4 and 5 until voice mail server drop this call.
- (No pending message)
- 6. Check telephonyGetVoiceMailCount result. it should be 0.
-
- Args:
- log: log object
- ad: android device object
- Returns:
- False if error happens. True is succeed.
- """
- log.info("Erase all pending voice mail.")
- count = ad.droid.telephonyGetVoiceMailCount()
- if count == 0:
- ad.log.info("No Pending voice mail.")
- return True
- if count == -1:
- ad.log.info("There is pending voice mail, but the count is unknown")
- count = MAX_SAVED_VOICE_MAIL
- else:
- ad.log.info("There are %s voicemails", count)
-
- voice_mail_number = get_voice_mail_number(log, ad)
- delete_digit = get_voice_mail_delete_digit(get_operator_name(log, ad))
- if not initiate_call(log, ad, voice_mail_number):
- log.error("Initiate call to voice mail failed.")
- return False
- time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
- callId = ad.droid.telecomCallGetCallIds()[0]
- time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
- while (is_phone_in_call(log, ad) and (count > 0)):
- ad.log.info("Press %s to delete voice mail.", delete_digit)
- ad.droid.telecomCallPlayDtmfTone(callId, delete_digit)
- ad.droid.telecomCallStopDtmfTone(callId)
- time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
- count -= 1
- if is_phone_in_call(log, ad):
- hangup_call(log, ad)
-
- # wait for telephonyGetVoiceMailCount to update correct result
- remaining_time = MAX_WAIT_TIME_VOICE_MAIL_COUNT
- while ((remaining_time > 0)
- and (ad.droid.telephonyGetVoiceMailCount() != 0)):
- time.sleep(1)
- remaining_time -= 1
- current_voice_mail_count = ad.droid.telephonyGetVoiceMailCount()
- ad.log.info("telephonyGetVoiceMailCount: %s", current_voice_mail_count)
- return (current_voice_mail_count == 0)
-
-
-def _is_on_message_waiting_event_true(event):
- """Private function to return if the received EventMessageWaitingIndicatorChanged
- event MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING field is True.
- """
- return event['data'][MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING]
-
-
-def call_setup_teardown(log,
- ad_caller,
- ad_callee,
- ad_hangup=None,
- verify_caller_func=None,
- verify_callee_func=None,
- wait_time_in_call=WAIT_TIME_IN_CALL,
- incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
- dialing_number_length=None,
- video_state=None,
- slot_id_callee=None,
- voice_type_init=None,
- call_stats_check=False,
- result_info=result_dict,
- nsa_5g_for_stress=False):
- """ Call process, including make a phone call from caller,
- accept from callee, and hang up. The call is on default voice subscription
-
- In call process, call from <droid_caller> to <droid_callee>,
- accept the call, (optional)then hang up from <droid_hangup>.
-
- Args:
- ad_caller: Caller Android Device Object.
- ad_callee: Callee Android Device Object.
- ad_hangup: Android Device Object end the phone call.
- Optional. Default value is None, and phone call will continue.
- verify_call_mode_caller: func_ptr to verify caller in correct mode
- Optional. Default is None
- verify_call_mode_caller: func_ptr to verify caller in correct mode
- Optional. Default is None
- incall_ui_display: after answer the call, bring in-call UI to foreground or
- background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
- if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
- if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
- else, do nothing.
- dialing_number_length: the number of digits used for dialing
- slot_id_callee : the slot if of the callee to call to
-
- Returns:
- True if call process without any error.
- False if error happened.
-
- """
- subid_caller = get_outgoing_voice_sub_id(ad_caller)
- if slot_id_callee is None:
- subid_callee = get_incoming_voice_sub_id(ad_callee)
- else:
- subid_callee = get_subid_from_slot_index(log, ad_callee, slot_id_callee)
-
- return call_setup_teardown_for_subscription(
- log, ad_caller, ad_callee, subid_caller, subid_callee, ad_hangup,
- verify_caller_func, verify_callee_func, wait_time_in_call,
- incall_ui_display, dialing_number_length, video_state,
- voice_type_init, call_stats_check, result_info, nsa_5g_for_stress)
-
-
-
-def call_setup_teardown_for_subscription(
- log,
- ad_caller,
- ad_callee,
- subid_caller,
- subid_callee,
- ad_hangup=None,
- verify_caller_func=None,
- verify_callee_func=None,
- wait_time_in_call=WAIT_TIME_IN_CALL,
- incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
- dialing_number_length=None,
- video_state=None,
- voice_type_init=None,
- call_stats_check=False,
- result_info=result_dict,
- nsa_5g_for_stress=False):
- """ Call process, including make a phone call from caller,
- accept from callee, and hang up. The call is on specified subscription
-
- In call process, call from <droid_caller> to <droid_callee>,
- accept the call, (optional)then hang up from <droid_hangup>.
-
- Args:
- ad_caller: Caller Android Device Object.
- ad_callee: Callee Android Device Object.
- subid_caller: Caller subscription ID
- subid_callee: Callee subscription ID
- ad_hangup: Android Device Object end the phone call.
- Optional. Default value is None, and phone call will continue.
- verify_call_mode_caller: func_ptr to verify caller in correct mode
- Optional. Default is None
- verify_call_mode_caller: func_ptr to verify caller in correct mode
- Optional. Default is None
- incall_ui_display: after answer the call, bring in-call UI to foreground or
- background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
- if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
- if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
- else, do nothing.
-
- Returns:
- TelResultWrapper which will evaluate as False if error.
-
- """
- CHECK_INTERVAL = 5
- begin_time = get_current_epoch_time()
- if not verify_caller_func:
- verify_caller_func = is_phone_in_call
- if not verify_callee_func:
- verify_callee_func = is_phone_in_call
-
- caller_number = ad_caller.telephony['subscription'][subid_caller][
- 'phone_num']
- callee_number = ad_callee.telephony['subscription'][subid_callee][
- 'phone_num']
- if dialing_number_length:
- skip_test = False
- trunc_position = 0 - int(dialing_number_length)
- try:
- caller_area_code = caller_number[:trunc_position]
- callee_area_code = callee_number[:trunc_position]
- callee_dial_number = callee_number[trunc_position:]
- except:
- skip_test = True
- if caller_area_code != callee_area_code:
- skip_test = True
- if skip_test:
- msg = "Cannot make call from %s to %s by %s digits" % (
- caller_number, callee_number, dialing_number_length)
- ad_caller.log.info(msg)
- raise signals.TestSkip(msg)
- else:
- callee_number = callee_dial_number
-
- tel_result_wrapper = TelResultWrapper(CallResult('SUCCESS'))
- msg = "Call from %s to %s" % (caller_number, callee_number)
- if video_state:
- msg = "Video %s" % msg
- video = True
- else:
- video = False
- if ad_hangup:
- msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
- ad_caller.log.info(msg)
-
- for ad in (ad_caller, ad_callee):
- call_ids = ad.droid.telecomCallGetCallIds()
- setattr(ad, "call_ids", call_ids)
- if call_ids:
- ad.log.info("Pre-exist CallId %s before making call", call_ids)
- try:
- if not initiate_call(
- log,
- ad_caller,
- callee_number,
- incall_ui_display=incall_ui_display,
- video=video):
- ad_caller.log.error("Initiate call failed.")
- tel_result_wrapper.result_value = CallResult('INITIATE_FAILED')
- return tel_result_wrapper
- else:
- ad_caller.log.info("Caller initate call successfully")
- if not wait_and_answer_call_for_subscription(
- log,
- ad_callee,
- subid_callee,
- incoming_number=caller_number,
- caller=ad_caller,
- incall_ui_display=incall_ui_display,
- video_state=video_state):
- ad_callee.log.error("Answer call fail.")
- tel_result_wrapper.result_value = CallResult(
- 'NO_RING_EVENT_OR_ANSWER_FAILED')
- return tel_result_wrapper
- else:
- ad_callee.log.info("Callee answered the call successfully")
-
- for ad, call_func in zip([ad_caller, ad_callee],
- [verify_caller_func, verify_callee_func]):
- call_ids = ad.droid.telecomCallGetCallIds()
- new_call_ids = set(call_ids) - set(ad.call_ids)
- if not new_call_ids:
- ad.log.error(
- "No new call ids are found after call establishment")
- ad.log.error("telecomCallGetCallIds returns %s",
- ad.droid.telecomCallGetCallIds())
- tel_result_wrapper.result_value = CallResult('NO_CALL_ID_FOUND')
- for new_call_id in new_call_ids:
- if not wait_for_in_call_active(ad, call_id=new_call_id):
- tel_result_wrapper.result_value = CallResult(
- 'CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT')
- else:
- ad.log.info("callProperties = %s",
- ad.droid.telecomCallGetProperties(new_call_id))
-
- if not ad.droid.telecomCallGetAudioState():
- ad.log.error("Audio is not in call state")
- tel_result_wrapper.result_value = CallResult(
- 'AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT')
-
- if call_func(log, ad):
- ad.log.info("Call is in %s state", call_func.__name__)
- else:
- ad.log.error("Call is not in %s state, voice in RAT %s",
- call_func.__name__,
- ad.droid.telephonyGetCurrentVoiceNetworkType())
- tel_result_wrapper.result_value = CallResult(
- 'CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT')
- if not tel_result_wrapper:
- return tel_result_wrapper
-
- if call_stats_check:
- voice_type_in_call = check_voice_network_type([ad_caller, ad_callee], voice_init=False)
- phone_a_call_type = check_call_status(ad_caller,
- voice_type_init[0],
- voice_type_in_call[0])
- result_info["Call Stats"] = phone_a_call_type
- ad_caller.log.debug("Voice Call Type: %s", phone_a_call_type)
- phone_b_call_type = check_call_status(ad_callee,
- voice_type_init[1],
- voice_type_in_call[1])
- result_info["Call Stats"] = phone_b_call_type
- ad_callee.log.debug("Voice Call Type: %s", phone_b_call_type)
-
- elapsed_time = 0
- while (elapsed_time < wait_time_in_call):
- CHECK_INTERVAL = min(CHECK_INTERVAL,
- wait_time_in_call - elapsed_time)
- time.sleep(CHECK_INTERVAL)
- elapsed_time += CHECK_INTERVAL
- time_message = "at <%s>/<%s> second." % (elapsed_time,
- wait_time_in_call)
- for ad, call_func in [(ad_caller, verify_caller_func),
- (ad_callee, verify_callee_func)]:
- if not call_func(log, ad):
- ad.log.error(
- "NOT in correct %s state at %s, voice in RAT %s",
- call_func.__name__, time_message,
- ad.droid.telephonyGetCurrentVoiceNetworkType())
- tel_result_wrapper.result_value = CallResult(
- 'CALL_DROP_OR_WRONG_STATE_AFTER_CONNECTED')
- else:
- ad.log.info("In correct %s state at %s",
- call_func.__name__, time_message)
- if not ad.droid.telecomCallGetAudioState():
- ad.log.error("Audio is not in call state at %s",
- time_message)
- tel_result_wrapper.result_value = CallResult(
- 'AUDIO_STATE_NOT_INCALL_AFTER_CONNECTED')
- if not tel_result_wrapper:
- return tel_result_wrapper
-
- if ad_hangup:
- if not hangup_call(log, ad_hangup):
- ad_hangup.log.info("Failed to hang up the call")
- tel_result_wrapper.result_value = CallResult('CALL_HANGUP_FAIL')
- return tel_result_wrapper
- finally:
- if not tel_result_wrapper:
- for ad in (ad_caller, ad_callee):
- last_call_drop_reason(ad, begin_time)
- try:
- if ad.droid.telecomIsInCall():
- ad.log.info("In call. End now.")
- ad.droid.telecomEndCall()
- except Exception as e:
- log.error(str(e))
-
- if nsa_5g_for_stress:
- for ad in (ad_caller, ad_callee):
- if not is_current_network_5g_nsa(ad):
- ad.log.error("Phone not attached on 5G NSA")
-
- if ad_hangup or not tel_result_wrapper:
- for ad in (ad_caller, ad_callee):
- if not wait_for_call_id_clearing(
- ad, getattr(ad, "caller_ids", [])):
- tel_result_wrapper.result_value = CallResult(
- 'CALL_ID_CLEANUP_FAIL')
- return tel_result_wrapper
-
-
-def call_setup_teardown_for_call_forwarding(
- log,
- ad_caller,
- ad_callee,
- forwarded_callee,
- ad_hangup=None,
- verify_callee_func=None,
- verify_after_cf_disabled=None,
- wait_time_in_call=WAIT_TIME_IN_CALL,
- incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
- dialing_number_length=None,
- video_state=None,
- call_forwarding_type="unconditional"):
- """ Call process for call forwarding, including make a phone call from
- caller, forward from callee, accept from the forwarded callee and hang up.
- The call is on default voice subscription
-
- In call process, call from <ad_caller> to <ad_callee>, forwarded to
- <forwarded_callee>, accept the call, (optional) and then hang up from
- <ad_hangup>.
-
- Args:
- ad_caller: Caller Android Device Object.
- ad_callee: Callee Android Device Object which forwards the call.
- forwarded_callee: Callee Android Device Object which answers the call.
- ad_hangup: Android Device Object end the phone call.
- Optional. Default value is None, and phone call will continue.
- verify_callee_func: func_ptr to verify callee in correct mode
- Optional. Default is None
- verify_after_cf_disabled: If True the test of disabling call forwarding
- will be appended.
- wait_time_in_call: the call duration of a connected call
- incall_ui_display: after answer the call, bring in-call UI to foreground
- or background.
- Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
- if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
- if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
- else, do nothing.
- dialing_number_length: the number of digits used for dialing
- video_state: video call or voice call. Default is voice call.
- call_forwarding_type: type of call forwarding listed below:
- - unconditional
- - busy
- - not_answered
- - not_reachable
-
- Returns:
- True if call process without any error.
- False if error happened.
-
- """
- subid_caller = get_outgoing_voice_sub_id(ad_caller)
- subid_callee = get_incoming_voice_sub_id(ad_callee)
- subid_forwarded_callee = get_incoming_voice_sub_id(forwarded_callee)
- return call_setup_teardown_for_call_forwarding_for_subscription(
- log,
- ad_caller,
- ad_callee,
- forwarded_callee,
- subid_caller,
- subid_callee,
- subid_forwarded_callee,
- ad_hangup,
- verify_callee_func,
- wait_time_in_call,
- incall_ui_display,
- dialing_number_length,
- video_state,
- call_forwarding_type,
- verify_after_cf_disabled)
-
-
-def call_setup_teardown_for_call_forwarding_for_subscription(
- log,
- ad_caller,
- ad_callee,
- forwarded_callee,
- subid_caller,
- subid_callee,
- subid_forwarded_callee,
- ad_hangup=None,
- verify_callee_func=None,
- wait_time_in_call=WAIT_TIME_IN_CALL,
- incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
- dialing_number_length=None,
- video_state=None,
- call_forwarding_type="unconditional",
- verify_after_cf_disabled=None):
- """ Call process for call forwarding, including make a phone call from caller,
- forward from callee, accept from the forwarded callee and hang up.
- The call is on specified subscription
-
- In call process, call from <ad_caller> to <ad_callee>, forwarded to
- <forwarded_callee>, accept the call, (optional) and then hang up from
- <ad_hangup>.
-
- Args:
- ad_caller: Caller Android Device Object.
- ad_callee: Callee Android Device Object which forwards the call.
- forwarded_callee: Callee Android Device Object which answers the call.
- subid_caller: Caller subscription ID
- subid_callee: Callee subscription ID
- subid_forwarded_callee: Forwarded callee subscription ID
- ad_hangup: Android Device Object end the phone call.
- Optional. Default value is None, and phone call will continue.
- verify_callee_func: func_ptr to verify callee in correct mode
- Optional. Default is None
- wait_time_in_call: the call duration of a connected call
- incall_ui_display: after answer the call, bring in-call UI to foreground
- or background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
- if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
- if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
- else, do nothing.
- dialing_number_length: the number of digits used for dialing
- video_state: video call or voice call. Default is voice call.
- call_forwarding_type: type of call forwarding listed below:
- - unconditional
- - busy
- - not_answered
- - not_reachable
- verify_after_cf_disabled: If True the call forwarding will not be
- enabled. This argument is used to verify if the call can be received
- successfully after call forwarding was disabled.
-
- Returns:
- True if call process without any error.
- False if error happened.
-
- """
- CHECK_INTERVAL = 5
- begin_time = get_current_epoch_time()
- verify_caller_func = is_phone_in_call
- if not verify_callee_func:
- verify_callee_func = is_phone_in_call
- verify_forwarded_callee_func = is_phone_in_call
-
- caller_number = ad_caller.telephony['subscription'][subid_caller][
- 'phone_num']
- callee_number = ad_callee.telephony['subscription'][subid_callee][
- 'phone_num']
- forwarded_callee_number = forwarded_callee.telephony['subscription'][
- subid_forwarded_callee]['phone_num']
-
- if dialing_number_length:
- skip_test = False
- trunc_position = 0 - int(dialing_number_length)
- try:
- caller_area_code = caller_number[:trunc_position]
- callee_area_code = callee_number[:trunc_position]
- callee_dial_number = callee_number[trunc_position:]
- except:
- skip_test = True
- if caller_area_code != callee_area_code:
- skip_test = True
- if skip_test:
- msg = "Cannot make call from %s to %s by %s digits" % (
- caller_number, callee_number, dialing_number_length)
- ad_caller.log.info(msg)
- raise signals.TestSkip(msg)
- else:
- callee_number = callee_dial_number
-
- result = True
- msg = "Call from %s to %s (forwarded to %s)" % (
- caller_number, callee_number, forwarded_callee_number)
- if video_state:
- msg = "Video %s" % msg
- video = True
- else:
- video = False
- if ad_hangup:
- msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
- ad_caller.log.info(msg)
-
- for ad in (ad_caller, forwarded_callee):
- call_ids = ad.droid.telecomCallGetCallIds()
- setattr(ad, "call_ids", call_ids)
- if call_ids:
- ad.log.info("Pre-exist CallId %s before making call", call_ids)
-
- if not verify_after_cf_disabled:
- if not set_call_forwarding_by_mmi(
- log,
- ad_callee,
- forwarded_callee,
- call_forwarding_type=call_forwarding_type):
- raise signals.TestFailure(
- "Failed to register or activate call forwarding.",
- extras={"fail_reason": "Failed to register or activate call"
- " forwarding."})
-
- if call_forwarding_type == "not_reachable":
- if not toggle_airplane_mode_msim(
- log,
- ad_callee,
- new_state=True,
- strict_checking=True):
- return False
-
- if call_forwarding_type == "busy":
- ad_callee.log.info("Callee is making a phone call to 0000000000 to make"
- " itself busy.")
- ad_callee.droid.telecomCallNumber("0000000000", False)
- time.sleep(2)
-
- if check_call_state_idle_by_adb(ad_callee):
- ad_callee.log.error("Call state of the callee is idle.")
- if not verify_after_cf_disabled:
- erase_call_forwarding_by_mmi(
- log,
- ad_callee,
- call_forwarding_type=call_forwarding_type)
- return False
-
- try:
- if not initiate_call(
- log,
- ad_caller,
- callee_number,
- incall_ui_display=incall_ui_display,
- video=video):
-
- ad_caller.log.error("Caller failed to initiate the call.")
- result = False
-
- if call_forwarding_type == "not_reachable":
- if toggle_airplane_mode_msim(
- log,
- ad_callee,
- new_state=False,
- strict_checking=True):
- time.sleep(10)
- elif call_forwarding_type == "busy":
- hangup_call(log, ad_callee)
-
- if not verify_after_cf_disabled:
- erase_call_forwarding_by_mmi(
- log,
- ad_callee,
- call_forwarding_type=call_forwarding_type)
- return False
- else:
- ad_caller.log.info("Caller initated the call successfully.")
-
- if call_forwarding_type == "not_answered":
- if not wait_for_ringing_call_for_subscription(
- log,
- ad_callee,
- subid_callee,
- incoming_number=caller_number,
- caller=ad_caller,
- event_tracking_started=True):
- ad.log.info("Incoming call ringing check failed.")
- return False
-
- _timeout = 30
- while check_call_state_ring_by_adb(ad_callee) == 1 and _timeout >= 0:
- time.sleep(1)
- _timeout = _timeout - 1
-
- if not wait_and_answer_call_for_subscription(
- log,
- forwarded_callee,
- subid_forwarded_callee,
- incoming_number=caller_number,
- caller=ad_caller,
- incall_ui_display=incall_ui_display,
- video_state=video_state):
-
- if not verify_after_cf_disabled:
- forwarded_callee.log.error("Forwarded callee failed to receive"
- "or answer the call.")
- result = False
- else:
- forwarded_callee.log.info("Forwarded callee did not receive or"
- " answer the call.")
-
- if call_forwarding_type == "not_reachable":
- if toggle_airplane_mode_msim(
- log,
- ad_callee,
- new_state=False,
- strict_checking=True):
- time.sleep(10)
- elif call_forwarding_type == "busy":
- hangup_call(log, ad_callee)
-
- if not verify_after_cf_disabled:
- erase_call_forwarding_by_mmi(
- log,
- ad_callee,
- call_forwarding_type=call_forwarding_type)
- return False
-
- else:
- if not verify_after_cf_disabled:
- forwarded_callee.log.info("Forwarded callee answered the call"
- " successfully.")
- else:
- forwarded_callee.log.error("Forwarded callee should not be able"
- " to answer the call.")
- hangup_call(log, ad_caller)
- result = False
-
- for ad, subid, call_func in zip(
- [ad_caller, forwarded_callee],
- [subid_caller, subid_forwarded_callee],
- [verify_caller_func, verify_forwarded_callee_func]):
- call_ids = ad.droid.telecomCallGetCallIds()
- new_call_ids = set(call_ids) - set(ad.call_ids)
- if not new_call_ids:
- if not verify_after_cf_disabled:
- ad.log.error(
- "No new call ids are found after call establishment")
- ad.log.error("telecomCallGetCallIds returns %s",
- ad.droid.telecomCallGetCallIds())
- result = False
- for new_call_id in new_call_ids:
- if not verify_after_cf_disabled:
- if not wait_for_in_call_active(ad, call_id=new_call_id):
- result = False
- else:
- ad.log.info("callProperties = %s",
- ad.droid.telecomCallGetProperties(new_call_id))
- else:
- ad.log.error("No new call id should be found.")
-
- if not ad.droid.telecomCallGetAudioState():
- if not verify_after_cf_disabled:
- ad.log.error("Audio is not in call state")
- result = False
-
- if call_func(log, ad):
- if not verify_after_cf_disabled:
- ad.log.info("Call is in %s state", call_func.__name__)
- else:
- ad.log.error("Call is in %s state", call_func.__name__)
- else:
- if not verify_after_cf_disabled:
- ad.log.error(
- "Call is not in %s state, voice in RAT %s",
- call_func.__name__,
- ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
- result = False
-
- if not result:
- if call_forwarding_type == "not_reachable":
- if toggle_airplane_mode_msim(
- log,
- ad_callee,
- new_state=False,
- strict_checking=True):
- time.sleep(10)
- elif call_forwarding_type == "busy":
- hangup_call(log, ad_callee)
-
- if not verify_after_cf_disabled:
- erase_call_forwarding_by_mmi(
- log,
- ad_callee,
- call_forwarding_type=call_forwarding_type)
- return False
-
- elapsed_time = 0
- while (elapsed_time < wait_time_in_call):
- CHECK_INTERVAL = min(CHECK_INTERVAL,
- wait_time_in_call - elapsed_time)
- time.sleep(CHECK_INTERVAL)
- elapsed_time += CHECK_INTERVAL
- time_message = "at <%s>/<%s> second." % (elapsed_time,
- wait_time_in_call)
- for ad, subid, call_func in [
- (ad_caller, subid_caller, verify_caller_func),
- (forwarded_callee, subid_forwarded_callee,
- verify_forwarded_callee_func)]:
- if not call_func(log, ad):
- if not verify_after_cf_disabled:
- ad.log.error(
- "NOT in correct %s state at %s, voice in RAT %s",
- call_func.__name__, time_message,
- ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
- result = False
- else:
- if not verify_after_cf_disabled:
- ad.log.info("In correct %s state at %s",
- call_func.__name__, time_message)
- else:
- ad.log.error("In correct %s state at %s",
- call_func.__name__, time_message)
-
- if not ad.droid.telecomCallGetAudioState():
- if not verify_after_cf_disabled:
- ad.log.error("Audio is not in call state at %s",
- time_message)
- result = False
-
- if not result:
- if call_forwarding_type == "not_reachable":
- if toggle_airplane_mode_msim(
- log,
- ad_callee,
- new_state=False,
- strict_checking=True):
- time.sleep(10)
- elif call_forwarding_type == "busy":
- hangup_call(log, ad_callee)
-
- if not verify_after_cf_disabled:
- erase_call_forwarding_by_mmi(
- log,
- ad_callee,
- call_forwarding_type=call_forwarding_type)
- return False
-
- if ad_hangup:
- if not hangup_call(log, ad_hangup):
- ad_hangup.log.info("Failed to hang up the call")
- result = False
- if call_forwarding_type == "not_reachable":
- if toggle_airplane_mode_msim(
- log,
- ad_callee,
- new_state=False,
- strict_checking=True):
- time.sleep(10)
- elif call_forwarding_type == "busy":
- hangup_call(log, ad_callee)
-
- if not verify_after_cf_disabled:
- erase_call_forwarding_by_mmi(
- log,
- ad_callee,
- call_forwarding_type=call_forwarding_type)
- return False
- finally:
- if not result:
- if verify_after_cf_disabled:
- result = True
- else:
- for ad in (ad_caller, forwarded_callee):
- last_call_drop_reason(ad, begin_time)
- try:
- if ad.droid.telecomIsInCall():
- ad.log.info("In call. End now.")
- ad.droid.telecomEndCall()
- except Exception as e:
- log.error(str(e))
-
- if ad_hangup or not result:
- for ad in (ad_caller, forwarded_callee):
- if not wait_for_call_id_clearing(
- ad, getattr(ad, "caller_ids", [])):
- result = False
-
- if call_forwarding_type == "not_reachable":
- if toggle_airplane_mode_msim(
- log,
- ad_callee,
- new_state=False,
- strict_checking=True):
- time.sleep(10)
- elif call_forwarding_type == "busy":
- hangup_call(log, ad_callee)
-
- if not verify_after_cf_disabled:
- erase_call_forwarding_by_mmi(
- log,
- ad_callee,
- call_forwarding_type=call_forwarding_type)
-
- if not result:
- return result
-
- ad_caller.log.info(
- "Make a normal call to callee to ensure the call can be connected after"
- " call forwarding was disabled")
- return call_setup_teardown_for_subscription(
- log, ad_caller, ad_callee, subid_caller, subid_callee, ad_caller,
- verify_caller_func, verify_callee_func, wait_time_in_call,
- incall_ui_display, dialing_number_length, video_state)
-
-
-def call_setup_teardown_for_call_waiting(log,
- ad_caller,
- ad_callee,
- ad_caller2,
- ad_hangup=None,
- ad_hangup2=None,
- verify_callee_func=None,
- end_first_call_before_answering_second_call=True,
- wait_time_in_call=WAIT_TIME_IN_CALL,
- incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
- dialing_number_length=None,
- video_state=None,
- call_waiting=True):
- """ Call process for call waiting, including make the 1st phone call from
- caller, answer the call by the callee, and receive the 2nd call from the
- caller2. The call is on default voice subscription
-
- In call process, 1st call from <ad_caller> to <ad_callee>, 2nd call from
- <ad_caller2> to <ad_callee>, hang up the existing call or reject the
- incoming call according to the test scenario.
-
- Args:
- ad_caller: Caller Android Device Object.
- ad_callee: Callee Android Device Object.
- ad_caller2: Caller2 Android Device Object.
- ad_hangup: Android Device Object end the 1st phone call.
- Optional. Default value is None, and phone call will continue.
- ad_hangup2: Android Device Object end the 2nd phone call.
- Optional. Default value is None, and phone call will continue.
- verify_callee_func: func_ptr to verify callee in correct mode
- Optional. Default is None
- end_first_call_before_answering_second_call: If True the 2nd call will
- be rejected on the ringing stage.
- wait_time_in_call: the call duration of a connected call
- incall_ui_display: after answer the call, bring in-call UI to foreground
- or background.
- Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
- if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
- if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
- else, do nothing.
- dialing_number_length: the number of digits used for dialing
- video_state: video call or voice call. Default is voice call.
- call_waiting: True to enable call waiting and False to disable.
-
- Returns:
- True if call process without any error.
- False if error happened.
-
- """
- subid_caller = get_outgoing_voice_sub_id(ad_caller)
- subid_callee = get_incoming_voice_sub_id(ad_callee)
- subid_caller2 = get_incoming_voice_sub_id(ad_caller2)
- return call_setup_teardown_for_call_waiting_for_subscription(
- log,
- ad_caller,
- ad_callee,
- ad_caller2,
- subid_caller,
- subid_callee,
- subid_caller2,
- ad_hangup, ad_hangup2,
- verify_callee_func,
- end_first_call_before_answering_second_call,
- wait_time_in_call,
- incall_ui_display,
- dialing_number_length,
- video_state,
- call_waiting)
-
-
-def call_setup_teardown_for_call_waiting_for_subscription(
- log,
- ad_caller,
- ad_callee,
- ad_caller2,
- subid_caller,
- subid_callee,
- subid_caller2,
- ad_hangup=None,
- ad_hangup2=None,
- verify_callee_func=None,
- end_first_call_before_answering_second_call=True,
- wait_time_in_call=WAIT_TIME_IN_CALL,
- incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
- dialing_number_length=None,
- video_state=None,
- call_waiting=True):
- """ Call process for call waiting, including make the 1st phone call from
- caller, answer the call by the callee, and receive the 2nd call from the
- caller2. The call is on specified subscription.
-
- In call process, 1st call from <ad_caller> to <ad_callee>, 2nd call from
- <ad_caller2> to <ad_callee>, hang up the existing call or reject the
- incoming call according to the test scenario.
-
- Args:
- ad_caller: Caller Android Device Object.
- ad_callee: Callee Android Device Object.
- ad_caller2: Caller2 Android Device Object.
- subid_caller: Caller subscription ID.
- subid_callee: Callee subscription ID.
- subid_caller2: Caller2 subscription ID.
- ad_hangup: Android Device Object end the 1st phone call.
- Optional. Default value is None, and phone call will continue.
- ad_hangup2: Android Device Object end the 2nd phone call.
- Optional. Default value is None, and phone call will continue.
- verify_callee_func: func_ptr to verify callee in correct mode
- Optional. Default is None
- end_first_call_before_answering_second_call: If True the 2nd call will
- be rejected on the ringing stage.
- wait_time_in_call: the call duration of a connected call
- incall_ui_display: after answer the call, bring in-call UI to foreground
- or background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
- if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
- if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
- else, do nothing.
- dialing_number_length: the number of digits used for dialing
- video_state: video call or voice call. Default is voice call.
- call_waiting: True to enable call waiting and False to disable.
-
- Returns:
- True if call process without any error.
- False if error happened.
-
- """
-
- CHECK_INTERVAL = 5
- begin_time = get_current_epoch_time()
- verify_caller_func = is_phone_in_call
- if not verify_callee_func:
- verify_callee_func = is_phone_in_call
- verify_caller2_func = is_phone_in_call
-
- caller_number = ad_caller.telephony['subscription'][subid_caller][
- 'phone_num']
- callee_number = ad_callee.telephony['subscription'][subid_callee][
- 'phone_num']
- caller2_number = ad_caller2.telephony['subscription'][subid_caller2][
- 'phone_num']
- if dialing_number_length:
- skip_test = False
- trunc_position = 0 - int(dialing_number_length)
- try:
- caller_area_code = caller_number[:trunc_position]
- callee_area_code = callee_number[:trunc_position]
- callee_dial_number = callee_number[trunc_position:]
- except:
- skip_test = True
- if caller_area_code != callee_area_code:
- skip_test = True
- if skip_test:
- msg = "Cannot make call from %s to %s by %s digits" % (
- caller_number, callee_number, dialing_number_length)
- ad_caller.log.info(msg)
- raise signals.TestSkip(msg)
- else:
- callee_number = callee_dial_number
-
- result = True
- msg = "Call from %s to %s" % (caller_number, callee_number)
- if video_state:
- msg = "Video %s" % msg
- video = True
- else:
- video = False
- if ad_hangup:
- msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
- ad_caller.log.info(msg)
-
- for ad in (ad_caller, ad_callee, ad_caller2):
- call_ids = ad.droid.telecomCallGetCallIds()
- setattr(ad, "call_ids", call_ids)
- if call_ids:
- ad.log.info("Pre-exist CallId %s before making call", call_ids)
-
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=0)
- else:
- set_call_waiting(log, ad_callee, enable=1)
-
- first_call_ids = []
- try:
- if not initiate_call(
- log,
- ad_caller,
- callee_number,
- incall_ui_display=incall_ui_display,
- video=video):
- ad_caller.log.error("Initiate call failed.")
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- result = False
- return False
- else:
- ad_caller.log.info("Caller initate call successfully")
- if not wait_and_answer_call_for_subscription(
- log,
- ad_callee,
- subid_callee,
- incoming_number=caller_number,
- caller=ad_caller,
- incall_ui_display=incall_ui_display,
- video_state=video_state):
- ad_callee.log.error("Answer call fail.")
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- result = False
- return False
- else:
- ad_callee.log.info("Callee answered the call successfully")
-
- for ad, subid, call_func in zip(
- [ad_caller, ad_callee],
- [subid_caller, subid_callee],
- [verify_caller_func, verify_callee_func]):
- call_ids = ad.droid.telecomCallGetCallIds()
- new_call_ids = set(call_ids) - set(ad.call_ids)
- if not new_call_ids:
- ad.log.error(
- "No new call ids are found after call establishment")
- ad.log.error("telecomCallGetCallIds returns %s",
- ad.droid.telecomCallGetCallIds())
- result = False
- for new_call_id in new_call_ids:
- first_call_ids.append(new_call_id)
- if not wait_for_in_call_active(ad, call_id=new_call_id):
- result = False
- else:
- ad.log.info("callProperties = %s",
- ad.droid.telecomCallGetProperties(new_call_id))
-
- if not ad.droid.telecomCallGetAudioState():
- ad.log.error("Audio is not in call state")
- result = False
-
- if call_func(log, ad):
- ad.log.info("Call is in %s state", call_func.__name__)
- else:
- ad.log.error("Call is not in %s state, voice in RAT %s",
- call_func.__name__,
- ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
- result = False
- if not result:
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- return False
-
- time.sleep(3)
- if not call_waiting:
- if not initiate_call(
- log,
- ad_caller2,
- callee_number,
- incall_ui_display=incall_ui_display,
- video=video):
- ad_caller2.log.info("Initiate call failed.")
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- result = False
- return False
- else:
- ad_caller2.log.info("Caller 2 initate 2nd call successfully")
-
- if not wait_and_answer_call_for_subscription(
- log,
- ad_callee,
- subid_callee,
- incoming_number=caller2_number,
- caller=ad_caller2,
- incall_ui_display=incall_ui_display,
- video_state=video_state):
- ad_callee.log.info(
- "Answering 2nd call fail due to call waiting deactivate.")
- else:
- ad_callee.log.error("Callee should not be able to answer the"
- " 2nd call due to call waiting deactivated.")
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- result = False
- return False
-
- time.sleep(3)
- if not hangup_call(log, ad_caller2):
- ad_caller2.log.info("Failed to hang up the 2nd call")
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- result = False
- return False
-
- else:
-
- for ad in (ad_callee, ad_caller2):
- call_ids = ad.droid.telecomCallGetCallIds()
- setattr(ad, "call_ids", call_ids)
- if call_ids:
- ad.log.info("Current existing CallId %s before making the"
- " second call.", call_ids)
-
- if not initiate_call(
- log,
- ad_caller2,
- callee_number,
- incall_ui_display=incall_ui_display,
- video=video):
- ad_caller2.log.info("Initiate 2nd call failed.")
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- result = False
- return False
- else:
- ad_caller2.log.info("Caller 2 initate 2nd call successfully")
-
- if end_first_call_before_answering_second_call:
- try:
- if not wait_for_ringing_call_for_subscription(
- log,
- ad_callee,
- subid_callee,
- incoming_number=caller2_number,
- caller=ad_caller2,
- event_tracking_started=True):
- ad_callee.log.info(
- "2nd incoming call ringing check failed.")
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- return False
-
- time.sleep(3)
-
- ad_hangup.log.info("Disconnecting first call...")
- for call_id in first_call_ids:
- disconnect_call_by_id(log, ad_hangup, call_id)
- time.sleep(3)
-
- ad_callee.log.info("Answering the 2nd ring call...")
- ad_callee.droid.telecomAcceptRingingCall(video_state)
-
- if wait_for_call_offhook_for_subscription(
- log,
- ad_callee,
- subid_callee,
- event_tracking_started=True):
- ad_callee.log.info(
- "Callee answered the 2nd call successfully.")
- else:
- ad_callee.log.error("Could not answer the 2nd call.")
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- return False
- except Exception as e:
- log.error(e)
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- return False
-
- else:
- if not wait_and_answer_call_for_subscription(
- log,
- ad_callee,
- subid_callee,
- incoming_number=caller2_number,
- caller=ad_caller2,
- incall_ui_display=incall_ui_display,
- video_state=video_state):
- ad_callee.log.error("Failed to answer 2nd call.")
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- result = False
- return False
- else:
- ad_callee.log.info(
- "Callee answered the 2nd call successfully.")
-
- for ad, subid, call_func in zip(
- [ad_callee, ad_caller2],
- [subid_callee, subid_caller2],
- [verify_callee_func, verify_caller2_func]):
- call_ids = ad.droid.telecomCallGetCallIds()
- new_call_ids = set(call_ids) - set(ad.call_ids)
- if not new_call_ids:
- ad.log.error(
- "No new call ids are found after 2nd call establishment")
- ad.log.error("telecomCallGetCallIds returns %s",
- ad.droid.telecomCallGetCallIds())
- result = False
- for new_call_id in new_call_ids:
- if not wait_for_in_call_active(ad, call_id=new_call_id):
- result = False
- else:
- ad.log.info("callProperties = %s",
- ad.droid.telecomCallGetProperties(new_call_id))
-
- if not ad.droid.telecomCallGetAudioState():
- ad.log.error("Audio is not in 2nd call state")
- result = False
-
- if call_func(log, ad):
- ad.log.info("2nd call is in %s state", call_func.__name__)
- else:
- ad.log.error("2nd call is not in %s state, voice in RAT %s",
- call_func.__name__,
- ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
- result = False
- if not result:
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- return False
-
- elapsed_time = 0
- while (elapsed_time < wait_time_in_call):
- CHECK_INTERVAL = min(CHECK_INTERVAL,
- wait_time_in_call - elapsed_time)
- time.sleep(CHECK_INTERVAL)
- elapsed_time += CHECK_INTERVAL
- time_message = "at <%s>/<%s> second." % (elapsed_time,
- wait_time_in_call)
-
- if not end_first_call_before_answering_second_call or \
- not call_waiting:
- for ad, subid, call_func in [
- (ad_caller, subid_caller, verify_caller_func),
- (ad_callee, subid_callee, verify_callee_func)]:
- if not call_func(log, ad):
- ad.log.error(
- "The first call NOT in correct %s state at %s,"
- " voice in RAT %s",
- call_func.__name__, time_message,
- ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
- result = False
- else:
- ad.log.info("The first call in correct %s state at %s",
- call_func.__name__, time_message)
- if not ad.droid.telecomCallGetAudioState():
- ad.log.error(
- "The first call audio is not in call state at %s",
- time_message)
- result = False
- if not result:
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- return False
-
- if call_waiting:
- for ad, call_func in [(ad_caller2, verify_caller2_func),
- (ad_callee, verify_callee_func)]:
- if not call_func(log, ad):
- ad.log.error(
- "The 2nd call NOT in correct %s state at %s,"
- " voice in RAT %s",
- call_func.__name__, time_message,
- ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
- result = False
- else:
- ad.log.info("The 2nd call in correct %s state at %s",
- call_func.__name__, time_message)
- if not ad.droid.telecomCallGetAudioState():
- ad.log.error(
- "The 2nd call audio is not in call state at %s",
- time_message)
- result = False
- if not result:
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- return False
-
- if not end_first_call_before_answering_second_call or not call_waiting:
- ad_hangup.log.info("Hanging up the first call...")
- for call_id in first_call_ids:
- disconnect_call_by_id(log, ad_hangup, call_id)
- time.sleep(5)
-
- if ad_hangup2 and call_waiting:
- if not hangup_call(log, ad_hangup2):
- ad_hangup2.log.info("Failed to hang up the 2nd call")
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- result = False
- return False
- finally:
- if not result:
- for ad in (ad_caller, ad_callee, ad_caller2):
- last_call_drop_reason(ad, begin_time)
- try:
- if ad.droid.telecomIsInCall():
- ad.log.info("In call. End now.")
- ad.droid.telecomEndCall()
- except Exception as e:
- log.error(str(e))
-
- if ad_hangup or not result:
- for ad in (ad_caller, ad_callee):
- if not wait_for_call_id_clearing(
- ad, getattr(ad, "caller_ids", [])):
- result = False
-
- if call_waiting:
- if ad_hangup2 or not result:
- for ad in (ad_caller2, ad_callee):
- if not wait_for_call_id_clearing(
- ad, getattr(ad, "caller_ids", [])):
- result = False
- if not call_waiting:
- set_call_waiting(log, ad_callee, enable=1)
- return result
-
-
-def wait_for_call_id_clearing(ad,
- previous_ids,
- timeout=MAX_WAIT_TIME_CALL_DROP):
- while timeout > 0:
- new_call_ids = ad.droid.telecomCallGetCallIds()
- if len(new_call_ids) <= len(previous_ids):
- return True
- time.sleep(5)
- timeout = timeout - 5
- ad.log.error("Call id clearing failed. Before: %s; After: %s",
- previous_ids, new_call_ids)
- return False
-
-
-def last_call_drop_reason(ad, begin_time=None):
- reasons = ad.search_logcat(
- "qcril_qmi_voice_map_qmi_to_ril_last_call_failure_cause", begin_time)
- reason_string = ""
- if reasons:
- log_msg = "Logcat call drop reasons:"
- for reason in reasons:
- log_msg = "%s\n\t%s" % (log_msg, reason["log_message"])
- if "ril reason str" in reason["log_message"]:
- reason_string = reason["log_message"].split(":")[-1].strip()
- ad.log.info(log_msg)
- reasons = ad.search_logcat("ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION",
- begin_time)
- if reasons:
- ad.log.warning("ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION is seen")
- ad.log.info("last call dumpsys: %s",
- sorted(dumpsys_last_call_info(ad).items()))
- return reason_string
-
-
def phone_number_formatter(input_string, formatter=None):
"""Get expected format of input phone number string.
@@ -3623,13 +1225,20 @@
# make sure input_string is 10 digital
# Remove white spaces, dashes, dots
input_string = input_string.replace(" ", "").replace("-", "").replace(
- ".", "").lstrip("0")
- if not formatter:
- return input_string
- # Remove +81 and add 0 for Japan Carriers only.
- if (len(input_string) == 13 and input_string[0:3] == "+81"):
+ ".", "")
+
+ # Remove a country code with '+' sign and add 0 for Japan/Korea Carriers.
+ if (len(input_string) == 13
+ and (input_string[0:3] == "+81" or input_string[0:3] == "+82")):
input_string = "0" + input_string[3:]
return input_string
+
+ if not formatter:
+ return input_string
+
+ # Remove leading 0 for the phone with area code started with 0
+ input_string = input_string.lstrip("0")
+
# Remove "1" or "+1"from front
if (len(input_string) == PHONE_NUMBER_STRING_FORMAT_11_DIGIT
and input_string[0] == "1"):
@@ -3727,7 +1336,7 @@
return file_directory, file_name
-def _check_file_existance(ad, file_path, expected_file_size=None):
+def _check_file_existence(ad, file_path, expected_file_size=None):
"""Check file existance by file_path. If expected_file_size
is provided, then also check if the file meet the file size requirement.
"""
@@ -3755,132 +1364,6 @@
return False
-def check_curl_availability(ad):
- if not hasattr(ad, "curl_capable"):
- try:
- out = ad.adb.shell("/data/curl --version")
- if not out or "not found" in out:
- setattr(ad, "curl_capable", False)
- ad.log.info("curl is unavailable, use chrome to download file")
- else:
- setattr(ad, "curl_capable", True)
- except Exception:
- setattr(ad, "curl_capable", False)
- ad.log.info("curl is unavailable, use chrome to download file")
- return ad.curl_capable
-
-
-def start_youtube_video(ad, url="vnd.youtube:watch?v=pSJoP0LR8CQ"):
- ad.log.info("Open an youtube video")
- for _ in range(3):
- ad.ensure_screen_on()
- ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url)
- if wait_for_state(ad.droid.audioIsMusicActive, True, 15, 1):
- ad.log.info("Started a video in youtube, audio is in MUSIC state")
- return True
- ad.log.info("Audio is not in MUSIC state. Quit Youtube.")
- for _ in range(3):
- ad.send_keycode("BACK")
- time.sleep(1)
- time.sleep(3)
- return False
-
-
-def active_file_download_task(log, ad, file_name="5MB", method="curl"):
- # files available for download on the same website:
- # 1GB.zip, 512MB.zip, 200MB.zip, 50MB.zip, 20MB.zip, 10MB.zip, 5MB.zip
- # download file by adb command, as phone call will use sl4a
- file_size_map = {
- '1MB': 1000000,
- '5MB': 5000000,
- '10MB': 10000000,
- '20MB': 20000000,
- '50MB': 50000000,
- '100MB': 100000000,
- '200MB': 200000000,
- '512MB': 512000000
- }
- url_map = {
- "1MB": [
- "http://146.148.91.8/download/1MB.zip",
- "http://ipv4.download.thinkbroadband.com/1MB.zip"
- ],
- "5MB": [
- "http://146.148.91.8/download/5MB.zip",
- "http://212.183.159.230/5MB.zip",
- "http://ipv4.download.thinkbroadband.com/5MB.zip"
- ],
- "10MB": [
- "http://146.148.91.8/download/10MB.zip",
- "http://212.183.159.230/10MB.zip",
- "http://ipv4.download.thinkbroadband.com/10MB.zip",
- "http://lax.futurehosting.com/test.zip",
- "http://ovh.net/files/10Mio.dat"
- ],
- "20MB": [
- "http://146.148.91.8/download/20MB.zip",
- "http://212.183.159.230/20MB.zip",
- "http://ipv4.download.thinkbroadband.com/20MB.zip"
- ],
- "50MB": [
- "http://146.148.91.8/download/50MB.zip",
- "http://212.183.159.230/50MB.zip",
- "http://ipv4.download.thinkbroadband.com/50MB.zip"
- ],
- "100MB": [
- "http://146.148.91.8/download/100MB.zip",
- "http://212.183.159.230/100MB.zip",
- "http://ipv4.download.thinkbroadband.com/100MB.zip",
- "http://speedtest-ca.turnkeyinternet.net/100mb.bin",
- "http://ovh.net/files/100Mio.dat",
- "http://lax.futurehosting.com/test100.zip"
- ],
- "200MB": [
- "http://146.148.91.8/download/200MB.zip",
- "http://212.183.159.230/200MB.zip",
- "http://ipv4.download.thinkbroadband.com/200MB.zip"
- ],
- "512MB": [
- "http://146.148.91.8/download/512MB.zip",
- "http://212.183.159.230/512MB.zip",
- "http://ipv4.download.thinkbroadband.com/512MB.zip"
- ]
- }
-
- file_size = file_size_map.get(file_name)
- file_urls = url_map.get(file_name)
- file_url = None
- for url in file_urls:
- url_splits = url.split("/")
- if verify_http_connection(log, ad, url=url, retry=1):
- output_path = "/sdcard/Download/%s" % url_splits[-1]
- file_url = url
- break
- if not file_url:
- ad.log.error("No url is available to download %s", file_name)
- return False
- timeout = min(max(file_size / 100000, 600), 3600)
- if method == "sl4a":
- return (http_file_download_by_sl4a, (ad, file_url, output_path,
- file_size, True, timeout))
- if method == "curl" and check_curl_availability(ad):
- return (http_file_download_by_curl, (ad, file_url, output_path,
- file_size, True, timeout))
- elif method == "sl4a" or method == "curl":
- return (http_file_download_by_sl4a, (ad, file_url, output_path,
- file_size, True, timeout))
- else:
- return (http_file_download_by_chrome, (ad, file_url, file_size, True,
- timeout))
-
-
-def active_file_download_test(log, ad, file_name="5MB", method="sl4a"):
- task = active_file_download_task(log, ad, file_name, method=method)
- if not task:
- return False
- return task[0](*task[1])
-
-
def verify_internet_connection_by_ping(log,
ad,
retries=1,
@@ -3983,7 +1466,7 @@
log_file_path=log_file_path)
return True
result, data = ad.run_iperf_client(
- iperf_server, iperf_option, timeout=timeout + 60)
+ iperf_server, iperf_option, timeout=timeout + 120)
ad.log.info("iperf test result with server %s is %s", iperf_server,
result)
if result:
@@ -4027,7 +1510,8 @@
ipv6=False,
rate_dict=None,
blocking=True,
- log_file_path=None):
+ log_file_path=None,
+ retry=5):
"""Iperf test by adb using UDP.
Args:
@@ -4043,29 +1527,36 @@
rate_dict: dictionary that can be passed in to save data
blocking: run iperf in blocking mode if True
log_file_path: location to save logs
+ retry: times of retry when the server is unavailable
"""
iperf_option = "-u -i 1 -t %s -O %s -J" % (timeout, omit)
if limit_rate:
iperf_option += " -b %s" % limit_rate
if pacing_timer:
iperf_option += " --pacing-timer %s" % pacing_timer
- if port_num:
- iperf_option += " -p %s" % port_num
if ipv6:
iperf_option += " -6"
if reverse:
iperf_option += " -R"
- try:
- return iperf_test_with_options(log,
- ad,
- iperf_server,
- iperf_option,
- timeout,
- rate_dict,
- blocking,
- log_file_path)
- except AdbError:
- return False
+ for _ in range(retry):
+ if port_num:
+ iperf_option_final = iperf_option + " -p %s" % port_num
+ port_num += 1
+ else:
+ iperf_option_final = iperf_option
+ try:
+ return iperf_test_with_options(log,
+ ad,
+ iperf_server,
+ iperf_option_final,
+ timeout,
+ rate_dict,
+ blocking,
+ log_file_path)
+ except (AdbCommandError, TimeoutError) as error:
+ continue
+ except AdbError:
+ return False
def iperf_test_by_adb(log,
@@ -4079,7 +1570,8 @@
ipv6=False,
rate_dict=None,
blocking=True,
- log_file_path=None):
+ log_file_path=None,
+ retry=5):
"""Iperf test by adb using TCP.
Args:
@@ -4095,368 +1587,34 @@
rate_dict: dictionary that can be passed in to save data
blocking: run iperf in blocking mode if True
log_file_path: location to save logs
+ retry: times of retry when the server is unavailable
"""
iperf_option = "-t %s -O %s -J" % (timeout, omit)
if limit_rate:
iperf_option += " -b %s" % limit_rate
- if port_num:
- iperf_option += " -p %s" % port_num
if ipv6:
iperf_option += " -6"
if reverse:
iperf_option += " -R"
- try:
- return iperf_test_with_options(log,
- ad,
- iperf_server,
- iperf_option,
- timeout,
- rate_dict,
- blocking,
- log_file_path)
- except AdbError:
- return False
-
-
-def http_file_download_by_curl(ad,
- url,
- out_path=None,
- expected_file_size=None,
- remove_file_after_check=True,
- timeout=3600,
- limit_rate=None,
- retry=3):
- """Download http file by adb curl.
-
- Args:
- ad: Android Device Object.
- url: The url that file to be downloaded from".
- out_path: Optional. Where to download file to.
- out_path is /sdcard/Download/ by default.
- expected_file_size: Optional. Provided if checking the download file meet
- expected file size in unit of byte.
- remove_file_after_check: Whether to remove the downloaded file after
- check.
- timeout: timeout for file download to complete.
- limit_rate: download rate in bps. None, if do not apply rate limit.
- retry: the retry request times provided in curl command.
- """
- file_directory, file_name = _generate_file_directory_and_file_name(
- url, out_path)
- file_path = os.path.join(file_directory, file_name)
- curl_cmd = "/data/curl"
- if limit_rate:
- curl_cmd += " --limit-rate %s" % limit_rate
- if retry:
- curl_cmd += " --retry %s" % retry
- curl_cmd += " --url %s > %s" % (url, file_path)
- try:
- ad.log.info("Download %s to %s by adb shell command %s", url,
- file_path, curl_cmd)
-
- ad.adb.shell(curl_cmd, timeout=timeout)
- if _check_file_existance(ad, file_path, expected_file_size):
- ad.log.info("%s is downloaded to %s successfully", url, file_path)
- return True
+ for _ in range(retry):
+ if port_num:
+ iperf_option_final = iperf_option + " -p %s" % port_num
+ port_num += 1
else:
- ad.log.warning("Fail to download %s", url)
+ iperf_option_final = iperf_option
+ try:
+ return iperf_test_with_options(log,
+ ad,
+ iperf_server,
+ iperf_option_final,
+ timeout,
+ rate_dict=rate_dict,
+ blocking=blocking,
+ log_file_path=log_file_path)
+ except (AdbCommandError, TimeoutError) as error:
+ continue
+ except AdbError:
return False
- except Exception as e:
- ad.log.warning("Download %s failed with exception %s", url, e)
- return False
- finally:
- if remove_file_after_check:
- ad.log.info("Remove the downloaded file %s", file_path)
- ad.adb.shell("rm %s" % file_path, ignore_status=True)
-
-
-def open_url_by_adb(ad, url):
- ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url)
-
-
-def http_file_download_by_chrome(ad,
- url,
- expected_file_size=None,
- remove_file_after_check=True,
- timeout=3600):
- """Download http file by chrome.
-
- Args:
- ad: Android Device Object.
- url: The url that file to be downloaded from".
- expected_file_size: Optional. Provided if checking the download file meet
- expected file size in unit of byte.
- remove_file_after_check: Whether to remove the downloaded file after
- check.
- timeout: timeout for file download to complete.
- """
- chrome_apk = "com.android.chrome"
- file_directory, file_name = _generate_file_directory_and_file_name(
- url, "/sdcard/Download/")
- file_path = os.path.join(file_directory, file_name)
- # Remove pre-existing file
- ad.force_stop_apk(chrome_apk)
- file_to_be_delete = os.path.join(file_directory, "*%s*" % file_name)
- ad.adb.shell("rm -f %s" % file_to_be_delete)
- ad.adb.shell("rm -rf /sdcard/Download/.*")
- ad.adb.shell("rm -f /sdcard/Download/.*")
- data_accounting = {
- "total_rx_bytes": ad.droid.getTotalRxBytes(),
- "mobile_rx_bytes": ad.droid.getMobileRxBytes(),
- "subscriber_mobile_data_usage": get_mobile_data_usage(ad, None, None),
- "chrome_mobile_data_usage": get_mobile_data_usage(
- ad, None, chrome_apk)
- }
- ad.log.debug("Before downloading: %s", data_accounting)
- ad.log.info("Download %s with timeout %s", url, timeout)
- ad.ensure_screen_on()
- open_url_by_adb(ad, url)
- elapse_time = 0
- result = True
- while elapse_time < timeout:
- time.sleep(30)
- if _check_file_existance(ad, file_path, expected_file_size):
- ad.log.info("%s is downloaded successfully", url)
- if remove_file_after_check:
- ad.log.info("Remove the downloaded file %s", file_path)
- ad.adb.shell("rm -f %s" % file_to_be_delete)
- ad.adb.shell("rm -rf /sdcard/Download/.*")
- ad.adb.shell("rm -f /sdcard/Download/.*")
- #time.sleep(30)
- new_data_accounting = {
- "mobile_rx_bytes":
- ad.droid.getMobileRxBytes(),
- "subscriber_mobile_data_usage":
- get_mobile_data_usage(ad, None, None),
- "chrome_mobile_data_usage":
- get_mobile_data_usage(ad, None, chrome_apk)
- }
- ad.log.info("After downloading: %s", new_data_accounting)
- accounting_diff = {
- key: value - data_accounting[key]
- for key, value in new_data_accounting.items()
- }
- ad.log.debug("Data accounting difference: %s", accounting_diff)
- if getattr(ad, "on_mobile_data", False):
- for key, value in accounting_diff.items():
- if value < expected_file_size:
- ad.log.warning("%s diff is %s less than %s", key,
- value, expected_file_size)
- ad.data_accounting["%s_failure" % key] += 1
- else:
- for key, value in accounting_diff.items():
- if value >= expected_file_size:
- ad.log.error("%s diff is %s. File download is "
- "consuming mobile data", key, value)
- result = False
- return result
- elif _check_file_existance(ad, "%s.crdownload" % file_path):
- ad.log.info("Chrome is downloading %s", url)
- elif elapse_time < 60:
- # download not started, retry download wit chrome again
- open_url_by_adb(ad, url)
- else:
- ad.log.error("Unable to download file from %s", url)
- break
- elapse_time += 30
- ad.log.warning("Fail to download file from %s", url)
- ad.force_stop_apk("com.android.chrome")
- ad.adb.shell("rm -f %s" % file_to_be_delete)
- ad.adb.shell("rm -rf /sdcard/Download/.*")
- ad.adb.shell("rm -f /sdcard/Download/.*")
- return False
-
-
-def http_file_download_by_sl4a(ad,
- url,
- out_path=None,
- expected_file_size=None,
- remove_file_after_check=True,
- timeout=300):
- """Download http file by sl4a RPC call.
-
- Args:
- ad: Android Device Object.
- url: The url that file to be downloaded from".
- out_path: Optional. Where to download file to.
- out_path is /sdcard/Download/ by default.
- expected_file_size: Optional. Provided if checking the download file meet
- expected file size in unit of byte.
- remove_file_after_check: Whether to remove the downloaded file after
- check.
- timeout: timeout for file download to complete.
- """
- file_folder, file_name = _generate_file_directory_and_file_name(
- url, out_path)
- file_path = os.path.join(file_folder, file_name)
- ad.adb.shell("rm -f %s" % file_path)
- accounting_apk = SL4A_APK_NAME
- result = True
- try:
- if not getattr(ad, "data_droid", None):
- ad.data_droid, ad.data_ed = ad.get_droid()
- ad.data_ed.start()
- else:
- try:
- if not ad.data_droid.is_live:
- ad.data_droid, ad.data_ed = ad.get_droid()
- ad.data_ed.start()
- except Exception:
- ad.log.info("Start new sl4a session for file download")
- ad.data_droid, ad.data_ed = ad.get_droid()
- ad.data_ed.start()
- data_accounting = {
- "mobile_rx_bytes":
- ad.droid.getMobileRxBytes(),
- "subscriber_mobile_data_usage":
- get_mobile_data_usage(ad, None, None),
- "sl4a_mobile_data_usage":
- get_mobile_data_usage(ad, None, accounting_apk)
- }
- ad.log.debug("Before downloading: %s", data_accounting)
- ad.log.info("Download file from %s to %s by sl4a RPC call", url,
- file_path)
- try:
- ad.data_droid.httpDownloadFile(url, file_path, timeout=timeout)
- except Exception as e:
- ad.log.warning("SL4A file download error: %s", e)
- ad.data_droid.terminate()
- return False
- if _check_file_existance(ad, file_path, expected_file_size):
- ad.log.info("%s is downloaded successfully", url)
- new_data_accounting = {
- "mobile_rx_bytes":
- ad.droid.getMobileRxBytes(),
- "subscriber_mobile_data_usage":
- get_mobile_data_usage(ad, None, None),
- "sl4a_mobile_data_usage":
- get_mobile_data_usage(ad, None, accounting_apk)
- }
- ad.log.debug("After downloading: %s", new_data_accounting)
- accounting_diff = {
- key: value - data_accounting[key]
- for key, value in new_data_accounting.items()
- }
- ad.log.debug("Data accounting difference: %s", accounting_diff)
- if getattr(ad, "on_mobile_data", False):
- for key, value in accounting_diff.items():
- if value < expected_file_size:
- ad.log.debug("%s diff is %s less than %s", key,
- value, expected_file_size)
- ad.data_accounting["%s_failure"] += 1
- else:
- for key, value in accounting_diff.items():
- if value >= expected_file_size:
- ad.log.error("%s diff is %s. File download is "
- "consuming mobile data", key, value)
- result = False
- return result
- else:
- ad.log.warning("Fail to download %s", url)
- return False
- except Exception as e:
- ad.log.error("Download %s failed with exception %s", url, e)
- raise
- finally:
- if remove_file_after_check:
- ad.log.info("Remove the downloaded file %s", file_path)
- ad.adb.shell("rm %s" % file_path, ignore_status=True)
-
-
-def get_wifi_usage(ad, sid=None, apk=None):
- if not sid:
- sid = ad.droid.subscriptionGetDefaultDataSubId()
- current_time = int(time.time() * 1000)
- begin_time = current_time - 10 * 24 * 60 * 60 * 1000
- end_time = current_time + 10 * 24 * 60 * 60 * 1000
-
- if apk:
- uid = ad.get_apk_uid(apk)
- ad.log.debug("apk %s uid = %s", apk, uid)
- try:
- return ad.droid.connectivityQueryDetailsForUid(
- TYPE_WIFI,
- ad.droid.telephonyGetSubscriberIdForSubscription(sid),
- begin_time, end_time, uid)
- except:
- return ad.droid.connectivityQueryDetailsForUid(
- ad.droid.telephonyGetSubscriberIdForSubscription(sid),
- begin_time, end_time, uid)
- else:
- try:
- return ad.droid.connectivityQuerySummaryForDevice(
- TYPE_WIFI,
- ad.droid.telephonyGetSubscriberIdForSubscription(sid),
- begin_time, end_time)
- except:
- return ad.droid.connectivityQuerySummaryForDevice(
- ad.droid.telephonyGetSubscriberIdForSubscription(sid),
- begin_time, end_time)
-
-
-def get_mobile_data_usage(ad, sid=None, apk=None):
- if not sid:
- sid = ad.droid.subscriptionGetDefaultDataSubId()
- current_time = int(time.time() * 1000)
- begin_time = current_time - 10 * 24 * 60 * 60 * 1000
- end_time = current_time + 10 * 24 * 60 * 60 * 1000
-
- if apk:
- uid = ad.get_apk_uid(apk)
- ad.log.debug("apk %s uid = %s", apk, uid)
- try:
- usage_info = ad.droid.getMobileDataUsageInfoForUid(uid, sid)
- ad.log.debug("Mobile data usage info for uid %s = %s", uid,
- usage_info)
- return usage_info["UsageLevel"]
- except:
- try:
- return ad.droid.connectivityQueryDetailsForUid(
- TYPE_MOBILE,
- ad.droid.telephonyGetSubscriberIdForSubscription(sid),
- begin_time, end_time, uid)
- except:
- return ad.droid.connectivityQueryDetailsForUid(
- ad.droid.telephonyGetSubscriberIdForSubscription(sid),
- begin_time, end_time, uid)
- else:
- try:
- usage_info = ad.droid.getMobileDataUsageInfo(sid)
- ad.log.debug("Mobile data usage info = %s", usage_info)
- return usage_info["UsageLevel"]
- except:
- try:
- return ad.droid.connectivityQuerySummaryForDevice(
- TYPE_MOBILE,
- ad.droid.telephonyGetSubscriberIdForSubscription(sid),
- begin_time, end_time)
- except:
- return ad.droid.connectivityQuerySummaryForDevice(
- ad.droid.telephonyGetSubscriberIdForSubscription(sid),
- begin_time, end_time)
-
-
-def set_mobile_data_usage_limit(ad, limit, subscriber_id=None):
- if not subscriber_id:
- subscriber_id = ad.droid.telephonyGetSubscriberId()
- ad.log.debug("Set subscriber mobile data usage limit to %s", limit)
- ad.droid.logV("Setting subscriber mobile data usage limit to %s" % limit)
- try:
- ad.droid.connectivitySetDataUsageLimit(subscriber_id, str(limit))
- except:
- ad.droid.connectivitySetDataUsageLimit(subscriber_id, limit)
-
-
-def remove_mobile_data_usage_limit(ad, subscriber_id=None):
- if not subscriber_id:
- subscriber_id = ad.droid.telephonyGetSubscriberId()
- ad.log.debug("Remove subscriber mobile data usage limit")
- ad.droid.logV(
- "Setting subscriber mobile data usage limit to -1, unlimited")
- try:
- ad.droid.connectivitySetDataUsageLimit(subscriber_id, "-1")
- except:
- ad.droid.connectivitySetDataUsageLimit(subscriber_id, -1)
def trigger_modem_crash(ad, timeout=120):
@@ -4612,276 +1770,6 @@
reboot_device(ad)
-def _connection_state_change(_event, target_state, connection_type):
- if connection_type:
- if 'TypeName' not in _event['data']:
- return False
- connection_type_string_in_event = _event['data']['TypeName']
- cur_type = connection_type_from_type_string(
- connection_type_string_in_event)
- if cur_type != connection_type:
- log.info(
- "_connection_state_change expect: %s, received: %s <type %s>",
- connection_type, connection_type_string_in_event, cur_type)
- return False
-
- if 'isConnected' in _event['data'] and _event['data']['isConnected'] == target_state:
- return True
- return False
-
-
-def wait_for_cell_data_connection(
- log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
- """Wait for data connection status to be expected value for default
- data subscription.
-
- Wait for the data connection status to be DATA_STATE_CONNECTED
- or DATA_STATE_DISCONNECTED.
-
- Args:
- log: Log object.
- ad: Android Device Object.
- state: Expected status: True or False.
- If True, it will wait for status to be DATA_STATE_CONNECTED.
- If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
- timeout_value: wait for cell data timeout value.
- This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
-
- Returns:
- True if success.
- False if failed.
- """
- sub_id = get_default_data_sub_id(ad)
- return wait_for_cell_data_connection_for_subscription(
- log, ad, sub_id, state, timeout_value)
-
-
-def _is_data_connection_state_match(log, ad, expected_data_connection_state):
- return (expected_data_connection_state ==
- ad.droid.telephonyGetDataConnectionState())
-
-
-def _is_network_connected_state_match(log, ad,
- expected_network_connected_state):
- return (expected_network_connected_state ==
- ad.droid.connectivityNetworkIsConnected())
-
-
-def wait_for_cell_data_connection_for_subscription(
- log,
- ad,
- sub_id,
- state,
- timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
- """Wait for data connection status to be expected value for specified
- subscrption id.
-
- Wait for the data connection status to be DATA_STATE_CONNECTED
- or DATA_STATE_DISCONNECTED.
-
- Args:
- log: Log object.
- ad: Android Device Object.
- sub_id: subscription Id
- state: Expected status: True or False.
- If True, it will wait for status to be DATA_STATE_CONNECTED.
- If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
- timeout_value: wait for cell data timeout value.
- This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
-
- Returns:
- True if success.
- False if failed.
- """
- state_str = {
- True: DATA_STATE_CONNECTED,
- False: DATA_STATE_DISCONNECTED
- }[state]
-
- data_state = ad.droid.telephonyGetDataConnectionState()
- if not state and ad.droid.telephonyGetDataConnectionState() == state_str:
- return True
-
- ad.ed.clear_events(EventDataConnectionStateChanged)
- ad.droid.telephonyStartTrackingDataConnectionStateChangeForSubscription(
- sub_id)
- ad.droid.connectivityStartTrackingConnectivityStateChange()
- try:
- ad.log.info("User data enabled for sub_id %s: %s", sub_id,
- ad.droid.telephonyIsDataEnabledForSubscription(sub_id))
- data_state = ad.droid.telephonyGetDataConnectionState()
- ad.log.info("Data connection state is %s", data_state)
- ad.log.info("Network is connected: %s",
- ad.droid.connectivityNetworkIsConnected())
- if data_state == state_str:
- return _wait_for_nw_data_connection(
- log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
-
- try:
- ad.ed.wait_for_event(
- EventDataConnectionStateChanged,
- is_event_match,
- timeout=timeout_value,
- field=DataConnectionStateContainer.DATA_CONNECTION_STATE,
- value=state_str)
- except Empty:
- ad.log.info("No expected event EventDataConnectionStateChanged %s",
- state_str)
-
- # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
- # data connection state.
- # Otherwise, the network state will not be correct.
- # The bug is tracked here: b/20921915
-
- # Previously we use _is_data_connection_state_match,
- # but telephonyGetDataConnectionState sometimes return wrong value.
- # The bug is tracked here: b/22612607
- # So we use _is_network_connected_state_match.
-
- if _wait_for_droid_in_state(log, ad, timeout_value,
- _is_network_connected_state_match, state):
- return _wait_for_nw_data_connection(
- log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
- else:
- return False
-
- finally:
- ad.droid.telephonyStopTrackingDataConnectionStateChangeForSubscription(
- sub_id)
-
-
-def wait_for_wifi_data_connection(
- log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
- """Wait for data connection status to be expected value and connection is by WiFi.
-
- Args:
- log: Log object.
- ad: Android Device Object.
- state: Expected status: True or False.
- If True, it will wait for status to be DATA_STATE_CONNECTED.
- If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
- timeout_value: wait for network data timeout value.
- This is optional, default value is MAX_WAIT_TIME_NW_SELECTION
-
- Returns:
- True if success.
- False if failed.
- """
- ad.log.info("wait_for_wifi_data_connection")
- return _wait_for_nw_data_connection(
- log, ad, state, NETWORK_CONNECTION_TYPE_WIFI, timeout_value)
-
-
-def wait_for_data_connection(
- log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
- """Wait for data connection status to be expected value.
-
- Wait for the data connection status to be DATA_STATE_CONNECTED
- or DATA_STATE_DISCONNECTED.
-
- Args:
- log: Log object.
- ad: Android Device Object.
- state: Expected status: True or False.
- If True, it will wait for status to be DATA_STATE_CONNECTED.
- If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
- timeout_value: wait for network data timeout value.
- This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
-
- Returns:
- True if success.
- False if failed.
- """
- return _wait_for_nw_data_connection(log, ad, state, None, timeout_value)
-
-
-def _wait_for_nw_data_connection(
- log,
- ad,
- is_connected,
- connection_type=None,
- timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
- """Wait for data connection status to be expected value.
-
- Wait for the data connection status to be DATA_STATE_CONNECTED
- or DATA_STATE_DISCONNECTED.
-
- Args:
- log: Log object.
- ad: Android Device Object.
- is_connected: Expected connection status: True or False.
- If True, it will wait for status to be DATA_STATE_CONNECTED.
- If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
- connection_type: expected connection type.
- This is optional, if it is None, then any connection type will return True.
- timeout_value: wait for network data timeout value.
- This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
-
- Returns:
- True if success.
- False if failed.
- """
- ad.ed.clear_events(EventConnectivityChanged)
- ad.droid.connectivityStartTrackingConnectivityStateChange()
- try:
- cur_data_connection_state = ad.droid.connectivityNetworkIsConnected()
- if is_connected == cur_data_connection_state:
- current_type = get_internet_connection_type(log, ad)
- ad.log.info("current data connection type: %s", current_type)
- if not connection_type:
- return True
- else:
- if not is_connected and current_type != connection_type:
- ad.log.info("data connection not on %s!", connection_type)
- return True
- elif is_connected and current_type == connection_type:
- ad.log.info("data connection on %s as expected",
- connection_type)
- return True
- else:
- ad.log.info("current data connection state: %s target: %s",
- cur_data_connection_state, is_connected)
-
- try:
- event = ad.ed.wait_for_event(
- EventConnectivityChanged, _connection_state_change,
- timeout_value, is_connected, connection_type)
- ad.log.info("Got event: %s", event)
- except Empty:
- pass
-
- log.info(
- "_wait_for_nw_data_connection: check connection after wait event.")
- # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
- # data connection state.
- # Otherwise, the network state will not be correct.
- # The bug is tracked here: b/20921915
- if _wait_for_droid_in_state(log, ad, timeout_value,
- _is_network_connected_state_match,
- is_connected):
- current_type = get_internet_connection_type(log, ad)
- ad.log.info("current data connection type: %s", current_type)
- if not connection_type:
- return True
- else:
- if not is_connected and current_type != connection_type:
- ad.log.info("data connection not on %s", connection_type)
- return True
- elif is_connected and current_type == connection_type:
- ad.log.info("after event wait, data connection on %s",
- connection_type)
- return True
- else:
- return False
- else:
- return False
- except Exception as e:
- ad.log.error("Exception error %s", str(e))
- return False
- finally:
- ad.droid.connectivityStopTrackingConnectivityStateChange()
-
-
def get_cell_data_roaming_state_by_adb(ad):
"""Get Cell Data Roaming state. True for enabled, False for disabled"""
state_mapping = {"1": True, "0": False}
@@ -4983,461 +1871,6 @@
return len(calls) if calls else 0
-def show_enhanced_4g_lte(ad, sub_id):
- result = True
- capabilities = ad.telephony["subscription"][sub_id].get("capabilities", [])
- 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)
- 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")
-
- if sub_id != current_voice_sub_id:
- set_incoming_voice_sub_id(ad, current_voice_sub_id)
-
- result = True
- return result
-
-
-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.
- """
- return toggle_volte_for_subscription(
- log, ad, get_outgoing_voice_sub_id(ad), new_state)
-
-
-def toggle_volte_for_subscription(log, ad, sub_id, new_state=None):
- """Toggle enable/disable VoLTE for specified voice subscription.
-
- Args:
- ad: Android device object.
- 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.
-
- """
- if not show_enhanced_4g_lte(ad, sub_id):
- return False
-
- 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):
- """ Toggle WFC enable/disable
-
- Args:
- log: Log object
- ad: Android device object.
- new_state: WFC state to set to.
- True for enable, False for disable.
- If None, opposite of the current state.
- """
- return toggle_wfc_for_subscription(
- log, ad, new_state, get_outgoing_voice_sub_id(ad))
-
-
-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: 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()
-
- 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 Wi-Fi calling 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 Wi-Fi calling 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.
-
- Args:
- log: log object.
- ad: android device.
- max_time: maximal wait time.
-
- Returns:
- Return True if device report VoLTE enabled bit true within max_time.
- Return False if timeout.
- """
- return wait_for_state(
- is_enhanced_4g_lte_mode_setting_enabled,
- True,
- max_time,
- WAIT_TIME_BETWEEN_STATE_CHECK,
- ad,
- sub_id,
- enabled_by="platform")
-
-
-def set_wfc_mode(log, ad, wfc_mode):
- """Set WFC enable/disable and mode.
-
- Args:
- log: Log object
- ad: Android device object.
- wfc_mode: WFC mode to set to.
- Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED,
- WFC_MODE_WIFI_PREFERRED, WFC_MODE_DISABLED.
-
- Returns:
- True if success. False if ad does not support WFC or error happened.
- """
- 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):
- """Set WFC enable/disable and mode subscription based
-
- Args:
- ad: Android device object.
- wfc_mode: WFC mode to set to.
- Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED,
- WFC_MODE_WIFI_PREFERRED.
- sub_id: subscription Id
-
- 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:
- current_mode = ad.droid.imsMmTelGetVoWiFiModeSetting(sub_id)
- ad.log.info("Current WFC mode of sub ID %s: %s", sub_id, current_mode)
- except Exception as e:
- 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:
- ad.log.info("WFC is already 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.log.info(
- "WFC is enabled for sub ID %s. Disabling WFC...", sub_id)
- 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):
- """ Sets Provisioning Values for Subscription Id
-
- Args:
- ad: Android device object.
- sub_id: Subscription Id
- feature_flag: voice or video
- value: enable or disable
-
- """
- try:
- if sub_id is None:
- sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
- ad.log.info("SubId %s - setprovisioning for %s to %s",
- sub_id, feature_flag, value)
- result = ad.droid.provisioningSetProvisioningIntValue(sub_id,
- feature_flag, value)
- if result == 0:
- return True
- return False
- except Exception as e:
- ad.log.error(e)
- return False
-
-
-def get_ims_provisioning_for_subscription(ad, feature_flag, tech, sub_id=None):
- """ Gets Provisioning Values for Subscription Id
-
- Args:
- ad: Android device object.
- sub_id: Subscription Id
- feature_flag: voice, video, ut, sms
- tech: lte, iwlan
-
- """
- try:
- if sub_id is None:
- sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
- result = ad.droid.provisioningGetProvisioningStatusForCapability(
- sub_id, feature_flag, tech)
- ad.log.info("SubId %s - getprovisioning for %s on %s - %s",
- sub_id, feature_flag, tech, result)
- return result
- except Exception as e:
- ad.log.error(e)
- return False
-
-
def get_carrier_provisioning_for_subscription(ad, feature_flag,
tech, sub_id=None):
""" Gets Provisioning Values for Subscription Id
@@ -5461,111 +1894,6 @@
return False
-def activate_wfc_on_device(log, ad):
- """ Activates WiFi calling on device.
-
- Required for certain network operators.
-
- Args:
- log: Log object
- ad: Android device object
-
- """
- activate_wfc_on_device_for_subscription(log, ad,
- ad.droid.subscriptionGetDefaultSubId())
-
-
-def activate_wfc_on_device_for_subscription(log, ad, sub_id):
- """ Activates WiFi calling on device for a subscription.
-
- Args:
- log: Log object
- ad: Android device object
- sub_id: Subscription id (integer)
-
- """
- if not sub_id or INVALID_SUB_ID == sub_id:
- ad.log.error("Subscription id invalid")
- return
- operator_name = get_operator_name(log, ad, sub_id)
- if operator_name in (CARRIER_VZW, CARRIER_ATT, CARRIER_BELL, CARRIER_ROGERS,
- CARRIER_TELUS, CARRIER_KOODO, CARRIER_VIDEOTRON, CARRIER_FRE):
- ad.log.info("Activating WFC on operator : %s", operator_name)
- if not ad.is_apk_installed("com.google.android.wfcactivation"):
- ad.log.error("WFC Activation Failed, wfc activation apk not installed")
- return
- wfc_activate_cmd ="am start --ei EXTRA_LAUNCH_CARRIER_APP 0 --ei " \
- "android.telephony.extra.SUBSCRIPTION_INDEX {} -n ".format(sub_id)
- if CARRIER_ATT == operator_name:
- ad.adb.shell("setprop dbg.att.force_wfc_nv_enabled true")
- wfc_activate_cmd = wfc_activate_cmd+\
- "\"com.google.android.wfcactivation/" \
- ".WfcActivationActivity\""
- elif CARRIER_VZW == operator_name:
- ad.adb.shell("setprop dbg.vzw.force_wfc_nv_enabled true")
- wfc_activate_cmd = wfc_activate_cmd + \
- "\"com.google.android.wfcactivation/" \
- ".VzwEmergencyAddressActivity\""
- else:
- wfc_activate_cmd = wfc_activate_cmd+ \
- "\"com.google.android.wfcactivation/" \
- ".can.WfcActivationCanadaActivity\""
- ad.adb.shell(wfc_activate_cmd)
-
-
-def toggle_video_calling(log, ad, new_state=None):
- """Toggle enable/disable Video calling for default voice subscription.
-
- Args:
- ad: Android device object.
- new_state: Video 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 Video calling.
- """
- if not ad.droid.imsIsVtEnabledByPlatform():
- if new_state is not False:
- raise TelTestUtilsError("VT not supported by platform.")
- # if the user sets VT false and it's unavailable we just let it go
- return False
-
- current_state = ad.droid.imsIsVtEnabledByUser()
- if new_state is None:
- new_state = not current_state
- if new_state != current_state:
- ad.droid.imsSetVtSetting(new_state)
- return True
-
-
-def toggle_video_calling_for_subscription(ad, new_state=None, sub_id=None):
- """Toggle enable/disable Video calling for subscription.
-
- Args:
- ad: Android device object.
- new_state: Video mode state to set to.
- True for enable, False for disable.
- If None, opposite of the current state.
- sub_id: subscription Id
-
- """
- try:
- if sub_id is None:
- sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
- current_state = ad.droid.imsMmTelIsVtSettingEnabled(sub_id)
- if new_state is None:
- new_state = not current_state
- if new_state != current_state:
- ad.log.info("SubId %s - Toggle VT from %s to %s", sub_id,
- current_state, new_state)
- ad.droid.imsMmTelSetVtSettingEnabled(sub_id, new_state)
- except Exception as e:
- ad.log.error(e)
- return False
- return True
-
-
def _wait_for_droid_in_state(log, ad, max_time, state_check_func, *args,
**kwargs):
while max_time >= 0:
@@ -5607,125 +1935,6 @@
return False
-def is_phone_in_call(log, ad):
- """Return True if phone in call.
-
- Args:
- log: log object.
- ad: android device.
- """
- try:
- return ad.droid.telecomIsInCall()
- except:
- return "mCallState=2" in ad.adb.shell(
- "dumpsys telephony.registry | grep mCallState")
-
-
-def is_phone_not_in_call(log, ad):
- """Return True if phone not in call.
-
- Args:
- log: log object.
- ad: android device.
- """
- in_call = ad.droid.telecomIsInCall()
- call_state = ad.droid.telephonyGetCallState()
- if in_call:
- ad.log.info("Device is In Call")
- if call_state != TELEPHONY_STATE_IDLE:
- ad.log.info("Call_state is %s, not %s", call_state,
- TELEPHONY_STATE_IDLE)
- return ((not in_call) and (call_state == TELEPHONY_STATE_IDLE))
-
-
-def wait_for_droid_in_call(log, ad, max_time):
- """Wait for android to be in call state.
-
- Args:
- log: log object.
- ad: android device.
- max_time: maximal wait time.
-
- Returns:
- If phone become in call state within max_time, return True.
- Return False if timeout.
- """
- return _wait_for_droid_in_state(log, ad, max_time, is_phone_in_call)
-
-
-def is_phone_in_call_active(ad, call_id=None):
- """Return True if phone in active call.
-
- Args:
- log: log object.
- ad: android device.
- call_id: the call id
- """
- if ad.droid.telecomIsInCall():
- if not call_id:
- call_id = ad.droid.telecomCallGetCallIds()[0]
- call_state = ad.droid.telecomCallGetCallState(call_id)
- ad.log.info("%s state is %s", call_id, call_state)
- return call_state == "ACTIVE"
- else:
- ad.log.info("Not in telecomIsInCall")
- return False
-
-
-def wait_for_in_call_active(ad,
- timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT,
- interval=WAIT_TIME_BETWEEN_STATE_CHECK,
- call_id=None):
- """Wait for call reach active state.
-
- Args:
- log: log object.
- ad: android device.
- call_id: the call id
- """
- if not call_id:
- call_id = ad.droid.telecomCallGetCallIds()[0]
- args = [ad, call_id]
- if not wait_for_state(is_phone_in_call_active, True, timeout, interval,
- *args):
- ad.log.error("Call did not reach ACTIVE state")
- return False
- else:
- return True
-
-
-def wait_for_telecom_ringing(log, ad, max_time=MAX_WAIT_TIME_TELECOM_RINGING):
- """Wait for android to be in telecom ringing state.
-
- Args:
- log: log object.
- ad: android device.
- max_time: maximal wait time. This is optional.
- Default Value is MAX_WAIT_TIME_TELECOM_RINGING.
-
- Returns:
- If phone become in telecom ringing state within max_time, return True.
- Return False if timeout.
- """
- return _wait_for_droid_in_state(
- log, ad, max_time, lambda log, ad: ad.droid.telecomIsRinging())
-
-
-def wait_for_droid_not_in_call(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP):
- """Wait for android to be not in call state.
-
- Args:
- log: log object.
- ad: android device.
- max_time: maximal wait time.
-
- Returns:
- If phone become not in call state within max_time, return True.
- Return False if timeout.
- """
- return _wait_for_droid_in_state(log, ad, max_time, is_phone_not_in_call)
-
-
def _is_attached(log, ad, voice_or_data):
return _is_attached_for_subscription(
log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data)
@@ -5743,48 +1952,6 @@
log, ad, ad.droid.subscriptionGetDefaultSubId(), NETWORK_SERVICE_VOICE)
-def wait_for_voice_attach(log, ad, max_time=MAX_WAIT_TIME_NW_SELECTION):
- """Wait for android device to attach on voice.
-
- Args:
- log: log object.
- ad: android device.
- max_time: maximal wait time.
-
- Returns:
- Return True if device attach voice within max_time.
- Return False if timeout.
- """
- return _wait_for_droid_in_state(log, ad, max_time, _is_attached,
- NETWORK_SERVICE_VOICE)
-
-
-def wait_for_voice_attach_for_subscription(
- log, ad, sub_id, max_time=MAX_WAIT_TIME_NW_SELECTION):
- """Wait for android device to attach on voice in subscription id.
-
- Args:
- log: log object.
- ad: android device.
- sub_id: subscription id.
- max_time: maximal wait time.
-
- Returns:
- Return True if device attach voice within max_time.
- Return False if timeout.
- """
- if not _wait_for_droid_in_state_for_subscription(
- log, ad, sub_id, max_time, _is_attached_for_subscription,
- NETWORK_SERVICE_VOICE):
- return False
-
- # TODO: b/26295983 if pone attach to 1xrtt from unknown, phone may not
- # receive incoming call immediately.
- if ad.droid.telephonyGetCurrentVoiceNetworkType() == RAT_1XRTT:
- time.sleep(WAIT_TIME_1XRTT_VOICE_ATTACH)
- return True
-
-
def wait_for_data_attach(log, ad, max_time):
"""Wait for android device to attach on data.
@@ -5819,196 +1986,6 @@
NETWORK_SERVICE_DATA)
-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.
- """
- 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):
- """Wait for android device to register on ims.
-
- Args:
- log: log object.
- ad: android device.
- max_time: maximal wait time.
-
- Returns:
- Return True if device register ims successfully within max_time.
- Return False if timeout.
- """
- 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, 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, sub_id):
- ad.log.info("IMS is not registered for sub ID %s.", sub_id)
- return 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 for sub ID %s, IsVolteCallingAvailable "
- "is True", sub_id)
- return True
-
-
-def is_video_enabled(log, ad):
- """Return True if Video Calling feature bit is True.
-
- Args:
- log: log object.
- ad: android device.
-
- Returns:
- Return True if Video Calling feature bit is True and IMS registered.
- Return False if Video Calling feature bit is False or IMS not registered.
- """
- video_status = ad.droid.telephonyIsVideoCallingAvailable()
- if video_status is True and is_ims_registered(log, ad) is False:
- ad.log.error(
- "Error! Video Call is Available, but IMS is not registered.")
- return False
- return video_status
-
-
-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:
- log: log object.
- ad: android device.
- max_time: maximal wait time.
-
- Returns:
- Return True if device report VoLTE enabled bit true within max_time.
- Return False if timeout.
- """
- 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):
- """Wait for android device to report Video Telephony enabled bit true.
-
- Args:
- log: log object.
- ad: android device.
- max_time: maximal wait time.
-
- Returns:
- Return True if device report Video Telephony enabled bit true within max_time.
- Return False if timeout.
- """
- return _wait_for_droid_in_state(log, ad, max_time, is_video_enabled)
-
-
-def is_wfc_enabled(log, ad):
- """Return True if WiFi Calling feature bit is True.
-
- Args:
- log: log object.
- ad: android device.
-
- Returns:
- Return True if WiFi Calling feature bit is True and IMS registered.
- Return False if WiFi Calling feature bit is False or IMS not registered.
- """
- if not is_ims_registered(log, ad):
- ad.log.info("IMS is not registered.")
- return False
- if not ad.droid.telephonyIsWifiCallingAvailable():
- ad.log.info("IMS is registered, IsWifiCallingAvailable is False")
- return False
- else:
- ad.log.info("IMS is registered, IsWifiCallingAvailable is True")
- return True
-
-
-def wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED):
- """Wait for android device to report WiFi Calling enabled bit true.
-
- Args:
- log: log object.
- ad: android device.
- max_time: maximal wait time.
- Default value is MAX_WAIT_TIME_WFC_ENABLED.
-
- Returns:
- Return True if device report WiFi Calling enabled bit true within max_time.
- Return False if timeout.
- """
- return _wait_for_droid_in_state(log, ad, max_time, is_wfc_enabled)
-
-
-def wait_for_wfc_disabled(log, ad, max_time=MAX_WAIT_TIME_WFC_DISABLED):
- """Wait for android device to report WiFi Calling enabled bit false.
-
- Args:
- log: log object.
- ad: android device.
- max_time: maximal wait time.
- Default value is MAX_WAIT_TIME_WFC_DISABLED.
-
- Returns:
- Return True if device report WiFi Calling enabled bit false within max_time.
- Return False if timeout.
- """
- return _wait_for_droid_in_state(
- log, ad, max_time, lambda log, ad: not is_wfc_enabled(log, ad))
-
-
def get_phone_number(log, ad):
"""Get phone number for default subscription
@@ -6125,867 +2102,6 @@
return model
-def is_sms_match(event, phonenumber_tx, text):
- """Return True if 'text' equals to event['data']['Text']
- and phone number match.
-
- Args:
- event: Event object to verify.
- phonenumber_tx: phone number for sender.
- text: text string to verify.
-
- Returns:
- Return True if 'text' equals to event['data']['Text']
- and phone number match.
- """
- return (check_phone_number_match(event['data']['Sender'], phonenumber_tx)
- and event['data']['Text'].strip() == text)
-
-
-def is_sms_partial_match(event, phonenumber_tx, text):
- """Return True if 'text' starts with event['data']['Text']
- and phone number match.
-
- Args:
- event: Event object to verify.
- phonenumber_tx: phone number for sender.
- text: text string to verify.
-
- Returns:
- Return True if 'text' starts with event['data']['Text']
- and phone number match.
- """
- event_text = event['data']['Text'].strip()
- if event_text.startswith("("):
- event_text = event_text.split(")")[-1]
- return (check_phone_number_match(event['data']['Sender'], phonenumber_tx)
- and text.startswith(event_text))
-
-
-def sms_send_receive_verify(log,
- ad_tx,
- ad_rx,
- array_message,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
- expected_result=True,
- slot_id_rx=None):
- """Send SMS, receive SMS, and verify content and sender's number.
-
- Send (several) SMS from droid_tx to droid_rx.
- Verify SMS is sent, delivered and received.
- Verify received content and sender's number are correct.
-
- Args:
- log: Log object.
- ad_tx: Sender's Android Device Object
- ad_rx: Receiver's Android Device Object
- array_message: the array of message to send/receive
- slot_id_rx: the slot on the Receiver's android device (0/1)
- """
- subid_tx = get_outgoing_message_sub_id(ad_tx)
- if slot_id_rx is None:
- subid_rx = get_incoming_message_sub_id(ad_rx)
- else:
- subid_rx = get_subid_from_slot_index(log, ad_rx, slot_id_rx)
-
- result = sms_send_receive_verify_for_subscription(
- log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time)
- if result != expected_result:
- log_messaging_screen_shot(ad_tx, test_name="sms_tx")
- log_messaging_screen_shot(ad_rx, test_name="sms_rx")
- return result == expected_result
-
-
-def wait_for_matching_sms(log,
- ad_rx,
- phonenumber_tx,
- text,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
- allow_multi_part_long_sms=True):
- """Wait for matching incoming SMS.
-
- Args:
- log: Log object.
- ad_rx: Receiver's Android Device Object
- phonenumber_tx: Sender's phone number.
- text: SMS content string.
- allow_multi_part_long_sms: is long SMS allowed to be received as
- multiple short SMS. This is optional, default value is True.
-
- Returns:
- True if matching incoming SMS is received.
- """
- if not allow_multi_part_long_sms:
- try:
- ad_rx.messaging_ed.wait_for_event(EventSmsReceived, is_sms_match,
- max_wait_time, phonenumber_tx,
- text)
- ad_rx.log.info("Got event %s", EventSmsReceived)
- return True
- except Empty:
- ad_rx.log.error("No matched SMS received event.")
- return False
- else:
- try:
- received_sms = ''
- remaining_text = text
- while (remaining_text != ''):
- event = ad_rx.messaging_ed.wait_for_event(
- EventSmsReceived, is_sms_partial_match, max_wait_time,
- phonenumber_tx, remaining_text)
- event_text = event['data']['Text'].split(")")[-1].strip()
- event_text_length = len(event_text)
- ad_rx.log.info("Got event %s of text length %s from %s",
- EventSmsReceived, event_text_length,
- phonenumber_tx)
- remaining_text = remaining_text[event_text_length:]
- received_sms += event_text
- ad_rx.log.info("Received SMS of length %s", len(received_sms))
- return True
- except Empty:
- ad_rx.log.error(
- "Missing SMS received event of text length %s from %s",
- len(remaining_text), phonenumber_tx)
- if received_sms != '':
- ad_rx.log.error(
- "Only received partial matched SMS of length %s",
- len(received_sms))
- return False
-
-
-def is_mms_match(event, phonenumber_tx, text):
- """Return True if 'text' equals to event['data']['Text']
- and phone number match.
-
- Args:
- event: Event object to verify.
- phonenumber_tx: phone number for sender.
- text: text string to verify.
-
- Returns:
- Return True if 'text' equals to event['data']['Text']
- and phone number match.
- """
- #TODO: add mms matching after mms message parser is added in sl4a. b/34276948
- return True
-
-
-def wait_for_matching_mms(log,
- ad_rx,
- phonenumber_tx,
- text,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
- """Wait for matching incoming SMS.
-
- Args:
- log: Log object.
- ad_rx: Receiver's Android Device Object
- phonenumber_tx: Sender's phone number.
- text: SMS content string.
- allow_multi_part_long_sms: is long SMS allowed to be received as
- multiple short SMS. This is optional, default value is True.
-
- Returns:
- True if matching incoming SMS is received.
- """
- try:
- #TODO: add mms matching after mms message parser is added in sl4a. b/34276948
- ad_rx.messaging_ed.wait_for_event(EventMmsDownloaded, is_mms_match,
- max_wait_time, phonenumber_tx, text)
- ad_rx.log.info("Got event %s", EventMmsDownloaded)
- return True
- except Empty:
- ad_rx.log.warning("No matched MMS downloaded event.")
- return False
-
-
-def sms_send_receive_verify_for_subscription(
- log,
- ad_tx,
- ad_rx,
- subid_tx,
- subid_rx,
- array_message,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
- """Send SMS, receive SMS, and verify content and sender's number.
-
- Send (several) SMS from droid_tx to droid_rx.
- Verify SMS is sent, delivered and received.
- Verify received content and sender's number are correct.
-
- Args:
- log: Log object.
- ad_tx: Sender's Android Device Object..
- ad_rx: Receiver's Android Device Object.
- subid_tx: Sender's subsciption ID to be used for SMS
- subid_rx: Receiver's subsciption ID to be used for SMS
- array_message: the array of message to send/receive
- """
- phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
- phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
-
- for ad in (ad_tx, ad_rx):
- ad.send_keycode("BACK")
- if not getattr(ad, "messaging_droid", None):
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
- else:
- try:
- if not ad.messaging_droid.is_live:
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
- else:
- ad.messaging_ed.clear_all_events()
- ad.messaging_droid.logI(
- "Start sms_send_receive_verify_for_subscription test")
- except Exception:
- ad.log.info("Create new sl4a session for messaging")
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
-
- for text in array_message:
- length = len(text)
- ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
- phonenumber_tx, phonenumber_rx, length, text)
- try:
- ad_rx.messaging_ed.clear_events(EventSmsReceived)
- ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
- ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
- ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
- time.sleep(1) #sleep 100ms after starting event tracking
- ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
- ad_rx.messaging_droid.logI("Expecting SMS of length %s" % length)
- ad_tx.messaging_droid.smsSendTextMessage(phonenumber_rx, text,
- True)
- try:
- events = ad_tx.messaging_ed.pop_events(
- "(%s|%s|%s|%s)" %
- (EventSmsSentSuccess, EventSmsSentFailure,
- EventSmsDeliverSuccess,
- EventSmsDeliverFailure), max_wait_time)
- for event in events:
- ad_tx.log.info("Got event %s", event["name"])
- if event["name"] == EventSmsSentFailure or event["name"] == EventSmsDeliverFailure:
- if event.get("data") and event["data"].get("Reason"):
- ad_tx.log.error("%s with reason: %s",
- event["name"],
- event["data"]["Reason"])
- return False
- elif event["name"] == EventSmsSentSuccess or event["name"] == EventSmsDeliverSuccess:
- break
- except Empty:
- ad_tx.log.error("No %s or %s event for SMS of length %s.",
- EventSmsSentSuccess, EventSmsSentFailure,
- length)
- return False
-
- if not wait_for_matching_sms(
- log,
- ad_rx,
- phonenumber_tx,
- text,
- max_wait_time,
- allow_multi_part_long_sms=True):
- ad_rx.log.error("No matching received SMS of length %s.",
- length)
- return False
- except Exception as e:
- log.error("Exception error %s", e)
- raise
- finally:
- ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
- return True
-
-
-def mms_send_receive_verify(log,
- ad_tx,
- ad_rx,
- array_message,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
- expected_result=True,
- slot_id_rx=None):
- """Send MMS, receive MMS, and verify content and sender's number.
-
- Send (several) MMS from droid_tx to droid_rx.
- Verify MMS is sent, delivered and received.
- Verify received content and sender's number are correct.
-
- Args:
- log: Log object.
- ad_tx: Sender's Android Device Object
- ad_rx: Receiver's Android Device Object
- array_message: the array of message to send/receive
- """
- subid_tx = get_outgoing_message_sub_id(ad_tx)
- if slot_id_rx is None:
- subid_rx = get_incoming_message_sub_id(ad_rx)
- else:
- subid_rx = get_subid_from_slot_index(log, ad_rx, slot_id_rx)
-
- result = mms_send_receive_verify_for_subscription(
- log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time)
- if result != expected_result:
- log_messaging_screen_shot(ad_tx, test_name="mms_tx")
- log_messaging_screen_shot(ad_rx, test_name="mms_rx")
- return result == expected_result
-
-
-def sms_mms_send_logcat_check(ad, type, begin_time):
- type = type.upper()
- log_results = ad.search_logcat(
- "%s Message sent successfully" % type, begin_time=begin_time)
- if log_results:
- ad.log.info("Found %s sent successful log message: %s", type,
- log_results[-1]["log_message"])
- return True
- else:
- log_results = ad.search_logcat(
- "ProcessSentMessageAction: Done sending %s message" % type,
- begin_time=begin_time)
- if log_results:
- for log_result in log_results:
- if "status is SUCCEEDED" in log_result["log_message"]:
- ad.log.info(
- "Found BugleDataModel %s send succeed log message: %s",
- type, log_result["log_message"])
- return True
- return False
-
-
-def sms_mms_receive_logcat_check(ad, type, begin_time):
- type = type.upper()
- smshandle_logs = ad.search_logcat(
- "InboundSmsHandler: No broadcast sent on processing EVENT_BROADCAST_SMS",
- begin_time=begin_time)
- if smshandle_logs:
- ad.log.warning("Found %s", smshandle_logs[-1]["log_message"])
- log_results = ad.search_logcat(
- "New %s Received" % type, begin_time=begin_time) or \
- ad.search_logcat("New %s Downloaded" % type, begin_time=begin_time)
- if log_results:
- ad.log.info("Found SL4A %s received log message: %s", type,
- log_results[-1]["log_message"])
- return True
- else:
- log_results = ad.search_logcat(
- "Received %s message" % type, begin_time=begin_time)
- if log_results:
- ad.log.info("Found %s received log message: %s", type,
- log_results[-1]["log_message"])
- log_results = ad.search_logcat(
- "ProcessDownloadedMmsAction", begin_time=begin_time)
- for log_result in log_results:
- ad.log.info("Found %s", log_result["log_message"])
- if "status is SUCCEEDED" in log_result["log_message"]:
- ad.log.info("Download succeed with ProcessDownloadedMmsAction")
- return True
- return False
-
-
-#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
-def mms_send_receive_verify_for_subscription(
- log,
- ad_tx,
- ad_rx,
- subid_tx,
- subid_rx,
- array_payload,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
- """Send MMS, receive MMS, and verify content and sender's number.
-
- Send (several) MMS from droid_tx to droid_rx.
- Verify MMS is sent, delivered and received.
- Verify received content and sender's number are correct.
-
- Args:
- log: Log object.
- ad_tx: Sender's Android Device Object..
- ad_rx: Receiver's Android Device Object.
- subid_tx: Sender's subsciption ID to be used for SMS
- subid_rx: Receiver's subsciption ID to be used for SMS
- array_message: the array of message to send/receive
- """
-
- phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
- phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
- toggle_enforce = False
-
- for ad in (ad_tx, ad_rx):
- ad.send_keycode("BACK")
- if "Permissive" not in ad.adb.shell("su root getenforce"):
- ad.adb.shell("su root setenforce 0")
- toggle_enforce = True
- if not getattr(ad, "messaging_droid", None):
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
- else:
- try:
- if not ad.messaging_droid.is_live:
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
- else:
- ad.messaging_ed.clear_all_events()
- ad.messaging_droid.logI(
- "Start mms_send_receive_verify_for_subscription test")
- except Exception:
- ad.log.info("Create new sl4a session for messaging")
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
-
- for subject, message, filename in array_payload:
- ad_tx.messaging_ed.clear_events(EventMmsSentSuccess)
- ad_tx.messaging_ed.clear_events(EventMmsSentFailure)
- ad_rx.messaging_ed.clear_events(EventMmsDownloaded)
- ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage()
- ad_tx.log.info(
- "Sending MMS from %s to %s, subject: %s, message: %s, file: %s.",
- phonenumber_tx, phonenumber_rx, subject, message, filename)
- try:
- ad_tx.messaging_droid.smsSendMultimediaMessage(
- phonenumber_rx, subject, message, phonenumber_tx, filename)
- try:
- events = ad_tx.messaging_ed.pop_events(
- "(%s|%s)" % (EventMmsSentSuccess,
- EventMmsSentFailure), max_wait_time)
- for event in events:
- ad_tx.log.info("Got event %s", event["name"])
- if event["name"] == EventMmsSentFailure:
- if event.get("data") and event["data"].get("Reason"):
- ad_tx.log.error("%s with reason: %s",
- event["name"],
- event["data"]["Reason"])
- return False
- elif event["name"] == EventMmsSentSuccess:
- break
- except Empty:
- ad_tx.log.warning("No %s or %s event.", EventMmsSentSuccess,
- EventMmsSentFailure)
- return False
-
- if not wait_for_matching_mms(log, ad_rx, phonenumber_tx,
- message, max_wait_time):
- return False
- except Exception as e:
- log.error("Exception error %s", e)
- raise
- finally:
- ad_rx.messaging_droid.smsStopTrackingIncomingMmsMessage()
- for ad in (ad_tx, ad_rx):
- if toggle_enforce:
- ad.send_keycode("BACK")
- ad.adb.shell("su root setenforce 1")
- return True
-
-
-def mms_receive_verify_after_call_hangup(
- log, ad_tx, ad_rx, array_message,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
- """Verify the suspanded MMS during call will send out after call release.
-
- Hangup call from droid_tx to droid_rx.
- Verify MMS is sent, delivered and received.
- Verify received content and sender's number are correct.
-
- Args:
- log: Log object.
- ad_tx: Sender's Android Device Object
- ad_rx: Receiver's Android Device Object
- array_message: the array of message to send/receive
- """
- return mms_receive_verify_after_call_hangup_for_subscription(
- log, ad_tx, ad_rx, get_outgoing_message_sub_id(ad_tx),
- get_incoming_message_sub_id(ad_rx), array_message, max_wait_time)
-
-
-#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
-def mms_receive_verify_after_call_hangup_for_subscription(
- log,
- ad_tx,
- ad_rx,
- subid_tx,
- subid_rx,
- array_payload,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
- """Verify the suspanded MMS during call will send out after call release.
-
- Hangup call from droid_tx to droid_rx.
- Verify MMS is sent, delivered and received.
- Verify received content and sender's number are correct.
-
- Args:
- log: Log object.
- ad_tx: Sender's Android Device Object..
- ad_rx: Receiver's Android Device Object.
- subid_tx: Sender's subsciption ID to be used for SMS
- subid_rx: Receiver's subsciption ID to be used for SMS
- array_message: the array of message to send/receive
- """
-
- phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
- phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
- for ad in (ad_tx, ad_rx):
- if not getattr(ad, "messaging_droid", None):
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
- for subject, message, filename in array_payload:
- ad_rx.log.info(
- "Waiting MMS from %s to %s, subject: %s, message: %s, file: %s.",
- phonenumber_tx, phonenumber_rx, subject, message, filename)
- ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage()
- time.sleep(5)
- try:
- hangup_call(log, ad_tx)
- hangup_call(log, ad_rx)
- try:
- ad_tx.messaging_ed.pop_event(EventMmsSentSuccess,
- max_wait_time)
- ad_tx.log.info("Got event %s", EventMmsSentSuccess)
- except Empty:
- log.warning("No sent_success event.")
- if not wait_for_matching_mms(log, ad_rx, phonenumber_tx, message):
- return False
- finally:
- ad_rx.messaging_droid.smsStopTrackingIncomingMmsMessage()
- return True
-
-
-def ensure_preferred_network_type_for_subscription(
- ad,
- network_preference
- ):
- sub_id = ad.droid.subscriptionGetDefaultSubId()
- if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
- network_preference, sub_id):
- ad.log.error("Set sub_id %s Preferred Networks Type %s failed.",
- sub_id, network_preference)
- return True
-
-
-def ensure_network_rat(log,
- ad,
- network_preference,
- rat_family,
- voice_or_data=None,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- toggle_apm_after_setting=False):
- """Ensure ad's current network is in expected rat_family.
- """
- return ensure_network_rat_for_subscription(
- log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
- rat_family, voice_or_data, max_wait_time, toggle_apm_after_setting)
-
-
-def ensure_network_rat_for_subscription(
- log,
- ad,
- sub_id,
- network_preference,
- rat_family,
- voice_or_data=None,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- toggle_apm_after_setting=False):
- """Ensure ad's current network is in expected rat_family.
- """
- if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
- network_preference, sub_id):
- ad.log.error("Set sub_id %s Preferred Networks Type %s failed.",
- sub_id, network_preference)
- return False
- if is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family,
- voice_or_data):
- ad.log.info("Sub_id %s in RAT %s for %s", sub_id, rat_family,
- voice_or_data)
- return True
-
- if toggle_apm_after_setting:
- toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- toggle_airplane_mode(log, ad, new_state=None, strict_checking=False)
-
- result = wait_for_network_rat_for_subscription(
- log, ad, sub_id, rat_family, max_wait_time, voice_or_data)
-
- log.info(
- "End of ensure_network_rat_for_subscription for %s. "
- "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
- "data: %s(family: %s)", ad.serial, network_preference, rat_family,
- voice_or_data,
- ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
- rat_family_from_rat(
- ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
- sub_id)),
- ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
- rat_family_from_rat(
- ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
- sub_id)))
- return result
-
-
-def ensure_network_preference(log,
- ad,
- network_preference,
- voice_or_data=None,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- toggle_apm_after_setting=False):
- """Ensure that current rat is within the device's preferred network rats.
- """
- return ensure_network_preference_for_subscription(
- log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
- voice_or_data, max_wait_time, toggle_apm_after_setting)
-
-
-def ensure_network_preference_for_subscription(
- log,
- ad,
- sub_id,
- network_preference,
- voice_or_data=None,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- toggle_apm_after_setting=False):
- """Ensure ad's network preference is <network_preference> for sub_id.
- """
- rat_family_list = rat_families_for_network_preference(network_preference)
- if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
- network_preference, sub_id):
- log.error("Set Preferred Networks failed.")
- return False
- if is_droid_in_rat_family_list_for_subscription(
- log, ad, sub_id, rat_family_list, voice_or_data):
- return True
-
- if toggle_apm_after_setting:
- toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)
-
- result = wait_for_preferred_network_for_subscription(
- log, ad, sub_id, network_preference, max_wait_time, voice_or_data)
-
- ad.log.info(
- "End of ensure_network_preference_for_subscription. "
- "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
- "data: %s(family: %s)", network_preference, rat_family_list,
- voice_or_data,
- ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
- rat_family_from_rat(
- ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
- sub_id)),
- ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
- rat_family_from_rat(
- ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
- sub_id)))
- return result
-
-
-def ensure_network_generation(log,
- ad,
- generation,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- voice_or_data=None,
- toggle_apm_after_setting=False):
- """Ensure ad's network is <network generation> for default subscription ID.
-
- Set preferred network generation to <generation>.
- Toggle ON/OFF airplane mode if necessary.
- Wait for ad in expected network type.
- """
- return ensure_network_generation_for_subscription(
- log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
- max_wait_time, voice_or_data, toggle_apm_after_setting)
-
-
-def ensure_network_generation_for_subscription(
- log,
- ad,
- sub_id,
- generation,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- voice_or_data=None,
- toggle_apm_after_setting=False):
- """Ensure ad's network is <network generation> for specified subscription ID.
-
- Set preferred network generation to <generation>.
- Toggle ON/OFF airplane mode if necessary.
- Wait for ad in expected network type.
-
- Args:
- log: log object.
- ad: android device object.
- sub_id: subscription id.
- generation: network generation, e.g. GEN_2G, GEN_3G, GEN_4G, GEN_5G.
- max_wait_time: the time to wait for NW selection.
- voice_or_data: check voice network generation or data network generation
- This parameter is optional. If voice_or_data is None, then if
- either voice or data in expected generation, function will return True.
- toggle_apm_after_setting: Cycle airplane mode if True, otherwise do nothing.
-
- Returns:
- True if success, False if fail.
- """
- ad.log.info(
- "RAT network type voice: %s, data: %s",
- ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
- ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id))
-
- try:
- ad.log.info("Finding the network preference for generation %s for "
- "operator %s phone type %s", generation,
- ad.telephony["subscription"][sub_id]["operator"],
- ad.telephony["subscription"][sub_id]["phone_type"])
- network_preference = network_preference_for_generation(
- generation, ad.telephony["subscription"][sub_id]["operator"],
- ad.telephony["subscription"][sub_id]["phone_type"])
- if ad.telephony["subscription"][sub_id]["operator"] == CARRIER_FRE \
- and generation == GEN_4G:
- network_preference = NETWORK_MODE_LTE_ONLY
- ad.log.info("Network preference for %s is %s", generation,
- network_preference)
- rat_family = rat_family_for_generation(
- generation, ad.telephony["subscription"][sub_id]["operator"],
- ad.telephony["subscription"][sub_id]["phone_type"])
- except KeyError as e:
- ad.log.error("Failed to find a rat_family entry for generation %s"
- " for subscriber id %s with error %s", generation,
- sub_id, e)
- return False
-
- if not set_preferred_network_mode_pref(log, ad, sub_id,
- network_preference):
- return False
-
- if hasattr(ad, "dsds") and voice_or_data == "data" and sub_id != get_default_data_sub_id(ad):
- ad.log.info("MSIM - Non DDS, ignore data RAT")
- return True
-
- if generation == GEN_5G:
- if is_current_network_5g_nsa_for_subscription(ad, sub_id=sub_id):
- ad.log.info("Current network type is 5G NSA.")
- return True
- else:
- ad.log.error("Not in 5G NSA coverage for Sub %s.", sub_id)
- return False
-
- if is_droid_in_network_generation_for_subscription(
- log, ad, sub_id, generation, voice_or_data):
- return True
-
- if toggle_apm_after_setting:
- toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)
-
- result = wait_for_network_generation_for_subscription(
- log, ad, sub_id, generation, max_wait_time, voice_or_data)
-
- ad.log.info(
- "Ensure network %s %s %s. With network preference %s, "
- "current: voice: %s(family: %s), data: %s(family: %s)", generation,
- voice_or_data, result, network_preference,
- ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
- rat_generation_from_rat(
- ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
- sub_id)),
- ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
- rat_generation_from_rat(
- ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
- sub_id)))
- if not result:
- get_telephony_signal_strength(ad)
- return result
-
-
-def wait_for_network_rat(log,
- ad,
- rat_family,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- voice_or_data=None):
- return wait_for_network_rat_for_subscription(
- log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
- max_wait_time, voice_or_data)
-
-
-def wait_for_network_rat_for_subscription(
- log,
- ad,
- sub_id,
- rat_family,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- voice_or_data=None):
- return _wait_for_droid_in_state_for_subscription(
- log, ad, sub_id, max_wait_time,
- is_droid_in_rat_family_for_subscription, rat_family, voice_or_data)
-
-
-def wait_for_not_network_rat(log,
- ad,
- rat_family,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- voice_or_data=None):
- return wait_for_not_network_rat_for_subscription(
- log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
- max_wait_time, voice_or_data)
-
-
-def wait_for_not_network_rat_for_subscription(
- log,
- ad,
- sub_id,
- rat_family,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- voice_or_data=None):
- return _wait_for_droid_in_state_for_subscription(
- log, ad, sub_id, max_wait_time,
- lambda log, ad, sub_id, *args, **kwargs: not is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family, voice_or_data)
- )
-
-
-def wait_for_preferred_network(log,
- ad,
- network_preference,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- voice_or_data=None):
- return wait_for_preferred_network_for_subscription(
- log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
- max_wait_time, voice_or_data)
-
-
-def wait_for_preferred_network_for_subscription(
- log,
- ad,
- sub_id,
- network_preference,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- voice_or_data=None):
- rat_family_list = rat_families_for_network_preference(network_preference)
- return _wait_for_droid_in_state_for_subscription(
- log, ad, sub_id, max_wait_time,
- is_droid_in_rat_family_list_for_subscription, rat_family_list,
- voice_or_data)
-
-
-def wait_for_network_generation(log,
- ad,
- generation,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- voice_or_data=None):
- return wait_for_network_generation_for_subscription(
- log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
- max_wait_time, voice_or_data)
-
-
-def wait_for_network_generation_for_subscription(
- log,
- ad,
- sub_id,
- generation,
- max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
- voice_or_data=None):
- return _wait_for_droid_in_state_for_subscription(
- log, ad, sub_id, max_wait_time,
- is_droid_in_network_generation_for_subscription, generation,
- voice_or_data)
-
-
def is_droid_in_rat_family(log, ad, rat_family, voice_or_data=None):
return is_droid_in_rat_family_for_subscription(
log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
@@ -7178,324 +2294,6 @@
return voice_mail_number
-def ensure_phones_idle(log, ads, max_time=MAX_WAIT_TIME_CALL_DROP):
- """Ensure ads idle (not in call).
- """
- result = True
- for ad in ads:
- if not ensure_phone_idle(log, ad, max_time=max_time):
- result = False
- return result
-
-
-def ensure_phone_idle(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP, retry=2):
- """Ensure ad idle (not in call).
- """
- while ad.droid.telecomIsInCall() and retry > 0:
- ad.droid.telecomEndCall()
- time.sleep(3)
- retry -= 1
- if not wait_for_droid_not_in_call(log, ad, max_time=max_time):
- ad.log.error("Failed to end call")
- return False
- return True
-
-
-def ensure_phone_subscription(log, ad):
- """Ensure Phone Subscription.
- """
- #check for sim and service
- duration = 0
- while duration < MAX_WAIT_TIME_NW_SELECTION:
- subInfo = ad.droid.subscriptionGetAllSubInfoList()
- if subInfo and len(subInfo) >= 1:
- ad.log.debug("Find valid subcription %s", subInfo)
- break
- else:
- ad.log.info("Did not find any subscription")
- time.sleep(5)
- duration += 5
- else:
- ad.log.error("Unable to find a valid subscription!")
- return False
- while duration < MAX_WAIT_TIME_NW_SELECTION:
- data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
- voice_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
- if data_sub_id > INVALID_SUB_ID or voice_sub_id > INVALID_SUB_ID:
- ad.log.debug("Find valid voice or data sub id")
- break
- else:
- ad.log.info("Did not find valid data or voice sub id")
- time.sleep(5)
- duration += 5
- else:
- ad.log.error("Unable to find valid data or voice sub id")
- return False
- while duration < MAX_WAIT_TIME_NW_SELECTION:
- data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
- if data_sub_id > INVALID_SUB_ID:
- data_rat = get_network_rat_for_subscription(
- log, ad, data_sub_id, NETWORK_SERVICE_DATA)
- else:
- data_rat = RAT_UNKNOWN
- if voice_sub_id > INVALID_SUB_ID:
- voice_rat = get_network_rat_for_subscription(
- log, ad, voice_sub_id, NETWORK_SERVICE_VOICE)
- else:
- voice_rat = RAT_UNKNOWN
- if data_rat != RAT_UNKNOWN or voice_rat != RAT_UNKNOWN:
- ad.log.info("Data sub_id %s in %s, voice sub_id %s in %s",
- data_sub_id, data_rat, voice_sub_id, voice_rat)
- return True
- else:
- ad.log.info("Did not attach for data or voice service")
- time.sleep(5)
- duration += 5
- else:
- ad.log.error("Did not attach for voice or data service")
- return False
-
-
-def ensure_phone_default_state(log, ad, check_subscription=True, retry=2):
- """Ensure ad in default state.
- Phone not in call.
- Phone have no stored WiFi network and WiFi disconnected.
- Phone not in airplane mode.
- """
- result = True
- if not toggle_airplane_mode(log, ad, False, False):
- ad.log.error("Fail to turn off airplane mode")
- result = False
- try:
- set_wifi_to_default(log, ad)
- while ad.droid.telecomIsInCall() and retry > 0:
- ad.droid.telecomEndCall()
- time.sleep(3)
- retry -= 1
- if not wait_for_droid_not_in_call(log, ad):
- ad.log.error("Failed to end call")
- #ad.droid.telephonyFactoryReset()
- data_roaming = getattr(ad, 'roaming', False)
- if get_cell_data_roaming_state_by_adb(ad) != data_roaming:
- set_cell_data_roaming_state_by_adb(ad, data_roaming)
- #remove_mobile_data_usage_limit(ad)
- if not wait_for_not_network_rat(
- log, ad, RAT_FAMILY_WLAN, voice_or_data=NETWORK_SERVICE_DATA):
- ad.log.error("%s still in %s", NETWORK_SERVICE_DATA,
- RAT_FAMILY_WLAN)
- result = False
-
- if check_subscription and not ensure_phone_subscription(log, ad):
- ad.log.error("Unable to find a valid subscription!")
- result = False
- except Exception as e:
- ad.log.error("%s failure, toggle APM instead", e)
- toggle_airplane_mode_by_adb(log, ad, True)
- toggle_airplane_mode_by_adb(log, ad, False)
- ad.send_keycode("ENDCALL")
- ad.adb.shell("settings put global wfc_ims_enabled 0")
- ad.adb.shell("settings put global mobile_data 1")
-
- return result
-
-
-def ensure_phones_default_state(log, ads, check_subscription=True):
- """Ensure ads in default state.
- Phone not in call.
- Phone have no stored WiFi network and WiFi disconnected.
- Phone not in airplane mode.
-
- Returns:
- True if all steps of restoring default state succeed.
- False if any of the steps to restore default state fails.
- """
- tasks = []
- for ad in ads:
- tasks.append((ensure_phone_default_state, (log, ad,
- check_subscription)))
- if not multithread_func(log, tasks):
- log.error("Ensure_phones_default_state Fail.")
- return False
- return True
-
-
-def check_is_wifi_connected(log, ad, wifi_ssid):
- """Check if ad is connected to wifi wifi_ssid.
-
- Args:
- log: Log object.
- ad: Android device object.
- wifi_ssid: WiFi network SSID.
-
- Returns:
- True if wifi is connected to wifi_ssid
- False if wifi is not connected to wifi_ssid
- """
- wifi_info = ad.droid.wifiGetConnectionInfo()
- if wifi_info["supplicant_state"] == "completed" and wifi_info["SSID"] == wifi_ssid:
- ad.log.info("Wifi is connected to %s", wifi_ssid)
- ad.on_mobile_data = False
- return True
- else:
- ad.log.info("Wifi is not connected to %s", wifi_ssid)
- ad.log.debug("Wifi connection_info=%s", wifi_info)
- ad.on_mobile_data = True
- return False
-
-
-def ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd=None, retries=3, apm=False):
- """Ensure ad connected to wifi on network wifi_ssid.
-
- Args:
- log: Log object.
- ad: Android device object.
- wifi_ssid: WiFi network SSID.
- wifi_pwd: optional secure network password.
- retries: the number of retries.
-
- Returns:
- True if wifi is connected to wifi_ssid
- False if wifi is not connected to wifi_ssid
- """
- if not toggle_airplane_mode(log, ad, apm, strict_checking=False):
- return False
-
- network = {WIFI_SSID_KEY: wifi_ssid}
- if wifi_pwd:
- network[WIFI_PWD_KEY] = wifi_pwd
- for i in range(retries):
- if not ad.droid.wifiCheckState():
- ad.log.info("Wifi state is down. Turn on Wifi")
- ad.droid.wifiToggleState(True)
- if check_is_wifi_connected(log, ad, wifi_ssid):
- ad.log.info("Wifi is connected to %s", wifi_ssid)
- return verify_internet_connection(log, ad, retries=3)
- else:
- ad.log.info("Connecting to wifi %s", wifi_ssid)
- try:
- ad.droid.wifiConnectByConfig(network)
- except Exception:
- ad.log.info("Connecting to wifi by wifiConnect instead")
- ad.droid.wifiConnect(network)
- time.sleep(20)
- if check_is_wifi_connected(log, ad, wifi_ssid):
- ad.log.info("Connected to Wifi %s", wifi_ssid)
- return verify_internet_connection(log, ad, retries=3)
- ad.log.info("Fail to connected to wifi %s", wifi_ssid)
- return False
-
-
-def forget_all_wifi_networks(log, ad):
- """Forget all stored wifi network information
-
- Args:
- log: log object
- ad: AndroidDevice object
-
- Returns:
- boolean success (True) or failure (False)
- """
- if not ad.droid.wifiGetConfiguredNetworks():
- ad.on_mobile_data = True
- return True
- try:
- old_state = ad.droid.wifiCheckState()
- wifi_test_utils.reset_wifi(ad)
- wifi_toggle_state(log, ad, old_state)
- except Exception as e:
- log.error("forget_all_wifi_networks with exception: %s", e)
- return False
- ad.on_mobile_data = True
- return True
-
-
-def wifi_reset(log, ad, disable_wifi=True):
- """Forget all stored wifi networks and (optionally) disable WiFi
-
- Args:
- log: log object
- ad: AndroidDevice object
- disable_wifi: boolean to disable wifi, defaults to True
- Returns:
- boolean success (True) or failure (False)
- """
- if not forget_all_wifi_networks(log, ad):
- ad.log.error("Unable to forget all networks")
- return False
- if not wifi_toggle_state(log, ad, not disable_wifi):
- ad.log.error("Failed to toggle WiFi state to %s!", not disable_wifi)
- return False
- return True
-
-
-def set_wifi_to_default(log, ad):
- """Set wifi to default state (Wifi disabled and no configured network)
-
- Args:
- log: log object
- ad: AndroidDevice object
-
- Returns:
- boolean success (True) or failure (False)
- """
- ad.droid.wifiFactoryReset()
- ad.droid.wifiToggleState(False)
- ad.on_mobile_data = True
-
-
-def wifi_toggle_state(log, ad, state, retries=3):
- """Toggle the WiFi State
-
- Args:
- log: log object
- ad: AndroidDevice object
- state: True, False, or None
-
- Returns:
- boolean success (True) or failure (False)
- """
- for i in range(retries):
- if wifi_test_utils.wifi_toggle_state(ad, state, assert_on_fail=False):
- ad.on_mobile_data = not state
- return True
- time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
- return False
-
-
-def start_wifi_tethering(log, ad, ssid, password, ap_band=None):
- """Start a Tethering Session
-
- Args:
- log: log object
- ad: AndroidDevice object
- ssid: the name of the WiFi network
- password: optional password, used for secure networks.
- ap_band=DEPRECATED specification of 2G or 5G tethering
- Returns:
- boolean success (True) or failure (False)
- """
- return wifi_test_utils._assert_on_fail_handler(
- wifi_test_utils.start_wifi_tethering,
- False,
- ad,
- ssid,
- password,
- band=ap_band)
-
-
-def stop_wifi_tethering(log, ad):
- """Stop a Tethering Session
-
- Args:
- log: log object
- ad: AndroidDevice object
- Returns:
- boolean success (True) or failure (False)
- """
- return wifi_test_utils._assert_on_fail_handler(
- wifi_test_utils.stop_wifi_tethering, False, ad)
-
-
def reset_preferred_network_type_to_allowable_range(log, ad):
"""If preferred network type is not in allowable range, reset to GEN_4G
preferred network type.
@@ -7522,109 +2320,6 @@
pass
-def task_wrapper(task):
- """Task wrapper for multithread_func
-
- Args:
- task[0]: function to be wrapped.
- task[1]: function args.
-
- Returns:
- Return value of wrapped function call.
- """
- func = task[0]
- params = task[1]
- return func(*params)
-
-
-def run_multithread_func_async(log, task):
- """Starts a multi-threaded function asynchronously.
-
- Args:
- log: log object.
- task: a task to be executed in parallel.
-
- Returns:
- Future object representing the execution of the task.
- """
- executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
- try:
- future_object = executor.submit(task_wrapper, task)
- except Exception as e:
- log.error("Exception error %s", e)
- raise
- return future_object
-
-
-def run_multithread_func(log, tasks):
- """Run multi-thread functions and return results.
-
- Args:
- log: log object.
- tasks: a list of tasks to be executed in parallel.
-
- Returns:
- results for tasks.
- """
- MAX_NUMBER_OF_WORKERS = 10
- number_of_workers = min(MAX_NUMBER_OF_WORKERS, len(tasks))
- executor = concurrent.futures.ThreadPoolExecutor(
- max_workers=number_of_workers)
- if not log: log = logging
- try:
- results = list(executor.map(task_wrapper, tasks))
- except Exception as e:
- log.error("Exception error %s", e)
- raise
- executor.shutdown()
- if log:
- log.info("multithread_func %s result: %s",
- [task[0].__name__ for task in tasks], results)
- return results
-
-
-def multithread_func(log, tasks):
- """Multi-thread function wrapper.
-
- Args:
- log: log object.
- tasks: tasks to be executed in parallel.
-
- Returns:
- True if all tasks return True.
- False if any task return False.
- """
- results = run_multithread_func(log, tasks)
- for r in results:
- if not r:
- return False
- return True
-
-
-def multithread_func_and_check_results(log, tasks, expected_results):
- """Multi-thread function wrapper.
-
- Args:
- log: log object.
- tasks: tasks to be executed in parallel.
- expected_results: check if the results from tasks match expected_results.
-
- Returns:
- True if expected_results are met.
- False if expected_results are not met.
- """
- return_value = True
- results = run_multithread_func(log, tasks)
- log.info("multithread_func result: %s, expecting %s", results,
- expected_results)
- for task, result, expected_result in zip(tasks, results, expected_results):
- if result != expected_result:
- logging.info("Result for task %s is %s, expecting %s", task[0],
- result, expected_result)
- return_value = False
- return return_value
-
-
def set_phone_screen_on(log, ad, screen_on_time=MAX_SCREEN_ON_TIME):
"""Set phone screen on time.
@@ -7701,61 +2396,6 @@
return False
-def set_preferred_subid_for_sms(log, ad, sub_id):
- """set subscription id for SMS
-
- Args:
- log: Log object.
- ad: Android device object.
- sub_id :Subscription ID.
-
- """
- ad.log.info("Setting subscription %s as preferred SMS SIM", sub_id)
- ad.droid.subscriptionSetDefaultSmsSubId(sub_id)
- # Wait to make sure settings take effect
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- return sub_id == ad.droid.subscriptionGetDefaultSmsSubId()
-
-
-def set_preferred_subid_for_data(log, ad, sub_id):
- """set subscription id for data
-
- Args:
- log: Log object.
- ad: Android device object.
- sub_id :Subscription ID.
-
- """
- ad.log.info("Setting subscription %s as preferred Data SIM", sub_id)
- ad.droid.subscriptionSetDefaultDataSubId(sub_id)
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- # Wait to make sure settings take effect
- # Data SIM change takes around 1 min
- # Check whether data has changed to selected sim
- if not wait_for_data_connection(log, ad, True,
- MAX_WAIT_TIME_DATA_SUB_CHANGE):
- log.error("Data Connection failed - Not able to switch Data SIM")
- return False
- return True
-
-
-def set_preferred_subid_for_voice(log, ad, sub_id):
- """set subscription id for voice
-
- Args:
- log: Log object.
- ad: Android device object.
- sub_id :Subscription ID.
-
- """
- ad.log.info("Setting subscription %s as Voice SIM", sub_id)
- ad.droid.subscriptionSetDefaultVoiceSubId(sub_id)
- ad.droid.telecomSetUserSelectedOutgoingPhoneAccountBySubId(sub_id)
- # Wait to make sure settings take effect
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- return True
-
-
def set_call_state_listen_level(log, ad, value, sub_id):
"""Set call state listen level for subscription id.
@@ -7780,34 +2420,6 @@
return True
-def setup_sim(log, ad, sub_id, voice=False, sms=False, data=False):
- """set subscription id for voice, sms and data
-
- Args:
- log: Log object.
- ad: Android device object.
- sub_id :Subscription ID.
- voice: True if to set subscription as default voice subscription
- sms: True if to set subscription as default sms subscription
- data: True if to set subscription as default data subscription
-
- """
- if sub_id == INVALID_SUB_ID:
- log.error("Invalid Subscription ID")
- return False
- else:
- if voice:
- if not set_preferred_subid_for_voice(log, ad, sub_id):
- return False
- if sms:
- if not set_preferred_subid_for_sms(log, ad, sub_id):
- return False
- if data:
- if not set_preferred_subid_for_data(log, ad, sub_id):
- return False
- return True
-
-
def is_event_match(event, field, value):
"""Return if <field> in "event" match <value> or not.
@@ -7954,467 +2566,6 @@
return None
-def find_qxdm_log_mask(ad, mask="default.cfg"):
- """Find QXDM logger mask."""
- if "/" not in mask:
- # Call nexuslogger to generate log mask
- start_nexuslogger(ad)
- # Find the log mask path
- for path in (DEFAULT_QXDM_LOG_PATH, "/data/diag_logs",
- "/vendor/etc/mdlog/", "/vendor/etc/modem/"):
- out = ad.adb.shell(
- "find %s -type f -iname %s" % (path, mask), ignore_status=True)
- if out and "No such" not in out and "Permission denied" not in out:
- if path.startswith("/vendor/"):
- setattr(ad, "qxdm_log_path", DEFAULT_QXDM_LOG_PATH)
- else:
- setattr(ad, "qxdm_log_path", path)
- return out.split("\n")[0]
- for mask_file in ("/vendor/etc/mdlog/", "/vendor/etc/modem/"):
- if mask in ad.adb.shell("ls %s" % mask_file, ignore_status=True):
- setattr(ad, "qxdm_log_path", DEFAULT_QXDM_LOG_PATH)
- return "%s/%s" % (mask_file, mask)
- else:
- out = ad.adb.shell("ls %s" % mask, ignore_status=True)
- if out and "No such" not in out:
- qxdm_log_path, cfg_name = os.path.split(mask)
- setattr(ad, "qxdm_log_path", qxdm_log_path)
- return mask
- ad.log.warning("Could NOT find QXDM logger mask path for %s", mask)
-
-
-def set_qxdm_logger_command(ad, mask=None):
- """Set QXDM logger always on.
-
- Args:
- ad: android device object.
-
- """
- ## Neet to check if log mask will be generated without starting nexus logger
- masks = []
- mask_path = None
- if mask:
- masks = [mask]
- masks.extend(["QC_Default.cfg", "default.cfg"])
- for mask in masks:
- mask_path = find_qxdm_log_mask(ad, mask)
- if mask_path: break
- if not mask_path:
- ad.log.error("Cannot find QXDM mask %s", mask)
- ad.qxdm_logger_command = None
- return False
- else:
- ad.log.info("Use QXDM log mask %s", mask_path)
- ad.log.debug("qxdm_log_path = %s", ad.qxdm_log_path)
- output_path = os.path.join(ad.qxdm_log_path, "logs")
- ad.qxdm_logger_command = ("diag_mdlog -f %s -o %s -s 90 -c" %
- (mask_path, output_path))
- return True
-
-
-
-def start_sdm_logger(ad):
- """Start SDM logger."""
- if not getattr(ad, "sdm_log", True): return
- # Delete existing SDM logs which were created 15 mins prior
- ad.sdm_log_path = DEFAULT_SDM_LOG_PATH
- file_count = ad.adb.shell(
- "find %s -type f -iname sbuff_[0-9]*.sdm* | wc -l" % ad.sdm_log_path)
- if int(file_count) > 3:
- seconds = 15 * 60
- # Remove sdm logs modified more than specified seconds ago
- ad.adb.shell(
- "find %s -type f -iname sbuff_[0-9]*.sdm* -not -mtime -%ss -delete" %
- (ad.sdm_log_path, seconds))
- # Disable any modem logging already running
- ad.adb.shell("setprop persist.vendor.sys.modem.logging.enable false")
- ad.adb.shell('echo "modem_logging_control START -n 10 -s 100 -i 1" > /data/vendor/radio/logs/always-on.conf')
- # start logging
- cmd = "setprop vendor.sys.modem.logging.enable true"
- ad.log.debug("start sdm logging")
- ad.adb.shell(cmd, ignore_status=True)
- time.sleep(5)
-
-
-def stop_sdm_logger(ad):
- """Stop SDM logger."""
- cmd = "setprop vendor.sys.modem.logging.enable false"
- ad.log.debug("stop sdm logging")
- ad.adb.shell(cmd, ignore_status=True)
- time.sleep(5)
-
-
-def stop_qxdm_logger(ad):
- """Stop QXDM logger."""
- for cmd in ("diag_mdlog -k", "killall diag_mdlog"):
- output = ad.adb.shell("ps -ef | grep mdlog") or ""
- if "diag_mdlog" not in output:
- break
- ad.log.debug("Kill the existing qxdm process")
- ad.adb.shell(cmd, ignore_status=True)
- time.sleep(5)
-
-
-def start_qxdm_logger(ad, begin_time=None):
- """Start QXDM logger."""
- if not getattr(ad, "qxdm_log", True): return
- # Delete existing QXDM logs 5 minutes earlier than the begin_time
- current_time = get_current_epoch_time()
- if getattr(ad, "qxdm_log_path", None):
- seconds = None
- file_count = ad.adb.shell(
- "find %s -type f -iname *.qmdl | wc -l" % ad.qxdm_log_path)
- if int(file_count) > 50:
- if begin_time:
- # if begin_time specified, delete old qxdm logs modified
- # 10 minutes before begin time
- seconds = int((current_time - begin_time) / 1000.0) + 10 * 60
- else:
- # if begin_time is not specified, delete old qxdm logs modified
- # 15 minutes before current time
- seconds = 15 * 60
- if seconds:
- # Remove qxdm logs modified more than specified seconds ago
- ad.adb.shell(
- "find %s -type f -iname *.qmdl -not -mtime -%ss -delete" %
- (ad.qxdm_log_path, seconds))
- ad.adb.shell(
- "find %s -type f -iname *.xml -not -mtime -%ss -delete" %
- (ad.qxdm_log_path, seconds))
- if getattr(ad, "qxdm_logger_command", None):
- output = ad.adb.shell("ps -ef | grep mdlog") or ""
- if ad.qxdm_logger_command not in output:
- ad.log.debug("QXDM logging command %s is not running",
- ad.qxdm_logger_command)
- if "diag_mdlog" in output:
- # Kill the existing non-matching diag_mdlog process
- # Only one diag_mdlog process can be run
- stop_qxdm_logger(ad)
- ad.log.info("Start QXDM logger")
- ad.adb.shell_nb(ad.qxdm_logger_command)
- time.sleep(10)
- else:
- run_time = check_qxdm_logger_run_time(ad)
- if run_time < 600:
- # the last diag_mdlog started within 10 minutes ago
- # no need to restart
- return True
- if ad.search_logcat(
- "Diag_Lib: diag: In delete_log",
- begin_time=current_time -
- run_time) or not ad.get_file_names(
- ad.qxdm_log_path,
- begin_time=current_time - 600000,
- match_string="*.qmdl"):
- # diag_mdlog starts deleting files or no qmdl logs were
- # modified in the past 10 minutes
- ad.log.debug("Quit existing diag_mdlog and start a new one")
- stop_qxdm_logger(ad)
- ad.adb.shell_nb(ad.qxdm_logger_command)
- time.sleep(10)
- return True
-
-
-def disable_qxdm_logger(ad):
- for prop in ("persist.sys.modem.diag.mdlog",
- "persist.vendor.sys.modem.diag.mdlog",
- "vendor.sys.modem.diag.mdlog_on"):
- if ad.adb.getprop(prop):
- ad.adb.shell("setprop %s false" % prop, ignore_status=True)
- for apk in ("com.android.nexuslogger", "com.android.pixellogger"):
- if ad.is_apk_installed(apk) and ad.is_apk_running(apk):
- ad.force_stop_apk(apk)
- stop_qxdm_logger(ad)
- return True
-
-
-def check_qxdm_logger_run_time(ad):
- output = ad.adb.shell("ps -eo etime,cmd | grep diag_mdlog")
- result = re.search(r"(\d+):(\d+):(\d+) diag_mdlog", output)
- if result:
- return int(result.group(1)) * 60 * 60 + int(
- result.group(2)) * 60 + int(result.group(3))
- else:
- result = re.search(r"(\d+):(\d+) diag_mdlog", output)
- if result:
- return int(result.group(1)) * 60 + int(result.group(2))
- else:
- return 0
-
-
-def start_qxdm_loggers(log, ads, begin_time=None):
- tasks = [(start_qxdm_logger, [ad, begin_time]) for ad in ads
- if getattr(ad, "qxdm_log", True)]
- if tasks: run_multithread_func(log, tasks)
-
-
-def stop_qxdm_loggers(log, ads):
- tasks = [(stop_qxdm_logger, [ad]) for ad in ads]
- run_multithread_func(log, tasks)
-
-
-def start_sdm_loggers(log, ads):
- tasks = [(start_sdm_logger, [ad]) for ad in ads
- if getattr(ad, "sdm_log", True)]
- if tasks: run_multithread_func(log, tasks)
-
-
-def stop_sdm_loggers(log, ads):
- tasks = [(stop_sdm_logger, [ad]) for ad in ads]
- run_multithread_func(log, tasks)
-
-
-def start_nexuslogger(ad):
- """Start Nexus/Pixel Logger Apk."""
- qxdm_logger_apk = None
- for apk, activity in (("com.android.nexuslogger", ".MainActivity"),
- ("com.android.pixellogger",
- ".ui.main.MainActivity")):
- if ad.is_apk_installed(apk):
- qxdm_logger_apk = apk
- break
- if not qxdm_logger_apk: return
- if ad.is_apk_running(qxdm_logger_apk):
- if "granted=true" in ad.adb.shell(
- "dumpsys package %s | grep WRITE_EXTERN" % qxdm_logger_apk):
- return True
- else:
- ad.log.info("Kill %s" % qxdm_logger_apk)
- ad.force_stop_apk(qxdm_logger_apk)
- time.sleep(5)
- for perm in ("READ", "WRITE"):
- ad.adb.shell("pm grant %s android.permission.%s_EXTERNAL_STORAGE" %
- (qxdm_logger_apk, perm))
- time.sleep(2)
- for i in range(3):
- ad.unlock_screen()
- ad.log.info("Start %s Attempt %d" % (qxdm_logger_apk, i + 1))
- ad.adb.shell("am start -n %s/%s" % (qxdm_logger_apk, activity))
- time.sleep(5)
- if ad.is_apk_running(qxdm_logger_apk):
- ad.send_keycode("HOME")
- return True
- return False
-
-
-def check_qxdm_logger_mask(ad, mask_file="QC_Default.cfg"):
- """Check if QXDM logger always on is set.
-
- Args:
- ad: android device object.
-
- """
- output = ad.adb.shell(
- "ls /data/vendor/radio/diag_logs/", ignore_status=True)
- if not output or "No such" in output:
- return True
- if mask_file not in ad.adb.shell(
- "cat /data/vendor/radio/diag_logs/diag.conf", ignore_status=True):
- return False
- return True
-
-
-def start_tcpdumps(ads,
- test_name="",
- begin_time=None,
- interface="any",
- mask="all"):
- for ad in ads:
- try:
- start_adb_tcpdump(
- ad,
- test_name=test_name,
- begin_time=begin_time,
- interface=interface,
- mask=mask)
- except Exception as e:
- ad.log.warning("Fail to start tcpdump due to %s", e)
-
-
-def start_adb_tcpdump(ad,
- test_name="",
- begin_time=None,
- interface="any",
- mask="all"):
- """Start tcpdump on any iface
-
- Args:
- ad: android device object.
- test_name: tcpdump file name will have this
-
- """
- out = ad.adb.shell("ls -l /data/local/tmp/tcpdump/", ignore_status=True)
- if "No such file" in out or not out:
- ad.adb.shell("mkdir /data/local/tmp/tcpdump")
- else:
- ad.adb.shell(
- "find /data/local/tmp/tcpdump -type f -not -mtime -1800s -delete",
- ignore_status=True)
- ad.adb.shell(
- "find /data/local/tmp/tcpdump -type f -size +5G -delete",
- ignore_status=True)
-
- if not begin_time:
- begin_time = get_current_epoch_time()
-
- out = ad.adb.shell(
- 'ifconfig | grep -v -E "r_|-rmnet" | grep -E "lan|data"',
- ignore_status=True,
- timeout=180)
- intfs = re.findall(r"(\S+).*", out)
- if interface and interface not in ("any", "all"):
- if interface not in intfs: return
- intfs = [interface]
-
- out = ad.adb.shell("ps -ef | grep tcpdump")
- cmds = []
- for intf in intfs:
- if intf in out:
- ad.log.info("tcpdump on interface %s is already running", intf)
- continue
- else:
- log_file_name = "/data/local/tmp/tcpdump/tcpdump_%s_%s_%s_%s.pcap" \
- % (ad.serial, intf, test_name, begin_time)
- if mask == "ims":
- cmds.append(
- "adb -s %s shell tcpdump -i %s -s0 -n -p udp port 500 or "
- "udp port 4500 -w %s" % (ad.serial, intf, log_file_name))
- else:
- cmds.append("adb -s %s shell tcpdump -i %s -s0 -w %s" %
- (ad.serial, intf, log_file_name))
- if not gutils.check_chipset_vendor_by_qualcomm(ad):
- log_file_name = ("/data/local/tmp/tcpdump/tcpdump_%s_any_%s_%s.pcap"
- % (ad.serial, test_name, begin_time))
- cmds.append("adb -s %s shell nohup tcpdump -i any -s0 -w %s" %
- (ad.serial, log_file_name))
- for cmd in cmds:
- ad.log.info(cmd)
- try:
- start_standing_subprocess(cmd, 10)
- except Exception as e:
- ad.log.error(e)
- if cmds:
- time.sleep(5)
-
-
-def stop_tcpdumps(ads):
- for ad in ads:
- stop_adb_tcpdump(ad)
-
-
-def stop_adb_tcpdump(ad, interface="any"):
- """Stops tcpdump on any iface
- Pulls the tcpdump file in the tcpdump dir
-
- Args:
- ad: android device object.
-
- """
- if interface == "any":
- try:
- ad.adb.shell("killall -9 tcpdump", ignore_status=True)
- except Exception as e:
- ad.log.error("Killing tcpdump with exception %s", e)
- else:
- out = ad.adb.shell("ps -ef | grep tcpdump | grep %s" % interface)
- if "tcpdump -i" in out:
- pids = re.findall(r"\S+\s+(\d+).*tcpdump -i", out)
- for pid in pids:
- ad.adb.shell("kill -9 %s" % pid)
- ad.adb.shell(
- "find /data/local/tmp/tcpdump -type f -not -mtime -1800s -delete",
- ignore_status=True)
-
-
-def get_tcpdump_log(ad, test_name="", begin_time=None):
- """Stops tcpdump on any iface
- Pulls the tcpdump file in the tcpdump dir
- Zips all tcpdump files
-
- Args:
- ad: android device object.
- test_name: test case name
- begin_time: test begin time
- """
- logs = ad.get_file_names("/data/local/tmp/tcpdump", begin_time=begin_time)
- if logs:
- ad.log.info("Pulling tcpdumps %s", logs)
- log_path = os.path.join(
- ad.device_log_path, "TCPDUMP_%s_%s" % (ad.model, ad.serial))
- os.makedirs(log_path, exist_ok=True)
- ad.pull_files(logs, log_path)
- shutil.make_archive(log_path, "zip", log_path)
- shutil.rmtree(log_path)
- return True
-
-
-def fastboot_wipe(ad, skip_setup_wizard=True):
- """Wipe the device in fastboot mode.
-
- Pull sl4a apk from device. Terminate all sl4a sessions,
- Reboot the device to bootloader, wipe the device by fastboot.
- Reboot the device. wait for device to complete booting
- Re-intall and start an sl4a session.
- """
- status = True
- # Pull sl4a apk from device
- out = ad.adb.shell("pm path %s" % SL4A_APK_NAME)
- result = re.search(r"package:(.*)", out)
- if not result:
- ad.log.error("Couldn't find sl4a apk")
- else:
- sl4a_apk = result.group(1)
- ad.log.info("Get sl4a apk from %s", sl4a_apk)
- ad.pull_files([sl4a_apk], "/tmp/")
- ad.stop_services()
- attemps = 3
- for i in range(1, attemps + 1):
- try:
- if ad.serial in list_adb_devices():
- ad.log.info("Reboot to bootloader")
- ad.adb.reboot("bootloader", ignore_status=True)
- time.sleep(10)
- if ad.serial in list_fastboot_devices():
- ad.log.info("Wipe in fastboot")
- ad.fastboot._w(timeout=300, ignore_status=True)
- time.sleep(30)
- ad.log.info("Reboot in fastboot")
- ad.fastboot.reboot()
- ad.wait_for_boot_completion()
- ad.root_adb()
- if ad.skip_sl4a:
- break
- if ad.is_sl4a_installed():
- break
- ad.log.info("Re-install sl4a")
- ad.adb.shell("settings put global verifier_verify_adb_installs 0")
- ad.adb.install("-r /tmp/base.apk")
- time.sleep(10)
- break
- except Exception as e:
- ad.log.warning(e)
- if i == attemps:
- abort_all_tests(log, str(e))
- time.sleep(5)
- try:
- ad.start_adb_logcat()
- except:
- ad.log.error("Failed to start adb logcat!")
- if skip_setup_wizard:
- ad.exit_setup_wizard()
- if getattr(ad, "qxdm_log", True):
- set_qxdm_logger_command(ad, mask=getattr(ad, "qxdm_log_mask", None))
- start_qxdm_logger(ad)
- if ad.skip_sl4a: return status
- bring_up_sl4a(ad)
- synchronize_device_time(ad)
- set_phone_silent_mode(ad.log, ad)
- # Activate WFC on Verizon, AT&T and Canada operators as per # b/33187374 &
- # b/122327716
- activate_wfc_on_device(ad.log, ad)
- return status
-
-
def install_carriersettings_apk(ad, carriersettingsapk, skip_setup_wizard=True):
""" Carrier Setting Installation Steps
@@ -8527,54 +2678,6 @@
bring_up_sl4a(ad)
-def reset_device_password(ad, device_password=None):
- # Enable or Disable Device Password per test bed config
- unlock_sim(ad)
- screen_lock = ad.is_screen_lock_enabled()
- if device_password:
- try:
- refresh_sl4a_session(ad)
- ad.droid.setDevicePassword(device_password)
- except Exception as e:
- ad.log.warning("setDevicePassword failed with %s", e)
- try:
- ad.droid.setDevicePassword(device_password, "1111")
- except Exception as e:
- ad.log.warning(
- "setDevicePassword providing previous password error: %s",
- e)
- time.sleep(2)
- if screen_lock:
- # existing password changed
- return
- else:
- # enable device password and log in for the first time
- ad.log.info("Enable device password")
- ad.adb.wait_for_device(timeout=180)
- else:
- if not screen_lock:
- # no existing password, do not set password
- return
- else:
- # password is enabled on the device
- # need to disable the password and log in on the first time
- # with unlocking with a swipe
- ad.log.info("Disable device password")
- ad.unlock_screen(password="1111")
- refresh_sl4a_session(ad)
- ad.ensure_screen_on()
- try:
- ad.droid.disableDevicePassword()
- except Exception as e:
- ad.log.warning("disableDevicePassword failed with %s", e)
- fastboot_wipe(ad)
- time.sleep(2)
- ad.adb.wait_for_device(timeout=180)
- refresh_sl4a_session(ad)
- if not ad.is_adb_logcat_on:
- ad.start_adb_logcat()
-
-
def get_sim_state(ad):
try:
state = ad.droid.telephonyGetSimState()
@@ -8766,47 +2869,6 @@
return True
-def flash_radio(ad, file_path, skip_setup_wizard=True):
- """Flash radio image."""
- ad.stop_services()
- ad.log.info("Reboot to bootloader")
- ad.adb.reboot_bootloader(ignore_status=True)
- ad.log.info("Flash radio in fastboot")
- try:
- ad.fastboot.flash("radio %s" % file_path, timeout=300)
- except Exception as e:
- ad.log.error(e)
- ad.fastboot.reboot("bootloader")
- time.sleep(5)
- output = ad.fastboot.getvar("version-baseband")
- result = re.search(r"version-baseband: (\S+)", output)
- if not result:
- ad.log.error("fastboot getvar version-baseband output = %s", output)
- abort_all_tests(ad.log, "Radio version-baseband is not provided")
- fastboot_radio_version_output = result.group(1)
- for _ in range(2):
- try:
- ad.log.info("Reboot in fastboot")
- ad.fastboot.reboot()
- ad.wait_for_boot_completion()
- break
- except Exception as e:
- ad.log.error("Exception error %s", e)
- ad.root_adb()
- adb_radio_version_output = ad.adb.getprop("gsm.version.baseband")
- ad.log.info("adb getprop gsm.version.baseband = %s",
- adb_radio_version_output)
- if adb_radio_version_output != fastboot_radio_version_output:
- msg = ("fastboot radio version output %s does not match with adb"
- " radio version output %s" % (fastboot_radio_version_output,
- adb_radio_version_output))
- abort_all_tests(ad.log, msg)
- if not ad.ensure_screen_on():
- ad.log.error("User window cannot come up")
- ad.start_services(skip_setup_wizard=skip_setup_wizard)
- unlock_sim(ad)
-
-
def set_preferred_apn_by_adb(ad, pref_apn_name):
"""Select Pref APN
Set Preferred APN on UI using content query/insert
@@ -8885,6 +2947,101 @@
return False
+def power_off_sim_by_adb(ad, sim_slot_id,
+ timeout=MAX_WAIT_TIME_FOR_STATE_CHANGE):
+ """Disable pSIM/eSIM SUB by adb command.
+
+ Args:
+ ad: android device object.
+ sim_slot_id: slot 0 or slot 1.
+ timeout: wait time for state change.
+
+ Returns:
+ True if success, False otherwise.
+ """
+ release_version = int(ad.adb.getprop("ro.build.version.release"))
+ if sim_slot_id == 0 and release_version < 12:
+ ad.log.error(
+ "The disable pSIM SUB command only support for Android S or higher "
+ "version, abort test.")
+ raise signals.TestSkip(
+ "The disable pSIM SUB command only support for Android S or higher "
+ "version, abort test.")
+ try:
+ if sim_slot_id:
+ ad.adb.shell("am broadcast -a android.telephony.euicc.action."
+ "TEST_PROFILE -n com.google.android.euicc/com.android.euicc."
+ "receiver.ProfileTestReceiver --es 'operation' 'switch' --ei "
+ "'subscriptionId' -1")
+ else:
+ sub_id = get_subid_by_adb(ad, sim_slot_id)
+ # The command only support for Android S. (b/159605922)
+ ad.adb.shell(
+ "cmd phone disable-physical-subscription %d" % sub_id)
+ except Exception as e:
+ ad.log.error(e)
+ return False
+ while timeout > 0:
+ if get_subid_by_adb(ad, sim_slot_id) == INVALID_SUB_ID:
+ return True
+ timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK
+ time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
+ sim_state = ad.adb.getprop("gsm.sim.state").split(",")
+ ad.log.warning("Fail to power off SIM slot %d, sim_state=%s",
+ sim_slot_id, sim_state[sim_slot_id])
+ return False
+
+
+def power_on_sim_by_adb(ad, sim_slot_id,
+ timeout=MAX_WAIT_TIME_FOR_STATE_CHANGE):
+ """Enable pSIM/eSIM SUB by adb command.
+
+ Args:
+ ad: android device object.
+ sim_slot_id: slot 0 or slot 1.
+ timeout: wait time for state change.
+
+ Returns:
+ True if success, False otherwise.
+ """
+ release_version = int(ad.adb.getprop("ro.build.version.release"))
+ if sim_slot_id == 0 and release_version < 12:
+ ad.log.error(
+ "The enable pSIM SUB command only support for Android S or higher "
+ "version, abort test.")
+ raise signals.TestSkip(
+ "The enable pSIM SUB command only support for Android S or higher "
+ "version, abort test.")
+ try:
+ output = ad.adb.shell(
+ "dumpsys isub | grep addSubInfoRecord | grep slotIndex=%d" %
+ sim_slot_id)
+ pattern = re.compile(r"subId=(\d+)")
+ sub_id = pattern.findall(output)
+ sub_id = int(sub_id[-1]) if sub_id else INVALID_SUB_ID
+ if sim_slot_id:
+ ad.adb.shell("am broadcast -a android.telephony.euicc.action."
+ "TEST_PROFILE -n com.google.android.euicc/com.android.euicc."
+ "receiver.ProfileTestReceiver --es 'operation' 'switch' --ei "
+ "'subscriptionId' %d" % sub_id)
+ else:
+ # The command only support for Android S or higher. (b/159605922)
+ ad.adb.shell(
+ "cmd phone enable-physical-subscription %d" % sub_id)
+ except Exception as e:
+ ad.log.error(e)
+ return False
+ while timeout > 0:
+ if get_subid_by_adb(ad, sim_slot_id) != INVALID_SUB_ID:
+ return True
+ timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK
+ time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
+ sim_state = ad.adb.getprop("gsm.sim.state").split(",")
+ ad.log.warning("Fail to power on SIM slot %d, sim_state=%s",
+ sim_slot_id, sim_state[sim_slot_id])
+ return False
+
+
def power_off_sim(ad, sim_slot_id=None,
timeout=MAX_WAIT_TIME_FOR_STATE_CHANGE):
try:
@@ -8902,7 +3059,8 @@
return False
while timeout > 0:
sim_state = verify_func(*verify_args)
- if sim_state in (SIM_STATE_UNKNOWN, SIM_STATE_ABSENT):
+ if sim_state in (
+ SIM_STATE_UNKNOWN, SIM_STATE_ABSENT, SIM_STATE_NOT_READY):
ad.log.info("SIM slot is powered off, SIM state is %s", sim_state)
return True
timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK
@@ -8938,27 +3096,6 @@
return False
-def extract_test_log(log, src_file, dst_file, test_tag):
- os.makedirs(os.path.dirname(dst_file), exist_ok=True)
- cmd = "grep -n '%s' %s" % (test_tag, src_file)
- result = job.run(cmd, ignore_status=True)
- if not result.stdout or result.exit_status == 1:
- log.warning("Command %s returns %s", cmd, result)
- return
- line_nums = re.findall(r"(\d+).*", result.stdout)
- if line_nums:
- begin_line = int(line_nums[0])
- end_line = int(line_nums[-1])
- if end_line - begin_line <= 5:
- result = job.run("wc -l < %s" % src_file)
- if result.stdout:
- end_line = int(result.stdout)
- log.info("Extract %s from line %s to line %s to %s", src_file,
- begin_line, end_line, dst_file)
- job.run("awk 'NR >= %s && NR <= %s' %s > %s" % (begin_line, end_line,
- src_file, dst_file))
-
-
def get_device_epoch_time(ad):
return int(1000 * float(ad.adb.shell("date +%s.%N")))
@@ -9033,47 +3170,6 @@
return result
-def log_messaging_screen_shot(ad, test_name=""):
- ad.ensure_screen_on()
- ad.send_keycode("HOME")
- ad.adb.shell("am start -n com.google.android.apps.messaging/.ui."
- "ConversationListActivity")
- time.sleep(3)
- log_screen_shot(ad, test_name)
- ad.adb.shell("am start -n com.google.android.apps.messaging/com.google."
- "android.apps.messaging.ui.conversation."
- "LaunchConversationShimActivity -e conversation_id 1")
- time.sleep(3)
- log_screen_shot(ad, test_name)
- ad.send_keycode("HOME")
-
-
-def log_screen_shot(ad, test_name=""):
- file_name = "/sdcard/Pictures/screencap"
- if test_name:
- file_name = "%s_%s" % (file_name, test_name)
- file_name = "%s_%s.png" % (file_name, utils.get_current_epoch_time())
- try:
- ad.adb.shell("screencap -p %s" % file_name)
- except:
- ad.log.error("Fail to log screen shot to %s", file_name)
-
-
-def get_screen_shot_log(ad, test_name="", begin_time=None):
- logs = ad.get_file_names("/sdcard/Pictures", begin_time=begin_time)
- if logs:
- ad.log.info("Pulling %s", logs)
- log_path = os.path.join(ad.device_log_path, "Screenshot_%s" % ad.serial)
- os.makedirs(log_path, exist_ok=True)
- ad.pull_files(logs, log_path)
- ad.adb.shell("rm -rf /sdcard/Pictures/screencap_*", ignore_status=True)
-
-
-def get_screen_shot_logs(ads, test_name="", begin_time=None):
- for ad in ads:
- get_screen_shot_log(ad, test_name=test_name, begin_time=begin_time)
-
-
def get_carrier_id_version(ad):
out = ad.adb.shell("dumpsys activity service TelephonyDebugService | " \
"grep -i carrier_list_version")
@@ -9133,6 +3229,72 @@
ad.log.error("Failed to add google account - %s", output)
return False
+def install_apk(ad, apk_path, app_package_name):
+ """Install assigned apk to specific device.
+
+ Args:
+ ad: android device object
+ apk_path: The path of apk (please refer to the "Resources" section in
+ go/mhbe-resources for supported file stores.)
+ app_package_name: package name of the application
+
+ Returns:
+ True if success, False if fail.
+ """
+ ad.log.info("Install %s from %s", app_package_name, apk_path)
+ ad.adb.install("-r -g %s" % apk_path, timeout=300, ignore_status=True)
+ time.sleep(3)
+ if not ad.is_apk_installed(app_package_name):
+ ad.log.info("%s is not installed.", app_package_name)
+ return False
+ if ad.get_apk_version(app_package_name):
+ ad.log.info("Current version of %s: %s", app_package_name,
+ ad.get_apk_version(app_package_name))
+ return True
+
+def install_dialer_apk(ad, dialer_util):
+ """Install dialer.apk to specific device.
+
+ Args:
+ ad: android device object.
+ dialer_util: path of dialer.apk
+
+ Returns:
+ True if success, False if fail.
+ """
+ ad.log.info("Install dialer_util %s", dialer_util)
+ ad.adb.install("-r -g %s" % dialer_util, timeout=300, ignore_status=True)
+ time.sleep(3)
+ if not ad.is_apk_installed(DIALER_PACKAGE_NAME):
+ ad.log.info("%s is not installed", DIALER_PACKAGE_NAME)
+ return False
+ if ad.get_apk_version(DIALER_PACKAGE_NAME):
+ ad.log.info("Current version of %s: %s", DIALER_PACKAGE_NAME,
+ ad.get_apk_version(DIALER_PACKAGE_NAME))
+ return True
+
+
+def install_message_apk(ad, message_util):
+ """Install message.apk to specific device.
+
+ Args:
+ ad: android device object.
+ message_util: path of message.apk
+
+ Returns:
+ True if success, False if fail.
+ """
+ ad.log.info("Install message_util %s", message_util)
+ ad.adb.install("-r -g %s" % message_util, timeout=300, ignore_status=True)
+ time.sleep(3)
+ if not ad.is_apk_installed(MESSAGE_PACKAGE_NAME):
+ ad.log.info("%s is not installed", MESSAGE_PACKAGE_NAME)
+ return False
+ if ad.get_apk_version(MESSAGE_PACKAGE_NAME):
+ ad.log.info("Current version of %s: %s", MESSAGE_PACKAGE_NAME,
+ ad.get_apk_version(MESSAGE_PACKAGE_NAME))
+ return True
+
def install_googleaccountutil_apk(ad, account_util):
ad.log.info("Install account_util %s", account_util)
@@ -9476,380 +3638,6 @@
return monitor_setting == expected_monitor_setting
-def get_call_forwarding_by_adb(log, ad, call_forwarding_type="unconditional"):
- """ Get call forwarding status by adb shell command
- 'dumpsys telephony.registry'.
-
- Args:
- log: log object
- ad: android object
- call_forwarding_type:
- - "unconditional"
- - "busy" (todo)
- - "not_answered" (todo)
- - "not_reachable" (todo)
- Returns:
- - "true": if call forwarding unconditional is enabled.
- - "false": if call forwarding unconditional is disabled.
- - "unknown": if the type is other than 'unconditional'.
- - False: any case other than above 3 cases.
- """
- if call_forwarding_type != "unconditional":
- return "unknown"
-
- slot_index_of_default_voice_subid = get_slot_index_from_subid(log, ad,
- get_incoming_voice_sub_id(ad))
- output = ad.adb.shell("dumpsys telephony.registry | grep mCallForwarding")
- if "mCallForwarding" in output:
- result_list = re.findall(r"mCallForwarding=(true|false)", output)
- if result_list:
- result = result_list[slot_index_of_default_voice_subid]
- ad.log.info("mCallForwarding is %s", result)
-
- if re.search("false", result, re.I):
- return "false"
- elif re.search("true", result, re.I):
- return "true"
- else:
- return False
- else:
- return False
- else:
- ad.log.error("'mCallForwarding' cannot be found in dumpsys.")
- return False
-
-
-def erase_call_forwarding_by_mmi(
- log,
- ad,
- retry=2,
- call_forwarding_type="unconditional"):
- """ Erase setting of call forwarding (erase the number and disable call
- forwarding) by MMI code.
-
- Args:
- log: log object
- ad: android object
- retry: times of retry if the erasure failed.
- call_forwarding_type:
- - "unconditional"
- - "busy"
- - "not_answered"
- - "not_reachable"
- Returns:
- True by successful erasure. Otherwise False.
- """
- operator_name = get_operator_name(log, ad)
-
- run_get_call_forwarding_by_adb = 1
- if operator_name in NOT_CHECK_MCALLFORWARDING_OPERATOR_LIST:
- run_get_call_forwarding_by_adb = 0
-
- if run_get_call_forwarding_by_adb:
- res = get_call_forwarding_by_adb(log, ad,
- call_forwarding_type=call_forwarding_type)
- if res == "false":
- return True
-
- user_config_profile = get_user_config_profile(ad)
- is_airplane_mode = user_config_profile["Airplane Mode"]
- is_wfc_enabled = user_config_profile["WFC Enabled"]
- wfc_mode = user_config_profile["WFC Mode"]
- is_wifi_on = user_config_profile["WiFi State"]
-
- if is_airplane_mode:
- if not toggle_airplane_mode(log, ad, False):
- ad.log.error("Failed to disable airplane mode.")
- return False
-
- code_dict = {
- "Verizon": {
- "unconditional": "73",
- "busy": "73",
- "not_answered": "73",
- "not_reachable": "73",
- "mmi": "*%s"
- },
- "Sprint": {
- "unconditional": "720",
- "busy": "740",
- "not_answered": "730",
- "not_reachable": "720",
- "mmi": "*%s"
- },
- "Far EasTone": {
- "unconditional": "142",
- "busy": "143",
- "not_answered": "144",
- "not_reachable": "144",
- "mmi": "*%s*2"
- },
- 'Generic': {
- "unconditional": "21",
- "busy": "67",
- "not_answered": "61",
- "not_reachable": "62",
- "mmi": "##%s#"
- }
- }
-
- if operator_name in code_dict:
- code = code_dict[operator_name][call_forwarding_type]
- mmi = code_dict[operator_name]["mmi"]
- else:
- code = code_dict['Generic'][call_forwarding_type]
- mmi = code_dict['Generic']["mmi"]
-
- result = False
- while retry >= 0:
- if run_get_call_forwarding_by_adb:
- res = get_call_forwarding_by_adb(
- log, ad, call_forwarding_type=call_forwarding_type)
- if res == "false":
- ad.log.info("Call forwarding is already disabled.")
- result = True
- break
-
- ad.log.info("Erasing and deactivating call forwarding %s..." %
- call_forwarding_type)
-
- ad.droid.telecomDialNumber(mmi % code)
-
- time.sleep(3)
- ad.send_keycode("ENTER")
- time.sleep(15)
-
- # To dismiss the pop-out dialog
- ad.send_keycode("BACK")
- time.sleep(5)
- ad.send_keycode("BACK")
-
- if run_get_call_forwarding_by_adb:
- res = get_call_forwarding_by_adb(
- log, ad, call_forwarding_type=call_forwarding_type)
- if res == "false" or res == "unknown":
- result = True
- break
- else:
- ad.log.error("Failed to erase and deactivate call forwarding by "
- "MMI code ##%s#." % code)
- retry = retry - 1
- time.sleep(30)
- else:
- result = True
- break
-
- if is_airplane_mode:
- if not toggle_airplane_mode(log, ad, True):
- ad.log.error("Failed to enable airplane mode again.")
- else:
- if is_wifi_on:
- ad.droid.wifiToggleState(True)
- if is_wfc_enabled:
- if not wait_for_wfc_enabled(
- log, ad,max_time=MAX_WAIT_TIME_WFC_ENABLED):
- ad.log.error("WFC is not enabled")
-
- return result
-
-def set_call_forwarding_by_mmi(
- log,
- ad,
- ad_forwarded,
- call_forwarding_type="unconditional",
- retry=2):
- """ Set up the forwarded number and enable call forwarding by MMI code.
-
- Args:
- log: log object
- ad: android object of the device forwarding the call (primary device)
- ad_forwarded: android object of the device receiving forwarded call.
- retry: times of retry if the erasure failed.
- call_forwarding_type:
- - "unconditional"
- - "busy"
- - "not_answered"
- - "not_reachable"
- Returns:
- True by successful erasure. Otherwise False.
- """
-
- res = get_call_forwarding_by_adb(log, ad,
- call_forwarding_type=call_forwarding_type)
- if res == "true":
- return True
-
- if ad.droid.connectivityCheckAirplaneMode():
- ad.log.warning("%s is now in airplane mode.", ad.serial)
- return False
-
- operator_name = get_operator_name(log, ad)
-
- code_dict = {
- "Verizon": {
- "unconditional": "72",
- "busy": "71",
- "not_answered": "71",
- "not_reachable": "72",
- "mmi": "*%s%s"
- },
- "Sprint": {
- "unconditional": "72",
- "busy": "74",
- "not_answered": "73",
- "not_reachable": "72",
- "mmi": "*%s%s"
- },
- "Far EasTone": {
- "unconditional": "142",
- "busy": "143",
- "not_answered": "144",
- "not_reachable": "144",
- "mmi": "*%s*%s"
- },
- 'Generic': {
- "unconditional": "21",
- "busy": "67",
- "not_answered": "61",
- "not_reachable": "62",
- "mmi": "*%s*%s#",
- "mmi_for_plus_sign": "*%s*"
- }
- }
-
- if operator_name in code_dict:
- code = code_dict[operator_name][call_forwarding_type]
- mmi = code_dict[operator_name]["mmi"]
- if "mmi_for_plus_sign" in code_dict[operator_name]:
- mmi_for_plus_sign = code_dict[operator_name]["mmi_for_plus_sign"]
- else:
- code = code_dict['Generic'][call_forwarding_type]
- mmi = code_dict['Generic']["mmi"]
- mmi_for_plus_sign = code_dict['Generic']["mmi_for_plus_sign"]
-
- while retry >= 0:
- if not erase_call_forwarding_by_mmi(
- log, ad, call_forwarding_type=call_forwarding_type):
- retry = retry - 1
- continue
-
- forwarded_number = ad_forwarded.telephony['subscription'][
- ad_forwarded.droid.subscriptionGetDefaultVoiceSubId()][
- 'phone_num']
- ad.log.info("Registering and activating call forwarding %s to %s..." %
- (call_forwarding_type, forwarded_number))
-
- (forwarded_number_no_prefix, _) = _phone_number_remove_prefix(
- forwarded_number)
-
- if operator_name == "Far EasTone":
- forwarded_number_no_prefix = "0" + forwarded_number_no_prefix
-
- run_get_call_forwarding_by_adb = 1
- if operator_name in NOT_CHECK_MCALLFORWARDING_OPERATOR_LIST:
- run_get_call_forwarding_by_adb = 0
-
- _found_plus_sign = 0
- if re.search("^\+", forwarded_number):
- _found_plus_sign = 1
- forwarded_number.replace("+", "")
-
- if operator_name in code_dict:
- ad.droid.telecomDialNumber(mmi % (code, forwarded_number_no_prefix))
- else:
- if _found_plus_sign == 0:
- ad.droid.telecomDialNumber(mmi % (code, forwarded_number))
- else:
- ad.droid.telecomDialNumber(mmi_for_plus_sign % code)
- ad.send_keycode("PLUS")
-
- if "#" in mmi:
- dial_phone_number(ad, forwarded_number + "#")
- else:
- dial_phone_number(ad, forwarded_number)
-
- time.sleep(3)
- ad.send_keycode("ENTER")
- time.sleep(15)
-
- # To dismiss the pop-out dialog
- ad.send_keycode("BACK")
- time.sleep(5)
- ad.send_keycode("BACK")
-
- if not run_get_call_forwarding_by_adb:
- return True
-
- result = get_call_forwarding_by_adb(
- log, ad, call_forwarding_type=call_forwarding_type)
- if result == "false":
- retry = retry - 1
- elif result == "true":
- return True
- elif result == "unknown":
- return True
- else:
- retry = retry - 1
-
- if retry >= 0:
- ad.log.warning("Failed to register or activate call forwarding %s "
- "to %s. Retry after 15 seconds." % (call_forwarding_type,
- forwarded_number))
- time.sleep(15)
-
- ad.log.error("Failed to register or activate call forwarding %s to %s." %
- (call_forwarding_type, forwarded_number))
- return False
-
-
-def get_call_waiting_status(log, ad):
- """ (Todo) Get call waiting status (activated or deactivated) when there is
- any proper method available.
- """
- return True
-
-
-def set_call_waiting(log, ad, enable=1, retry=1):
- """ Activate/deactivate call waiting by dialing MMI code.
-
- Args:
- log: log object.
- ad: android object.
- enable: 1 for activation and 0 fir deactivation
- retry: times of retry if activation/deactivation fails
-
- Returns:
- True by successful activation/deactivation; otherwise False.
- """
- operator_name = get_operator_name(log, ad)
-
- if operator_name in ["Verizon", "Sprint"]:
- return True
-
- while retry >= 0:
- if enable:
- ad.log.info("Activating call waiting...")
- ad.droid.telecomDialNumber("*43#")
- else:
- ad.log.info("Deactivating call waiting...")
- ad.droid.telecomDialNumber("#43#")
-
- time.sleep(3)
- ad.send_keycode("ENTER")
- time.sleep(15)
-
- ad.send_keycode("BACK")
- time.sleep(5)
- ad.send_keycode("BACK")
-
- if get_call_waiting_status(log, ad):
- return True
- else:
- retry = retry + 1
-
- return False
-
-
def get_rx_tx_power_levels(log, ad):
""" Obtains Rx and Tx power levels from the MDS application.
@@ -9917,819 +3705,6 @@
return rx_power, tx_power
-def sms_in_collision_send_receive_verify(
- log,
- ad_rx,
- ad_rx2,
- ad_tx,
- ad_tx2,
- array_message,
- array_message2,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
- """Send 2 SMS', receive both SMS', and verify content and sender's number of
- each SMS.
-
- Send 2 SMS'. One from ad_tx to ad_rx and the other from ad_tx2 to ad_rx2.
- When ad_rx is identical to ad_rx2, the scenario of SMS' in collision can
- be tested.
- Verify both SMS' are sent, delivered and received.
- Verify received content and sender's number of each SMS is correct.
-
- Args:
- log: Log object.
- ad_tx: Sender's Android Device Object..
- ad_rx: Receiver's Android Device Object.
- ad_tx2: 2nd sender's Android Device Object..
- ad_rx2: 2nd receiver's Android Device Object.
- array_message: the array of message to send/receive from ad_tx to ad_rx
- array_message2: the array of message to send/receive from ad_tx2 to
- ad_rx2
- max_wait_time: Max time to wait for reception of SMS
- """
-
- rx_sub_id = get_outgoing_message_sub_id(ad_rx)
- rx2_sub_id = get_outgoing_message_sub_id(ad_rx2)
-
- _, tx_sub_id, _ = get_subid_on_same_network_of_host_ad(
- [ad_rx, ad_tx, ad_tx2],
- host_sub_id=rx_sub_id)
- set_subid_for_message(ad_tx, tx_sub_id)
-
- _, _, tx2_sub_id = get_subid_on_same_network_of_host_ad(
- [ad_rx2, ad_tx, ad_tx2],
- host_sub_id=rx2_sub_id)
- set_subid_for_message(ad_tx2, tx2_sub_id)
-
- if not sms_in_collision_send_receive_verify_for_subscription(
- log,
- ad_tx,
- ad_tx2,
- ad_rx,
- ad_rx2,
- tx_sub_id,
- tx2_sub_id,
- rx_sub_id,
- rx_sub_id,
- array_message,
- array_message2,
- max_wait_time):
- log_messaging_screen_shot(
- ad_rx, test_name="sms rx subid: %s" % rx_sub_id)
- log_messaging_screen_shot(
- ad_rx2, test_name="sms rx2 subid: %s" % rx2_sub_id)
- log_messaging_screen_shot(
- ad_tx, test_name="sms tx subid: %s" % tx_sub_id)
- log_messaging_screen_shot(
- ad_tx2, test_name="sms tx subid: %s" % tx2_sub_id)
- return False
- return True
-
-
-def sms_in_collision_send_receive_verify_for_subscription(
- log,
- ad_tx,
- ad_tx2,
- ad_rx,
- ad_rx2,
- subid_tx,
- subid_tx2,
- subid_rx,
- subid_rx2,
- array_message,
- array_message2,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
- """Send 2 SMS', receive both SMS', and verify content and sender's number of
- each SMS.
-
- Send 2 SMS'. One from ad_tx to ad_rx and the other from ad_tx2 to ad_rx2.
- When ad_rx is identical to ad_rx2, the scenario of SMS' in collision can
- be tested.
- Verify both SMS' are sent, delivered and received.
- Verify received content and sender's number of each SMS is correct.
-
- Args:
- log: Log object.
- ad_tx: Sender's Android Device Object..
- ad_rx: Receiver's Android Device Object.
- ad_tx2: 2nd sender's Android Device Object..
- ad_rx2: 2nd receiver's Android Device Object.
- subid_tx: Sub ID of ad_tx as default Sub ID for outgoing SMS
- subid_tx2: Sub ID of ad_tx2 as default Sub ID for outgoing SMS
- subid_rx: Sub ID of ad_rx as default Sub ID for incoming SMS
- subid_rx2: Sub ID of ad_rx2 as default Sub ID for incoming SMS
- array_message: the array of message to send/receive from ad_tx to ad_rx
- array_message2: the array of message to send/receive from ad_tx2 to
- ad_rx2
- max_wait_time: Max time to wait for reception of SMS
- """
-
- phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
- phonenumber_tx2 = ad_tx2.telephony['subscription'][subid_tx2]['phone_num']
- phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
- phonenumber_rx2 = ad_rx2.telephony['subscription'][subid_rx2]['phone_num']
-
- for ad in (ad_tx, ad_tx2, ad_rx, ad_rx2):
- ad.send_keycode("BACK")
- if not getattr(ad, "messaging_droid", None):
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
- else:
- try:
- if not ad.messaging_droid.is_live:
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
- else:
- ad.messaging_ed.clear_all_events()
- ad.messaging_droid.logI(
- "Start sms_send_receive_verify_for_subscription test")
- except Exception:
- ad.log.info("Create new sl4a session for messaging")
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
-
- for text, text2 in zip(array_message, array_message2):
- length = len(text)
- length2 = len(text2)
- ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
- phonenumber_tx, phonenumber_rx, length, text)
- ad_tx2.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
- phonenumber_tx2, phonenumber_rx2, length2, text2)
-
- try:
- ad_rx.messaging_ed.clear_events(EventSmsReceived)
- ad_rx2.messaging_ed.clear_events(EventSmsReceived)
- ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
- ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
- ad_tx2.messaging_ed.clear_events(EventSmsSentSuccess)
- ad_tx2.messaging_ed.clear_events(EventSmsSentFailure)
- ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
- if ad_rx2 != ad_rx:
- ad_rx2.messaging_droid.smsStartTrackingIncomingSmsMessage()
- time.sleep(1)
- ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
- ad_tx2.messaging_droid.logI("Sending SMS of length %s" % length2)
- ad_rx.messaging_droid.logI(
- "Expecting SMS of length %s from %s" % (length, ad_tx.serial))
- ad_rx2.messaging_droid.logI(
- "Expecting SMS of length %s from %s" % (length2, ad_tx2.serial))
-
- tasks = [
- (ad_tx.messaging_droid.smsSendTextMessage,
- (phonenumber_rx, text, True)),
- (ad_tx2.messaging_droid.smsSendTextMessage,
- (phonenumber_rx2, text2, True))]
- multithread_func(log, tasks)
- try:
- tasks = [
- (ad_tx.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
- EventSmsSentSuccess,
- EventSmsSentFailure,
- EventSmsDeliverSuccess,
- EventSmsDeliverFailure), max_wait_time)),
- (ad_tx2.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
- EventSmsSentSuccess,
- EventSmsSentFailure,
- EventSmsDeliverSuccess,
- EventSmsDeliverFailure), max_wait_time))
- ]
- results = run_multithread_func(log, tasks)
- res = True
- _ad = ad_tx
- for ad, events in [(ad_tx, results[0]),(ad_tx2, results[1])]:
- _ad = ad
- for event in events:
- ad.log.info("Got event %s", event["name"])
- if event["name"] == EventSmsSentFailure or \
- event["name"] == EventSmsDeliverFailure:
- if event.get("data") and event["data"].get("Reason"):
- ad.log.error("%s with reason: %s",
- event["name"],
- event["data"]["Reason"])
- res = False
- elif event["name"] == EventSmsSentSuccess or \
- event["name"] == EventSmsDeliverSuccess:
- break
- if not res:
- return False
- except Empty:
- _ad.log.error("No %s or %s event for SMS of length %s.",
- EventSmsSentSuccess, EventSmsSentFailure,
- length)
- return False
- if ad_rx == ad_rx2:
- if not wait_for_matching_mt_sms_in_collision(
- log,
- ad_rx,
- phonenumber_tx,
- phonenumber_tx2,
- text,
- text2,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
-
- ad_rx.log.error(
- "No matching received SMS of length %s from %s.",
- length,
- ad_rx.serial)
- return False
- else:
- if not wait_for_matching_mt_sms_in_collision_with_mo_sms(
- log,
- ad_rx,
- ad_rx2,
- phonenumber_tx,
- phonenumber_tx2,
- text,
- text2,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
- return False
- except Exception as e:
- log.error("Exception error %s", e)
- raise
- finally:
- ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
- ad_rx2.messaging_droid.smsStopTrackingIncomingSmsMessage()
- return True
-
-
-def sms_rx_power_off_multiple_send_receive_verify(
- log,
- ad_rx,
- ad_tx,
- ad_tx2,
- array_message_length,
- array_message2_length,
- num_array_message,
- num_array_message2,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
-
- rx_sub_id = get_outgoing_message_sub_id(ad_rx)
-
- _, tx_sub_id, _ = get_subid_on_same_network_of_host_ad(
- [ad_rx, ad_tx, ad_tx2],
- host_sub_id=rx_sub_id)
- set_subid_for_message(ad_tx, tx_sub_id)
-
- _, _, tx2_sub_id = get_subid_on_same_network_of_host_ad(
- [ad_rx, ad_tx, ad_tx2],
- host_sub_id=rx_sub_id)
- set_subid_for_message(ad_tx2, tx2_sub_id)
-
- if not sms_rx_power_off_multiple_send_receive_verify_for_subscription(
- log,
- ad_tx,
- ad_tx2,
- ad_rx,
- tx_sub_id,
- tx2_sub_id,
- rx_sub_id,
- rx_sub_id,
- array_message_length,
- array_message2_length,
- num_array_message,
- num_array_message2):
- log_messaging_screen_shot(
- ad_rx, test_name="sms rx subid: %s" % rx_sub_id)
- log_messaging_screen_shot(
- ad_tx, test_name="sms tx subid: %s" % tx_sub_id)
- log_messaging_screen_shot(
- ad_tx2, test_name="sms tx subid: %s" % tx2_sub_id)
- return False
- return True
-
-
-def sms_rx_power_off_multiple_send_receive_verify_for_subscription(
- log,
- ad_tx,
- ad_tx2,
- ad_rx,
- subid_tx,
- subid_tx2,
- subid_rx,
- subid_rx2,
- array_message_length,
- array_message2_length,
- num_array_message,
- num_array_message2,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
-
- phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
- phonenumber_tx2 = ad_tx2.telephony['subscription'][subid_tx2]['phone_num']
- phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
- phonenumber_rx2 = ad_rx.telephony['subscription'][subid_rx2]['phone_num']
-
- if not toggle_airplane_mode(log, ad_rx, True):
- ad_rx.log.error("Failed to enable Airplane Mode")
- return False
- ad_rx.stop_services()
- ad_rx.log.info("Rebooting......")
- ad_rx.adb.reboot()
-
- message_dict = {phonenumber_tx: [], phonenumber_tx2: []}
- for index in range(max(num_array_message, num_array_message2)):
- array_message = [rand_ascii_str(array_message_length)]
- array_message2 = [rand_ascii_str(array_message2_length)]
- for text, text2 in zip(array_message, array_message2):
- message_dict[phonenumber_tx].append(text)
- message_dict[phonenumber_tx2].append(text2)
- length = len(text)
- length2 = len(text2)
-
- ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
- phonenumber_tx, phonenumber_rx, length, text)
- ad_tx2.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
- phonenumber_tx2, phonenumber_rx2, length2, text2)
-
- try:
- for ad in (ad_tx, ad_tx2):
- ad.send_keycode("BACK")
- if not getattr(ad, "messaging_droid", None):
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
- else:
- try:
- if not ad.messaging_droid.is_live:
- ad.messaging_droid, ad.messaging_ed = \
- ad.get_droid()
- ad.messaging_ed.start()
- else:
- ad.messaging_ed.clear_all_events()
- ad.messaging_droid.logI(
- "Start sms_send_receive_verify_for_subscription"
- " test")
- except Exception:
- ad.log.info("Create new sl4a session for messaging")
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
-
- ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
- ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
- ad_tx2.messaging_ed.clear_events(EventSmsSentSuccess)
- ad_tx2.messaging_ed.clear_events(EventSmsSentFailure)
-
- if index < num_array_message and index < num_array_message2:
- ad_tx.messaging_droid.logI(
- "Sending SMS of length %s" % length)
- ad_tx2.messaging_droid.logI(
- "Sending SMS of length %s" % length2)
- tasks = [
- (ad_tx.messaging_droid.smsSendTextMessage,
- (phonenumber_rx, text, True)),
- (ad_tx2.messaging_droid.smsSendTextMessage,
- (phonenumber_rx2, text2, True))]
- multithread_func(log, tasks)
- else:
- if index < num_array_message:
- ad_tx.messaging_droid.logI(
- "Sending SMS of length %s" % length)
- ad_tx.messaging_droid.smsSendTextMessage(
- phonenumber_rx, text, True)
- if index < num_array_message2:
- ad_tx2.messaging_droid.logI(
- "Sending SMS of length %s" % length2)
- ad_tx2.messaging_droid.smsSendTextMessage(
- phonenumber_rx2, text2, True)
-
- try:
- if index < num_array_message and index < num_array_message2:
- tasks = [
- (ad_tx.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
- EventSmsSentSuccess,
- EventSmsSentFailure,
- EventSmsDeliverSuccess,
- EventSmsDeliverFailure),
- max_wait_time)),
- (ad_tx2.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
- EventSmsSentSuccess,
- EventSmsSentFailure,
- EventSmsDeliverSuccess,
- EventSmsDeliverFailure),
- max_wait_time))
- ]
- results = run_multithread_func(log, tasks)
- res = True
- _ad = ad_tx
- for ad, events in [
- (ad_tx, results[0]), (ad_tx2, results[1])]:
- _ad = ad
- for event in events:
- ad.log.info("Got event %s", event["name"])
- if event["name"] == EventSmsSentFailure or \
- event["name"] == EventSmsDeliverFailure:
- if event.get("data") and \
- event["data"].get("Reason"):
- ad.log.error("%s with reason: %s",
- event["name"],
- event["data"]["Reason"])
- res = False
- elif event["name"] == EventSmsSentSuccess or \
- event["name"] == EventSmsDeliverSuccess:
- break
- if not res:
- return False
- else:
- if index < num_array_message:
- result = ad_tx.messaging_ed.pop_events(
- "(%s|%s|%s|%s)" % (
- EventSmsSentSuccess,
- EventSmsSentFailure,
- EventSmsDeliverSuccess,
- EventSmsDeliverFailure),
- max_wait_time)
- res = True
- _ad = ad_tx
- for ad, events in [(ad_tx, result)]:
- _ad = ad
- for event in events:
- ad.log.info("Got event %s", event["name"])
- if event["name"] == EventSmsSentFailure or \
- event["name"] == EventSmsDeliverFailure:
- if event.get("data") and \
- event["data"].get("Reason"):
- ad.log.error(
- "%s with reason: %s",
- event["name"],
- event["data"]["Reason"])
- res = False
- elif event["name"] == EventSmsSentSuccess \
- or event["name"] == EventSmsDeliverSuccess:
- break
- if not res:
- return False
- if index < num_array_message2:
- result = ad_tx2.messaging_ed.pop_events(
- "(%s|%s|%s|%s)" % (
- EventSmsSentSuccess,
- EventSmsSentFailure,
- EventSmsDeliverSuccess,
- EventSmsDeliverFailure),
- max_wait_time)
- res = True
- _ad = ad_tx2
- for ad, events in [(ad_tx2, result)]:
- _ad = ad
- for event in events:
- ad.log.info("Got event %s", event["name"])
- if event["name"] == EventSmsSentFailure or \
- event["name"] == EventSmsDeliverFailure:
- if event.get("data") and \
- event["data"].get("Reason"):
- ad.log.error(
- "%s with reason: %s",
- event["name"],
- event["data"]["Reason"])
- res = False
- elif event["name"] == EventSmsSentSuccess \
- or event["name"] == EventSmsDeliverSuccess:
- break
- if not res:
- return False
-
-
- except Empty:
- _ad.log.error("No %s or %s event for SMS of length %s.",
- EventSmsSentSuccess, EventSmsSentFailure,
- length)
- return False
-
- except Exception as e:
- log.error("Exception error %s", e)
- raise
-
- ad_rx.wait_for_boot_completion()
- ad_rx.root_adb()
- ad_rx.start_services(skip_setup_wizard=False)
-
- output = ad_rx.adb.logcat("-t 1")
- match = re.search(r"\d+-\d+\s\d+:\d+:\d+.\d+", output)
- if match:
- ad_rx.test_log_begin_time = match.group(0)
-
- ad_rx.messaging_droid, ad_rx.messaging_ed = ad_rx.get_droid()
- ad_rx.messaging_ed.start()
- ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
- time.sleep(1) #sleep 100ms after starting event tracking
-
- if not toggle_airplane_mode(log, ad_rx, False):
- ad_rx.log.error("Failed to disable Airplane Mode")
- return False
-
- res = True
- try:
- if not wait_for_matching_multiple_sms(log,
- ad_rx,
- phonenumber_tx,
- phonenumber_tx2,
- messages=message_dict,
- max_wait_time=max_wait_time):
- res = False
- except Exception as e:
- log.error("Exception error %s", e)
- raise
- finally:
- ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
-
- return res
-
-
-def wait_for_matching_mt_sms_in_collision(log,
- ad_rx,
- phonenumber_tx,
- phonenumber_tx2,
- text,
- text2,
- allow_multi_part_long_sms=True,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
-
- if not allow_multi_part_long_sms:
- try:
- ad_rx.messaging_ed.wait_for_event(
- EventSmsReceived,
- is_sms_in_collision_match,
- max_wait_time,
- phonenumber_tx,
- phonenumber_tx2,
- text,
- text2)
- ad_rx.log.info("Got event %s", EventSmsReceived)
- return True
- except Empty:
- ad_rx.log.error("No matched SMS received event.")
- return False
- else:
- try:
- received_sms = ''
- received_sms2 = ''
- remaining_text = text
- remaining_text2 = text2
- while (remaining_text != '' or remaining_text2 != ''):
- event = ad_rx.messaging_ed.wait_for_event(
- EventSmsReceived,
- is_sms_in_collision_partial_match,
- max_wait_time,
- phonenumber_tx,
- phonenumber_tx2,
- remaining_text,
- remaining_text2)
- event_text = event['data']['Text'].split(")")[-1].strip()
- event_text_length = len(event_text)
-
- if event_text in remaining_text:
- ad_rx.log.info("Got event %s of text length %s from %s",
- EventSmsReceived, event_text_length,
- phonenumber_tx)
- remaining_text = remaining_text[event_text_length:]
- received_sms += event_text
- elif event_text in remaining_text2:
- ad_rx.log.info("Got event %s of text length %s from %s",
- EventSmsReceived, event_text_length,
- phonenumber_tx2)
- remaining_text2 = remaining_text2[event_text_length:]
- received_sms2 += event_text
-
- ad_rx.log.info("Received SMS of length %s", len(received_sms))
- ad_rx.log.info("Received SMS of length %s", len(received_sms2))
- return True
- except Empty:
- ad_rx.log.error(
- "Missing SMS received event.")
- if received_sms != '':
- ad_rx.log.error(
- "Only received partial matched SMS of length %s from %s",
- len(received_sms), phonenumber_tx)
- if received_sms2 != '':
- ad_rx.log.error(
- "Only received partial matched SMS of length %s from %s",
- len(received_sms2), phonenumber_tx2)
- return False
-
-
-def wait_for_matching_mt_sms_in_collision_with_mo_sms(log,
- ad_rx,
- ad_rx2,
- phonenumber_tx,
- phonenumber_tx2,
- text,
- text2,
- allow_multi_part_long_sms=True,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
-
- if not allow_multi_part_long_sms:
- result = True
- try:
- ad_rx.messaging_ed.wait_for_call_offhook_event(
- EventSmsReceived,
- is_sms_match,
- max_wait_time,
- phonenumber_tx,
- text)
- ad_rx.log.info("Got event %s", EventSmsReceived)
- except Empty:
- ad_rx.log.error("No matched SMS received event.")
- result = False
-
- try:
- ad_rx2.messaging_ed.wait_for_call_offhook_event(
- EventSmsReceived,
- is_sms_match,
- max_wait_time,
- phonenumber_tx2,
- text2)
- ad_rx2.log.info("Got event %s", EventSmsReceived)
- except Empty:
- ad_rx2.log.error("No matched SMS received event.")
- result = False
-
- return result
- else:
- result = True
- try:
- received_sms = ''
- remaining_text = text
- while remaining_text != '':
- event = ad_rx.messaging_ed.wait_for_event(
- EventSmsReceived, is_sms_partial_match, max_wait_time,
- phonenumber_tx, remaining_text)
- event_text = event['data']['Text'].split(")")[-1].strip()
- event_text_length = len(event_text)
-
- if event_text in remaining_text:
- ad_rx.log.info("Got event %s of text length %s from %s",
- EventSmsReceived, event_text_length,
- phonenumber_tx)
- remaining_text = remaining_text[event_text_length:]
- received_sms += event_text
-
- ad_rx.log.info("Received SMS of length %s", len(received_sms))
- except Empty:
- ad_rx.log.error(
- "Missing SMS received event.")
- if received_sms != '':
- ad_rx.log.error(
- "Only received partial matched SMS of length %s from %s",
- len(received_sms), phonenumber_tx)
- result = False
-
- try:
- received_sms2 = ''
- remaining_text2 = text2
- while remaining_text2 != '':
- event2 = ad_rx2.messaging_ed.wait_for_event(
- EventSmsReceived, is_sms_partial_match, max_wait_time,
- phonenumber_tx2, remaining_text2)
- event_text2 = event2['data']['Text'].split(")")[-1].strip()
- event_text_length2 = len(event_text2)
-
- if event_text2 in remaining_text2:
- ad_rx2.log.info("Got event %s of text length %s from %s",
- EventSmsReceived, event_text_length2,
- phonenumber_tx2)
- remaining_text2 = remaining_text2[event_text_length2:]
- received_sms2 += event_text2
-
- ad_rx2.log.info("Received SMS of length %s", len(received_sms2))
- except Empty:
- ad_rx2.log.error(
- "Missing SMS received event.")
- if received_sms2 != '':
- ad_rx2.log.error(
- "Only received partial matched SMS of length %s from %s",
- len(received_sms2), phonenumber_tx2)
- result = False
-
- return result
-
-
-def wait_for_matching_multiple_sms(log,
- ad_rx,
- phonenumber_tx,
- phonenumber_tx2,
- messages={},
- allow_multi_part_long_sms=True,
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
-
- if not allow_multi_part_long_sms:
- try:
- ad_rx.messaging_ed.wait_for_event(
- EventSmsReceived,
- is_sms_match_among_multiple_sms,
- max_wait_time,
- phonenumber_tx,
- phonenumber_tx2,
- messages[phonenumber_tx],
- messages[phonenumber_tx2])
- ad_rx.log.info("Got event %s", EventSmsReceived)
- return True
- except Empty:
- ad_rx.log.error("No matched SMS received event.")
- return False
- else:
- all_msgs = []
- for tx, msgs in messages.items():
- for msg in msgs:
- all_msgs.append([tx, msg, msg, ''])
-
- all_msgs_copy = all_msgs.copy()
-
- try:
- while (all_msgs != []):
- event = ad_rx.messaging_ed.wait_for_event(
- EventSmsReceived,
- is_sms_partial_match_among_multiple_sms,
- max_wait_time,
- phonenumber_tx,
- phonenumber_tx2,
- messages[phonenumber_tx],
- messages[phonenumber_tx2])
- event_text = event['data']['Text'].split(")")[-1].strip()
- event_text_length = len(event_text)
-
- for msg in all_msgs_copy:
- if event_text in msg[2]:
- ad_rx.log.info("Got event %s of text length %s from %s",
- EventSmsReceived, event_text_length,
- msg[0])
- msg[2] = msg[2][event_text_length:]
- msg[3] += event_text
-
- if msg[2] == "":
- all_msgs.remove(msg)
-
- ad_rx.log.info("Received all SMS' sent when power-off.")
- except Empty:
- ad_rx.log.error(
- "Missing SMS received event.")
-
- for msg in all_msgs_copy:
- if msg[3] != '':
- ad_rx.log.error(
- "Only received partial matched SMS of length %s from %s",
- len(msg[3]), msg[0])
- return False
-
- return True
-
-
-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):
- return True
- return False
-
-
-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:
- return True
- return False
-
-
-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:
- return True
-
- for txt in texts2:
- 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=[]):
- 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):
- return True
-
- for txt in texts2:
- 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.')
@@ -10767,327 +3742,6 @@
return get_value
-def wait_for_sending_sms(ad_tx, max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
- try:
- events = ad_tx.messaging_ed.pop_events(
- "(%s|%s|%s|%s)" %
- (EventSmsSentSuccess, EventSmsSentFailure,
- EventSmsDeliverSuccess,
- EventSmsDeliverFailure), max_wait_time)
- for event in events:
- ad_tx.log.info("Got event %s", event["name"])
- if event["name"] == EventSmsSentFailure or \
- event["name"] == EventSmsDeliverFailure:
- if event.get("data") and event["data"].get("Reason"):
- ad_tx.log.error("%s with reason: %s",
- event["name"],
- event["data"]["Reason"])
- return False
- elif event["name"] == EventSmsSentSuccess or \
- event["name"] == EventSmsDeliverSuccess:
- return True
- except Empty:
- ad_tx.log.error("No %s or %s event for SMS.",
- EventSmsSentSuccess, EventSmsSentFailure)
- return False
-
-
-def wait_for_call_end(
- log,
- ad_caller,
- ad_callee,
- ad_hangup,
- verify_caller_func,
- verify_callee_func,
- call_begin_time,
- check_interval=5,
- tel_result_wrapper=TelResultWrapper(CallResult('SUCCESS')),
- wait_time_in_call=WAIT_TIME_IN_CALL):
- elapsed_time = 0
- while (elapsed_time < wait_time_in_call):
- check_interval = min(check_interval, wait_time_in_call - elapsed_time)
- time.sleep(check_interval)
- elapsed_time += check_interval
- time_message = "at <%s>/<%s> second." % (elapsed_time, wait_time_in_call)
- for ad, call_func in [(ad_caller, verify_caller_func),
- (ad_callee, verify_callee_func)]:
- if not call_func(log, ad):
- ad.log.error(
- "NOT in correct %s state at %s, voice in RAT %s",
- call_func.__name__,
- time_message,
- ad.droid.telephonyGetCurrentVoiceNetworkType())
- tel_result_wrapper.result_value = CallResult(
- 'CALL_DROP_OR_WRONG_STATE_AFTER_CONNECTED')
- else:
- ad.log.info("In correct %s state at %s",
- call_func.__name__, time_message)
- if not ad.droid.telecomCallGetAudioState():
- ad.log.error("Audio is not in call state at %s", time_message)
- tel_result_wrapper.result_value = CallResult(
- 'AUDIO_STATE_NOT_INCALL_AFTER_CONNECTED')
- if not tel_result_wrapper:
- return tel_result_wrapper
-
- if ad_hangup:
- if not hangup_call(log, ad_hangup):
- ad_hangup.log.info("Failed to hang up the call")
- tel_result_wrapper.result_value = CallResult('CALL_HANGUP_FAIL')
-
- if not tel_result_wrapper:
- for ad in (ad_caller, ad_callee):
- last_call_drop_reason(ad, call_begin_time)
- try:
- if ad.droid.telecomIsInCall():
- ad.log.info("In call. End now.")
- ad.droid.telecomEndCall()
- except Exception as e:
- log.error(str(e))
- if ad_hangup or not tel_result_wrapper:
- for ad in (ad_caller, ad_callee):
- if not wait_for_call_id_clearing(ad, getattr(ad, "caller_ids", [])):
- tel_result_wrapper.result_value = CallResult(
- 'CALL_ID_CLEANUP_FAIL')
-
- return tel_result_wrapper
-
-
-def voice_call_in_collision_with_mt_sms_msim(
- log,
- ad_primary,
- ad_sms,
- ad_voice,
- sms_subid_ad_primary,
- sms_subid_ad_sms,
- voice_subid_ad_primary,
- voice_subid_ad_voice,
- array_message,
- ad_hangup=None,
- verify_caller_func=None,
- verify_callee_func=None,
- call_direction="mo",
- wait_time_in_call=WAIT_TIME_IN_CALL,
- incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
- dialing_number_length=None,
- video_state=None):
-
- ad_tx = ad_sms
- ad_rx = ad_primary
- subid_tx = sms_subid_ad_sms
- subid_rx = sms_subid_ad_primary
-
- if call_direction == "mo":
- ad_caller = ad_primary
- ad_callee = ad_voice
- subid_caller = voice_subid_ad_primary
- subid_callee = voice_subid_ad_voice
- elif call_direction == "mt":
- ad_callee = ad_primary
- ad_caller = ad_voice
- subid_callee = voice_subid_ad_primary
- subid_caller = voice_subid_ad_voice
-
-
- phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
- phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
-
- tel_result_wrapper = TelResultWrapper(CallResult('SUCCESS'))
-
- for ad in (ad_tx, ad_rx):
- ad.send_keycode("BACK")
- if not getattr(ad, "messaging_droid", None):
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
- else:
- try:
- if not ad.messaging_droid.is_live:
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
- else:
- ad.messaging_ed.clear_all_events()
- except Exception:
- ad.log.info("Create new sl4a session for messaging")
- ad.messaging_droid, ad.messaging_ed = ad.get_droid()
- ad.messaging_ed.start()
-
- if not verify_caller_func:
- verify_caller_func = is_phone_in_call
- if not verify_callee_func:
- verify_callee_func = is_phone_in_call
-
- caller_number = ad_caller.telephony['subscription'][subid_caller][
- 'phone_num']
- callee_number = ad_callee.telephony['subscription'][subid_callee][
- 'phone_num']
- if dialing_number_length:
- skip_test = False
- trunc_position = 0 - int(dialing_number_length)
- try:
- caller_area_code = caller_number[:trunc_position]
- callee_area_code = callee_number[:trunc_position]
- callee_dial_number = callee_number[trunc_position:]
- except:
- skip_test = True
- if caller_area_code != callee_area_code:
- skip_test = True
- if skip_test:
- msg = "Cannot make call from %s to %s by %s digits" % (
- caller_number, callee_number, dialing_number_length)
- ad_caller.log.info(msg)
- raise signals.TestSkip(msg)
- else:
- callee_number = callee_dial_number
-
- msg = "Call from %s to %s" % (caller_number, callee_number)
- if video_state:
- msg = "Video %s" % msg
- video = True
- else:
- video = False
- if ad_hangup:
- msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
- ad_caller.log.info(msg)
-
- for ad in (ad_caller, ad_callee):
- call_ids = ad.droid.telecomCallGetCallIds()
- setattr(ad, "call_ids", call_ids)
- if call_ids:
- ad.log.info("Pre-exist CallId %s before making call", call_ids)
-
- ad_caller.ed.clear_events(EventCallStateChanged)
- call_begin_time = get_device_epoch_time(ad)
- ad_caller.droid.telephonyStartTrackingCallStateForSubscription(subid_caller)
-
- for text in array_message:
- length = len(text)
- ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
- phonenumber_tx, phonenumber_rx, length, text)
- try:
- ad_rx.messaging_ed.clear_events(EventSmsReceived)
- ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
- ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
- ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
- time.sleep(1) #sleep 100ms after starting event tracking
- ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
- ad_rx.messaging_droid.logI("Expecting SMS of length %s" % length)
- ad_caller.log.info("Make a phone call to %s", callee_number)
-
- tasks = [
- (ad_tx.messaging_droid.smsSendTextMessage,
- (phonenumber_rx, text, True)),
- (ad_caller.droid.telecomCallNumber,
- (callee_number, video))]
-
- run_multithread_func(log, tasks)
-
- try:
- # Verify OFFHOOK state
- if not wait_for_call_offhook_for_subscription(
- log,
- ad_caller,
- subid_caller,
- event_tracking_started=True):
- ad_caller.log.info(
- "sub_id %s not in call offhook state", subid_caller)
- last_call_drop_reason(ad_caller, begin_time=call_begin_time)
-
- ad_caller.log.error("Initiate call failed.")
- tel_result_wrapper.result_value = CallResult(
- 'INITIATE_FAILED')
- return tel_result_wrapper
- else:
- ad_caller.log.info("Caller initate call successfully")
- finally:
- ad_caller.droid.telephonyStopTrackingCallStateChangeForSubscription(
- subid_caller)
- if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
- ad_caller.droid.telecomShowInCallScreen()
- elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
- ad_caller.droid.showHomeScreen()
-
- if not wait_and_answer_call_for_subscription(
- log,
- ad_callee,
- subid_callee,
- incoming_number=caller_number,
- caller=ad_caller,
- incall_ui_display=incall_ui_display,
- video_state=video_state):
- ad_callee.log.error("Answer call fail.")
- tel_result_wrapper.result_value = CallResult(
- 'NO_RING_EVENT_OR_ANSWER_FAILED')
- return tel_result_wrapper
- else:
- ad_callee.log.info("Callee answered the call successfully")
-
- for ad, call_func in zip([ad_caller, ad_callee],
- [verify_caller_func, verify_callee_func]):
- call_ids = ad.droid.telecomCallGetCallIds()
- new_call_ids = set(call_ids) - set(ad.call_ids)
- if not new_call_ids:
- ad.log.error(
- "No new call ids are found after call establishment")
- ad.log.error("telecomCallGetCallIds returns %s",
- ad.droid.telecomCallGetCallIds())
- tel_result_wrapper.result_value = CallResult(
- 'NO_CALL_ID_FOUND')
- for new_call_id in new_call_ids:
- if not wait_for_in_call_active(ad, call_id=new_call_id):
- tel_result_wrapper.result_value = CallResult(
- 'CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT')
- else:
- ad.log.info(
- "callProperties = %s",
- ad.droid.telecomCallGetProperties(new_call_id))
-
- if not ad.droid.telecomCallGetAudioState():
- ad.log.error("Audio is not in call state")
- tel_result_wrapper.result_value = CallResult(
- 'AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT')
-
- if call_func(log, ad):
- ad.log.info("Call is in %s state", call_func.__name__)
- else:
- ad.log.error("Call is not in %s state, voice in RAT %s",
- call_func.__name__,
- ad.droid.telephonyGetCurrentVoiceNetworkType())
- tel_result_wrapper.result_value = CallResult(
- 'CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT')
- if not tel_result_wrapper:
- return tel_result_wrapper
-
- if not wait_for_sending_sms(
- ad_tx,
- max_wait_time=MAX_WAIT_TIME_SMS_SENT_SUCCESS_IN_COLLISION):
- return False
-
- tasks = [
- (wait_for_matching_sms,
- (log, ad_rx, phonenumber_tx, text,
- MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION, True)),
- (wait_for_call_end,
- (log, ad_caller, ad_callee, ad_hangup, verify_caller_func,
- verify_callee_func, call_begin_time, 5, tel_result_wrapper,
- WAIT_TIME_IN_CALL))]
-
- results = run_multithread_func(log, tasks)
-
- if not results[0]:
- ad_rx.log.error("No matching received SMS of length %s.",
- length)
- return False
-
- tel_result_wrapper = results[1]
-
- except Exception as e:
- log.error("Exception error %s", e)
- raise
- finally:
- ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
-
- return tel_result_wrapper
-
-
def change_voice_subid_temporarily(ad, sub_id, state_check_func, params=None):
result = False
voice_sub_id_changed = False
@@ -11109,107 +3763,6 @@
return result
-def wait_for_network_service(
- log,
- ad,
- wifi_connected=False,
- wifi_ssid=None,
- ims_reg=True,
- recover=False,
- retry=3):
- """ Wait for multiple network services in sequence, including:
- - service state
- - network connection
- - wifi connection
- - cellular data
- - internet connection
- - IMS registration
-
- The mechanism (cycling airplane mode) to recover network services is
- also provided if any service is not available.
-
- Args:
- log: log object
- ad: android device
- wifi_connected: True if wifi should be connected. Otherwise False.
- ims_reg: True if IMS should be registered. Otherwise False.
- recover: True if the mechanism (cycling airplane mode) to recover
- network services should be enabled (by default False).
- retry: times of retry.
- """
- times = 1
- while times <= retry:
- while True:
- 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 is not 'IN_SERVICE'.")
- break
-
- if not wait_for_state(
- ad.droid.connectivityNetworkIsConnected,
- True,
- MAX_WAIT_TIME_FOR_STATE_CHANGE,
- WAIT_TIME_BETWEEN_STATE_CHECK):
- ad.log.error("Network is NOT connected!")
- break
-
- if wifi_connected and wifi_ssid:
- if not wait_for_state(
- check_is_wifi_connected,
- True,
- MAX_WAIT_TIME_FOR_STATE_CHANGE,
- WAIT_TIME_BETWEEN_STATE_CHECK,
- log,
- ad,
- wifi_ssid):
- ad.log.error("Failed to connect Wi-Fi SSID '%s'.", wifi_ssid)
- break
- else:
- if not wait_for_cell_data_connection(log, ad, True):
- ad.log.error("Failed to enable data connection.")
- break
-
- if not wait_for_state(
- verify_internet_connection,
- True,
- MAX_WAIT_TIME_FOR_STATE_CHANGE,
- WAIT_TIME_BETWEEN_STATE_CHECK,
- log,
- ad):
- ad.log.error("Data not available on cell.")
- break
-
- if ims_reg:
- if not wait_for_ims_registered(log, ad):
- ad.log.error("IMS is not registered.")
- break
- ad.log.info("IMS is registered.")
- return True
-
- if recover:
- ad.log.warning("Trying to recover by cycling airplane mode...")
- if not toggle_airplane_mode(log, ad, True):
- ad.log.error("Failed to enable airplane mode")
- break
-
- time.sleep(5)
-
- if not toggle_airplane_mode(log, ad, False):
- ad.log.error("Failed to disable airplane mode")
- break
-
- times = times + 1
-
- else:
- return False
- return False
-
-
def check_voice_network_type(ads, voice_init=True):
"""
Args:
@@ -11230,75 +3783,13 @@
return voice_network_list
-def check_call_status(ad, voice_type_init=None, voice_type_in_call=None):
- """"
- Args:
- ad: Android device object
- voice_type_init: Voice network type before initiate call
- voice_type_in_call: Voice network type in call state
-
- Return:
- voice_call_type_dict: Voice call status
- """
- dut = str(ad.serial)
- network_type = voice_type_init + "_" + voice_type_in_call
- if network_type == "NR_NR":
- voice_call_type_dict = update_voice_call_type_dict(dut, "VoNR")
- elif network_type == "NR_LTE":
- voice_call_type_dict = update_voice_call_type_dict(dut, "EPSFB")
- elif network_type == "LTE_LTE":
- voice_call_type_dict = update_voice_call_type_dict(dut, "VoLTE")
- elif network_type == "LTE_WCDMA":
- voice_call_type_dict = update_voice_call_type_dict(dut, "CSFB")
- else:
- voice_call_type_dict = update_voice_call_type_dict(dut, "UNKNOWN")
- return voice_call_type_dict
-
-
-def update_voice_call_type_dict(dut, key):
- """
- Args:
- dut: Serial Number of android device object
- key: Network subscription parameter (VoNR or EPSFB or VoLTE or CSFB or UNKNOWN)
- Return:
- voice_call_type: Voice call status
- """
- if dut in voice_call_type.keys():
- voice_call_type[dut][key] += 1
- else:
- voice_call_type[dut] = {key:0}
- voice_call_type[dut][key] += 1
- return voice_call_type
-
-
-def wait_for_log(ad, pattern, begin_time=None, end_time=None, max_wait_time=120):
- """Wait for logcat logs matching given pattern. This function searches in
- logcat for strings matching given pattern by using search_logcat per second
- until max_wait_time reaches.
-
- Args:
- ad: android device object
- pattern: pattern to be searched in grep format
- begin_time: only the lines in logcat with time stamps later than
- begin_time will be searched.
- end_time: only the lines in logcat with time stamps earlier than
- end_time will be searched.
- max_wait_time: timeout of this function
-
- Returns:
- All matched lines will be returned. If no line matches the given pattern
- None will be returned.
- """
- start_time = datetime.now()
- while True:
- ad.log.info(
- '====== Searching logcat for "%s" ====== ', pattern)
- res = ad.search_logcat(
- pattern, begin_time=begin_time, end_time=end_time)
- if res:
- return res
- time.sleep(1)
- stop_time = datetime.now()
- passed_time = (stop_time - start_time).total_seconds()
- if passed_time > max_wait_time:
- return
+def cycle_airplane_mode(ad):
+ """Turn on APM and then off."""
+ # APM toggle
+ if not toggle_airplane_mode(ad.log, ad, True):
+ ad.log.info("Failed to turn on airplane mode.")
+ return False
+ if not toggle_airplane_mode(ad.log, ad, False):
+ ad.log.info("Failed to turn off airplane mode.")
+ return False
+ return True
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_video_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_video_utils.py
index 047b512..26751cf 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_video_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_video_utils.py
@@ -17,25 +17,12 @@
import time
from queue import Empty
from acts_contrib.test_utils.tel.tel_defines import AUDIO_ROUTE_EARPIECE
-from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_RINGING
-from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND
from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_INITIATION
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALLEE_RINGING
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_TELECOM_RINGING
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VIDEO_SESSION_EVENT
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOLTE_ENABLED
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
from acts_contrib.test_utils.tel.tel_defines import GEN_4G
-from acts_contrib.test_utils.tel.tel_defines import RAT_1XRTT
from acts_contrib.test_utils.tel.tel_defines import RAT_IWLAN
-from acts_contrib.test_utils.tel.tel_defines import RAT_LTE
-from acts_contrib.test_utils.tel.tel_defines import RAT_UMTS
-from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_OFFHOOK
-from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_RINGING
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_AUDIO_ONLY
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL_PAUSED
@@ -45,37 +32,27 @@
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_TX_PAUSED
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_STATE_INVALID
from acts_contrib.test_utils.tel.tel_defines import VT_VIDEO_QUALITY_DEFAULT
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ACCEPT_VIDEO_CALL_TO_CHECK_STATE
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
-from acts_contrib.test_utils.tel.tel_defines import EventCallStateChanged
from acts_contrib.test_utils.tel.tel_defines import EventTelecomVideoCallSessionModifyRequestReceived
from acts_contrib.test_utils.tel.tel_defines import EventTelecomVideoCallSessionModifyResponseReceived
from acts_contrib.test_utils.tel.tel_defines import EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED
from acts_contrib.test_utils.tel.tel_defines import EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED
-from acts_contrib.test_utils.tel.tel_defines import CallStateContainer
+from acts_contrib.test_utils.tel.tel_ims_utils import is_wfc_enabled
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode_for_subscription
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_video_enabled
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_network_generation
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_generation
-from acts_contrib.test_utils.tel.tel_test_utils import is_event_match
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte
-from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
-from acts_contrib.test_utils.tel.tel_test_utils import wait_and_answer_call_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_generation
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_rat_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_ringing_call
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_telecom_ringing
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_video_enabled
from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import is_wfc_enabled
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown_for_subscription
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
from acts_contrib.test_utils.tel.tel_voice_utils import is_call_hd
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan_for_subscription
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call_for_subscription
def phone_setup_video(
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_voice_conf_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_voice_conf_utils.py
index 75ff64b..721e83e 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_voice_conf_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_voice_conf_utils.py
@@ -17,26 +17,26 @@
import time
from acts import signals
+from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.tel_defines import CALL_CAPABILITY_MANAGE_CONFERENCE
from acts_contrib.test_utils.tel.tel_defines import CALL_PROPERTY_CONFERENCE
from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_ACTIVE
from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_HOLDING
from acts_contrib.test_utils.tel.tel_defines import PHONE_TYPE_GSM
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_2g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
from acts_contrib.test_utils.tel.tel_test_utils import get_call_uri
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls
from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
-from acts_contrib.test_utils.tel.tel_voice_utils import get_cep_conference_call_id
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_wcdma
from acts_contrib.test_utils.tel.tel_test_utils import is_uri_equivalent
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import get_cep_conference_call_id
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
from acts_contrib.test_utils.tel.tel_voice_utils import swap_calls
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_reject_call_for_subscription
def _three_phone_call_mo_add_mo(log, ads, phone_setups, verify_funcs):
@@ -219,41 +219,41 @@
ads[0].droid.telecomCallGetProperties(call_conf_id))
return None
- if (CALL_CAPABILITY_MANAGE_CONFERENCE not in ads[0]
- .droid.telecomCallGetCapabilities(call_conf_id)):
- ads[0].log.error(
- "Conf call id %s capabilities wrong: %s", call_conf_id,
- ads[0].droid.telecomCallGetCapabilities(call_conf_id))
- return None
+ if (CALL_CAPABILITY_MANAGE_CONFERENCE not in ads[0]
+ .droid.telecomCallGetCapabilities(call_conf_id)):
+ ads[0].log.error(
+ "Conf call id %s capabilities wrong: %s", call_conf_id,
+ ads[0].droid.telecomCallGetCapabilities(call_conf_id))
+ return None
- if (call_ab_id in calls) or (call_ac_id in calls):
- log.error("Previous call ids should not in new call"
- " list after merge.")
- return None
- else:
- for call_id in calls:
- if call_id != call_ab_id and call_id != call_ac_id:
- call_conf_id = call_id
- log.info("CEP not enabled.")
+ if (call_ab_id in calls) or (call_ac_id in calls):
+ log.error("Previous call ids should not in new call"
+ " list after merge.")
+ return None
+ else:
+ for call_id in calls:
+ if call_id != call_ab_id and call_id != call_ac_id:
+ call_conf_id = call_id
+ log.info("CEP not enabled.")
- if not call_conf_id:
- log.error("Merge call fail, no new conference call id.")
- raise signals.TestFailure(
- "Calls were not merged. Failed to merge calls.",
- extras={"fail_reason": "Calls were not merged."
- " Failed to merge calls."})
- if not verify_incall_state(log, [ads[0], ads[1], ads[2]], True):
- return False
+ if not call_conf_id:
+ log.error("Merge call fail, no new conference call id.")
+ raise signals.TestFailure(
+ "Calls were not merged. Failed to merge calls.",
+ extras={"fail_reason": "Calls were not merged."
+ " Failed to merge calls."})
+ if not verify_incall_state(log, [ads[0], ads[1], ads[2]], True):
+ return False
- # Check if Conf Call is currently active
- if ads[0].droid.telecomCallGetCallState(
- call_conf_id) != CALL_STATE_ACTIVE:
- ads[0].log.error(
- "Call_ID: %s, state: %s, expected: STATE_ACTIVE", call_conf_id,
- ads[0].droid.telecomCallGetCallState(call_conf_id))
- return None
+ # Check if Conf Call is currently active
+ if ads[0].droid.telecomCallGetCallState(
+ call_conf_id) != CALL_STATE_ACTIVE:
+ ads[0].log.error(
+ "Call_ID: %s, state: %s, expected: STATE_ACTIVE", call_conf_id,
+ ads[0].droid.telecomCallGetCallState(call_conf_id))
+ return None
- return call_conf_id
+ return call_conf_id
def _hangup_call(log, ad, device_description='Device'):
@@ -266,7 +266,7 @@
def _test_ims_conference_merge_drop_second_call_from_participant(
log, ads, call_ab_id, call_ac_id):
"""Test conference merge and drop in IMS (VoLTE or WiFi Calling) call.
- (CEP enabled).
+ (supporting both cases of CEP enabled and disabled).
PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneB.
PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneC.
@@ -336,10 +336,19 @@
calls = ads[0].droid.telecomCallGetCallIds()
calls.remove(call_conf_id)
+ if not calls:
+ raise signals.TestSkip('CEP is not supported. The test will be skipped.')
+
log.info("Step5: Disconnect call A-C and verify call continues.")
call_to_disconnect = None
for call in calls:
- if is_uri_equivalent(call_ac_uri, get_call_uri(ads[0], call)):
+ new_uri = get_call_uri(ads[0], call)
+ if not new_uri:
+ ads[0].log.warning('New URI should NOT be None.')
+ raise signals.TestSkip('Invalid URI is found on the host. The test will be skipped.')
+ else:
+ ads[0].log.info('URI for call ID %s: %s', call, new_uri)
+ if is_uri_equivalent(call_ac_uri, new_uri):
call_to_disconnect = call
calls.remove(call_to_disconnect)
break
@@ -359,7 +368,13 @@
calls = ads[0].droid.telecomCallGetCallIds()
call_to_disconnect = None
for call in calls:
- if is_uri_equivalent(call_ab_uri, get_call_uri(ads[0], call)):
+ new_uri = get_call_uri(ads[0], call)
+ if not new_uri:
+ ads[0].log.warning('New URI should NOT be None.')
+ raise signals.TestSkip('Invalid URI is found on the host. The test will be skipped.')
+ else:
+ ads[0].log.info('URI for call ID %s: %s', call, new_uri)
+ if is_uri_equivalent(call_ab_uri, new_uri):
call_to_disconnect = call
calls.remove(call_to_disconnect)
break
@@ -444,10 +459,19 @@
calls = ads[0].droid.telecomCallGetCallIds()
calls.remove(call_conf_id)
+ if not calls:
+ raise signals.TestSkip('CEP is not supported. The test will be skipped.')
+
log.info("Step5: Disconnect call A-B and verify call continues.")
call_to_disconnect = None
for call in calls:
- if is_uri_equivalent(call_ab_uri, get_call_uri(ads[0], call)):
+ new_uri = get_call_uri(ads[0], call)
+ if not new_uri:
+ ads[0].log.warning('New URI should NOT be None.')
+ raise signals.TestSkip('Invalid URI is found on the host. The test will be skipped.')
+ else:
+ ads[0].log.info('URI for call ID %s: %s', call, new_uri)
+ if is_uri_equivalent(call_ab_uri, new_uri):
call_to_disconnect = call
calls.remove(call_to_disconnect)
break
@@ -467,7 +491,13 @@
calls = ads[0].droid.telecomCallGetCallIds()
call_to_disconnect = None
for call in calls:
- if is_uri_equivalent(call_ac_uri, get_call_uri(ads[0], call)):
+ new_uri = get_call_uri(ads[0], call)
+ if not new_uri:
+ ads[0].log.warning('New URI should NOT be None.')
+ raise signals.TestSkip('Invalid URI is found on the host. The test will be skipped.')
+ else:
+ ads[0].log.info('URI for call ID %s: %s', call, new_uri)
+ if is_uri_equivalent(call_ac_uri, new_uri):
call_to_disconnect = call
calls.remove(call_to_disconnect)
break
@@ -482,7 +512,12 @@
return True
-def _three_phone_call_mo_add_mt(log, ads, phone_setups, verify_funcs):
+def _three_phone_call_mo_add_mt(
+ log,
+ ads,
+ phone_setups,
+ verify_funcs,
+ reject_once=False):
"""Use 3 phones to make MO call and MT call.
Call from PhoneA to PhoneB, accept on PhoneB.
@@ -495,6 +530,7 @@
The list should have three objects.
verify_funcs: list of phone call verify functions.
The list should have three objects.
+ reject_once: True for rejecting the second call once.
Returns:
If success, return 'call_AB' id in PhoneA.
@@ -536,6 +572,30 @@
call_ab_id = calls[0]
log.info("Step2: Call From PhoneC to PhoneA.")
+ if reject_once:
+ log.info("Step2-1: Reject incoming call once.")
+ if not initiate_call(
+ log,
+ ads[2],
+ ads[0].telephony['subscription'][get_incoming_voice_sub_id(
+ ads[0])]['phone_num']):
+ ads[2].log.error("Initiate call failed.")
+ raise _CallException("Failed to initiate call.")
+
+ if not wait_and_reject_call_for_subscription(
+ log,
+ ads[0],
+ get_incoming_voice_sub_id(ads[0]),
+ incoming_number= \
+ ads[2].telephony['subscription'][
+ get_incoming_voice_sub_id(
+ ads[2])]['phone_num']):
+ ads[0].log.error("Reject call fail.")
+ raise _CallException("Failed to reject call.")
+
+ _hangup_call(log, ads[2], "PhoneC")
+ time.sleep(15)
+
if not call_setup_teardown(
log,
ads[2],
@@ -691,7 +751,6 @@
return call_ab_id
-
def _test_call_mt_mt_add_swap_x(log,
ads,
num_swaps,
@@ -780,7 +839,6 @@
True if no error happened. Otherwise False.
"""
-
ad_hangup.log.info("Hangup, verify call continues.")
if not _hangup_call(log, ad_hangup):
ad_hangup.log.error("Phone fails to hang up")
@@ -812,4 +870,74 @@
return CALL_STATE_ACTIVE
return CALL_STATE_HOLDING
+def _test_wcdma_conference_merge_drop(log, ads, call_ab_id, call_ac_id):
+ """Test conference merge and drop in WCDMA/CSFB_WCDMA call.
+ PhoneA in WCDMA (or CSFB_WCDMA) call with PhoneB.
+ PhoneA in WCDMA (or CSFB_WCDMA) call with PhoneC.
+ Merge calls to conference on PhoneA.
+ Hangup on PhoneC, check call continues between AB.
+ Hangup on PhoneB, check A ends.
+
+ Args:
+ call_ab_id: call id for call_AB on PhoneA.
+ call_ac_id: call id for call_AC on PhoneA.
+
+ Returns:
+ True if succeed;
+ False if failed.
+ """
+ log.info("Step4: Merge to Conf Call and verify Conf Call.")
+ ads[0].droid.telecomCallJoinCallsInConf(call_ab_id, call_ac_id)
+ time.sleep(WAIT_TIME_IN_CALL)
+ calls = ads[0].droid.telecomCallGetCallIds()
+ ads[0].log.info("Calls in PhoneA %s", calls)
+ num_calls = num_active_calls(log, ads[0])
+ if num_calls != 3:
+ ads[0].log.error("Total number of call ids is not 3.")
+ if num_calls == 2:
+ if call_ab_id in calls and call_ac_id in calls:
+ ads[0].log.error("Calls were not merged."
+ " Failed to merge calls.")
+ raise signals.TestFailure(
+ "Calls were not merged. Failed to merge calls.",
+ extras={"fail_reason": "Calls were not merged."
+ " Failed to merge calls."})
+ return False
+ call_conf_id = None
+ for call_id in calls:
+ if call_id != call_ab_id and call_id != call_ac_id:
+ call_conf_id = call_id
+ if not call_conf_id:
+ log.error("Merge call fail, no new conference call id.")
+ return False
+ if not verify_incall_state(log, [ads[0], ads[1], ads[2]], True):
+ return False
+
+ if ads[0].droid.telecomCallGetCallState(
+ call_conf_id) != CALL_STATE_ACTIVE:
+ ads[0].log.error(
+ "Call_id: %s, state: %s, expected: STATE_ACTIVE", call_conf_id,
+ ads[0].droid.telecomCallGetCallState(call_conf_id))
+ return False
+
+ log.info("Step5: End call on PhoneC and verify call continues.")
+ if not _hangup_call(log, ads[2], "PhoneC"):
+ return False
+ time.sleep(WAIT_TIME_IN_CALL)
+ calls = ads[0].droid.telecomCallGetCallIds()
+ ads[0].log.info("Calls in PhoneA %s", calls)
+ if num_active_calls(log, ads[0]) != 1:
+ return False
+ if not verify_incall_state(log, [ads[0], ads[1]], True):
+ return False
+ if not verify_incall_state(log, [ads[2]], False):
+ return False
+
+ log.info("Step6: End call on PhoneB and verify PhoneA end.")
+ if not _hangup_call(log, ads[1], "PhoneB"):
+ return False
+ time.sleep(WAIT_TIME_IN_CALL)
+ if not verify_incall_state(log, [ads[0], ads[1], ads[2]], False):
+ return False
+ return True
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_voice_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_voice_utils.py
index 3f4d518..89d8f05 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_voice_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_voice_utils.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2016 - Google
+# Copyright 2021 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,101 +14,922 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import re
import time
+from queue import Empty
from acts import signals
+from acts.logger import epoch_to_log_line_timestamp
+from acts.utils import get_current_epoch_time
from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
+from acts_contrib.test_utils.tel.tel_defines import CarrierConfigs
+from acts_contrib.test_utils.tel.tel_defines import CARRIER_NTT_DOCOMO, CARRIER_KDDI, CARRIER_RAKUTEN, CARRIER_SBM
from acts_contrib.test_utils.tel.tel_defines import CALL_PROPERTY_HIGH_DEF_AUDIO
from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_ACTIVE
from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_HOLDING
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC
-from acts_contrib.test_utils.tel.tel_defines import CARRIER_TMO
+from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED
from acts_contrib.test_utils.tel.tel_defines import GEN_2G
from acts_contrib.test_utils.tel.tel_defines import GEN_3G
-from acts_contrib.test_utils.tel.tel_defines import GEN_4G
-from acts_contrib.test_utils.tel.tel_defines import GEN_5G
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOLTE_ENABLED
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED
+from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND
+from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND
+from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
+from acts_contrib.test_utils.tel.tel_defines import MAX_SAVED_VOICE_MAIL
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_DROP
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_IDLE_EVENT
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_INITIATION
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALLEE_RINGING
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_TELECOM_RINGING
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOICE_MAIL_COUNT
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
-from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_CDMA2000
-from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
-from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
-from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_WCDMA
-from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_WLAN
from acts_contrib.test_utils.tel.tel_defines import RAT_1XRTT
from acts_contrib.test_utils.tel.tel_defines import RAT_IWLAN
from acts_contrib.test_utils.tel.tel_defines import RAT_LTE
from acts_contrib.test_utils.tel.tel_defines import RAT_UMTS
+from acts_contrib.test_utils.tel.tel_defines import RAT_UNKNOWN
+from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_IDLE
+from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_OFFHOOK
+from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_RINGING
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_REG_AND_CALL
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_LEAVE_VOICE_MAIL
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_CDMA
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GSM_ONLY
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GSM_UMTS
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_CDMA_EVDO
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_GSM_WCDMA
-from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
-from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_REJECT_CALL
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.tel.tel_defines import EventCallStateChanged
+from acts_contrib.test_utils.tel.tel_defines import EventMessageWaitingIndicatorChanged
+from acts_contrib.test_utils.tel.tel_defines import CallStateContainer
+from acts_contrib.test_utils.tel.tel_defines import MessageWaitingIndicatorContainer
+from acts_contrib.test_utils.tel.tel_ims_utils import is_wfc_enabled
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_wfc
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_volte_enabled
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_enabled
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_disabled
+from acts_contrib.test_utils.tel.tel_lookup_tables import get_voice_mail_delete_digit
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_network_rat
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_not_network_rat
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_voice_attach
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_outgoing_call
from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id
-from acts_contrib.test_utils.tel.tel_test_utils import call_reject_leave_message
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown_for_call_forwarding
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown_for_call_waiting
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_generation
-from acts_contrib.test_utils.tel.tel_test_utils import \
- ensure_network_generation_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import \
- ensure_network_rat_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_test_utils import _wait_for_droid_in_state
+from acts_contrib.test_utils.tel.tel_test_utils import check_call_state_connected_by_adb
+from acts_contrib.test_utils.tel.tel_test_utils import check_call_state_idle_by_adb
+from acts_contrib.test_utils.tel.tel_test_utils import check_phone_number_match
+from acts_contrib.test_utils.tel.tel_test_utils import check_voice_mail_count
+from acts_contrib.test_utils.tel.tel_test_utils import check_voice_network_type
+from acts_contrib.test_utils.tel.tel_test_utils import get_call_uri
+from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
from acts_contrib.test_utils.tel.tel_test_utils import get_network_gen_for_subscription
from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat
from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import get_telephony_signal_strength
+from acts_contrib.test_utils.tel.tel_test_utils import get_number_from_tel_uri
from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
-from acts_contrib.test_utils.tel.tel_test_utils import is_wfc_enabled
-from acts_contrib.test_utils.tel.tel_test_utils import \
- reset_preferred_network_type_to_allowable_range
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import set_wifi_to_default
-from acts_contrib.test_utils.tel.tel_test_utils import TelResultWrapper
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
-from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import \
- wait_for_data_attach_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_enhanced_4g_lte_setting
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_generation
-from acts_contrib.test_utils.tel.tel_test_utils import \
- wait_for_network_generation_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_not_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import \
- wait_for_network_rat_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import \
- wait_for_not_network_rat_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_volte_enabled
-from acts_contrib.test_utils.tel.tel_test_utils import \
- wait_for_voice_attach_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wfc_enabled
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wfc_disabled
-from acts_contrib.test_utils.tel.tel_test_utils import get_capability_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import get_user_config_profile
+from acts_contrib.test_utils.tel.tel_test_utils import get_voice_mail_number
+from acts_contrib.test_utils.tel.tel_test_utils import is_event_match
+from acts_contrib.test_utils.tel.tel_test_utils import is_event_match_for_list
from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_nsa_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import TelResultWrapper
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
+from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
+from acts_contrib.test_utils.tel.tel_test_utils import wait_for_state
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
CallResult = TelephonyVoiceTestResult.CallResult.Value
+result_dict ={}
+voice_call_type = {}
+
+
+def check_call_status(ad, voice_type_init=None, voice_type_in_call=None):
+ """"
+ Args:
+ ad: Android device object
+ voice_type_init: Voice network type before initiate call
+ voice_type_in_call: Voice network type in call state
+
+ Return:
+ voice_call_type_dict: Voice call status
+ """
+ dut = str(ad.serial)
+ network_type = voice_type_init + "_" + voice_type_in_call
+ if network_type == "NR_NR":
+ voice_call_type_dict = update_voice_call_type_dict(dut, "VoNR")
+ elif network_type == "NR_LTE":
+ voice_call_type_dict = update_voice_call_type_dict(dut, "EPSFB")
+ elif network_type == "LTE_LTE":
+ voice_call_type_dict = update_voice_call_type_dict(dut, "VoLTE")
+ elif network_type == "LTE_WCDMA":
+ voice_call_type_dict = update_voice_call_type_dict(dut, "CSFB")
+ else:
+ voice_call_type_dict = update_voice_call_type_dict(dut, "UNKNOWN")
+ return voice_call_type_dict
+
+
+def update_voice_call_type_dict(dut, key):
+ """
+ Args:
+ dut: Serial Number of android device object
+ key: Network subscription parameter (VoNR or EPSFB or VoLTE or CSFB or UNKNOWN)
+ Return:
+ voice_call_type: Voice call status
+ """
+ if dut in voice_call_type.keys():
+ voice_call_type[dut][key] += 1
+ else:
+ voice_call_type[dut] = {key:0}
+ voice_call_type[dut][key] += 1
+ return voice_call_type
+
+
+def dial_phone_number(ad, callee_number):
+ for number in str(callee_number):
+ if number == "#":
+ ad.send_keycode("POUND")
+ elif number == "*":
+ ad.send_keycode("STAR")
+ elif number in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]:
+ ad.send_keycode("%s" % number)
+
+
+def disconnect_call_by_id(log, ad, call_id):
+ """Disconnect call by call id.
+ """
+ ad.droid.telecomCallDisconnect(call_id)
+ return True
+
+
+def dumpsys_last_call_info(ad):
+ """ Get call information by dumpsys telecom. """
+ num = dumpsys_last_call_number(ad)
+ output = ad.adb.shell("dumpsys telecom")
+ result = re.search(r"Call TC@%s: {(.*?)}" % num, output, re.DOTALL)
+ call_info = {"TC": num}
+ if result:
+ result = result.group(1)
+ for attr in ("startTime", "endTime", "direction", "isInterrupted",
+ "callTechnologies", "callTerminationsReason",
+ "isVideoCall", "callProperties"):
+ match = re.search(r"%s: (.*)" % attr, result)
+ if match:
+ if attr in ("startTime", "endTime"):
+ call_info[attr] = epoch_to_log_line_timestamp(
+ int(match.group(1)))
+ else:
+ call_info[attr] = match.group(1)
+ ad.log.debug("call_info = %s", call_info)
+ return call_info
+
+
+def dumpsys_last_call_number(ad):
+ output = ad.adb.shell("dumpsys telecom")
+ call_nums = re.findall("Call TC@(\d+):", output)
+ if not call_nums:
+ return 0
+ else:
+ return int(call_nums[-1])
+
+
+def dumpsys_new_call_info(ad, last_tc_number, retries=3, interval=5):
+ for i in range(retries):
+ if dumpsys_last_call_number(ad) > last_tc_number:
+ call_info = dumpsys_last_call_info(ad)
+ ad.log.info("New call info = %s", sorted(call_info.items()))
+ return call_info
+ else:
+ time.sleep(interval)
+ ad.log.error("New call is not in sysdump telecom")
+ return {}
+
+
+def emergency_dialer_call_by_keyevent(ad, callee_number):
+ for i in range(3):
+ if "EmergencyDialer" in ad.get_my_current_focus_window():
+ ad.log.info("EmergencyDialer is the current focus window")
+ break
+ elif i <= 2:
+ ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL")
+ time.sleep(1)
+ else:
+ ad.log.error("Unable to bring up EmergencyDialer")
+ return False
+ ad.log.info("Make a phone call to %s", callee_number)
+ dial_phone_number(ad, callee_number)
+ ad.send_keycode("CALL")
+
+
+def get_current_voice_rat(log, ad):
+ """Return current Voice RAT
+
+ Args:
+ ad: Android device object.
+ """
+ return get_current_voice_rat_for_subscription(
+ log, ad, get_outgoing_voice_sub_id(ad))
+
+
+def get_current_voice_rat_for_subscription(log, ad, sub_id):
+ """Return current Voice RAT for subscription id.
+
+ Args:
+ ad: Android device object.
+ sub_id: subscription id.
+ """
+ return get_network_rat_for_subscription(log, ad, sub_id,
+ NETWORK_SERVICE_VOICE)
+
+
+def hangup_call_by_adb(ad):
+ """Make emergency call by EmergencyDialer.
+
+ Args:
+ ad: Caller android device object.
+ callee_number: Callee phone number.
+ """
+ ad.log.info("End call by adb")
+ ad.send_keycode("ENDCALL")
+
+
+def hangup_call(log, ad, is_emergency=False):
+ """Hang up ongoing active call.
+
+ Args:
+ log: log object.
+ ad: android device object.
+
+ Returns:
+ True: if all calls are cleared
+ False: for errors
+ """
+ # short circuit in case no calls are active
+ if not ad.droid.telecomIsInCall():
+ ad.log.warning("No active call exists.")
+ return True
+ ad.ed.clear_events(EventCallStateChanged)
+ ad.droid.telephonyStartTrackingCallState()
+ ad.log.info("Hangup call.")
+ if is_emergency:
+ for call in ad.droid.telecomCallGetCallIds():
+ ad.droid.telecomCallDisconnect(call)
+ else:
+ ad.droid.telecomEndCall()
+
+ try:
+ ad.ed.wait_for_event(
+ EventCallStateChanged,
+ is_event_match,
+ timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT,
+ field=CallStateContainer.CALL_STATE,
+ value=TELEPHONY_STATE_IDLE)
+ except Empty:
+ ad.log.warning("Call state IDLE event is not received after hang up.")
+ finally:
+ ad.droid.telephonyStopTrackingCallStateChange()
+ if not wait_for_state(ad.droid.telecomIsInCall, False, 15, 1):
+ ad.log.error("Telecom is in call, hangup call failed.")
+ return False
+ return True
+
+
+def initiate_emergency_dialer_call_by_adb(
+ log,
+ ad,
+ callee_number,
+ timeout=MAX_WAIT_TIME_CALL_INITIATION,
+ checking_interval=5):
+ """Make emergency call by EmergencyDialer.
+
+ Args:
+ ad: Caller android device object.
+ callee_number: Callee phone number.
+ emergency : specify the call is emergency.
+ Optional. Default value is False.
+
+ Returns:
+ result: if phone call is placed successfully.
+ """
+ try:
+ # Make a Call
+ ad.wakeup_screen()
+ ad.send_keycode("MENU")
+ ad.log.info("Call %s", callee_number)
+ ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL")
+ ad.adb.shell(
+ "am start -a android.intent.action.CALL_EMERGENCY -d tel:%s" %
+ callee_number)
+ if not timeout: return True
+ ad.log.info("Check call state")
+ # Verify Call State
+ elapsed_time = 0
+ while elapsed_time < timeout:
+ time.sleep(checking_interval)
+ elapsed_time += checking_interval
+ if check_call_state_connected_by_adb(ad):
+ ad.log.info("Call to %s is connected", callee_number)
+ return True
+ if check_call_state_idle_by_adb(ad):
+ ad.log.info("Call to %s failed", callee_number)
+ return False
+ ad.log.info("Make call to %s failed", callee_number)
+ return False
+ except Exception as e:
+ ad.log.error("initiate emergency call failed with error %s", e)
+
+
+def initiate_call(log,
+ ad,
+ callee_number,
+ emergency=False,
+ incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
+ video=False):
+ """Make phone call from caller to callee.
+
+ Args:
+ ad_caller: Caller android device object.
+ callee_number: Callee phone number.
+ emergency : specify the call is emergency.
+ Optional. Default value is False.
+ incall_ui_display: show the dialer UI foreground or backgroud
+ video: whether to initiate as video call
+
+ Returns:
+ result: if phone call is placed successfully.
+ """
+ ad.ed.clear_events(EventCallStateChanged)
+ sub_id = get_outgoing_voice_sub_id(ad)
+ begin_time = get_device_epoch_time(ad)
+ ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
+ try:
+ # Make a Call
+ ad.log.info("Make a phone call to %s", callee_number)
+ if emergency:
+ ad.droid.telecomCallEmergencyNumber(callee_number)
+ else:
+ ad.droid.telecomCallNumber(callee_number, video)
+
+ # Verify OFFHOOK state
+ if not wait_for_call_offhook_for_subscription(
+ log, ad, sub_id, event_tracking_started=True):
+ ad.log.info("sub_id %s not in call offhook state", sub_id)
+ last_call_drop_reason(ad, begin_time=begin_time)
+ return False
+ else:
+ return True
+
+ finally:
+ if hasattr(ad, "sdm_log") and getattr(ad, "sdm_log"):
+ ad.adb.shell("i2cset -fy 3 64 6 1 b", ignore_status=True)
+ ad.adb.shell("i2cset -fy 3 65 6 1 b", ignore_status=True)
+ ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
+
+ if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
+ ad.droid.telecomShowInCallScreen()
+ elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
+ ad.droid.showHomeScreen()
+
+
+def last_call_drop_reason(ad, begin_time=None):
+ reasons = ad.search_logcat(
+ "qcril_qmi_voice_map_qmi_to_ril_last_call_failure_cause", begin_time)
+ reason_string = ""
+ if reasons:
+ log_msg = "Logcat call drop reasons:"
+ for reason in reasons:
+ log_msg = "%s\n\t%s" % (log_msg, reason["log_message"])
+ if "ril reason str" in reason["log_message"]:
+ reason_string = reason["log_message"].split(":")[-1].strip()
+ ad.log.info(log_msg)
+ reasons = ad.search_logcat("ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION",
+ begin_time)
+ if reasons:
+ ad.log.warning("ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION is seen")
+ ad.log.info("last call dumpsys: %s",
+ sorted(dumpsys_last_call_info(ad).items()))
+ return reason_string
+
+
+def call_reject(log, ad_caller, ad_callee, reject=True):
+ """Caller call Callee, then reject on callee.
+
+
+ """
+ subid_caller = ad_caller.droid.subscriptionGetDefaultVoiceSubId()
+ subid_callee = ad_callee.incoming_voice_sub_id
+ ad_caller.log.info("Sub-ID Caller %s, Sub-ID Callee %s", subid_caller,
+ subid_callee)
+ return call_reject_for_subscription(log, ad_caller, ad_callee,
+ subid_caller, subid_callee, reject)
+
+
+def call_reject_for_subscription(log,
+ ad_caller,
+ ad_callee,
+ subid_caller,
+ subid_callee,
+ reject=True):
+ """
+ """
+
+ caller_number = ad_caller.telephony['subscription'][subid_caller][
+ 'phone_num']
+ callee_number = ad_callee.telephony['subscription'][subid_callee][
+ 'phone_num']
+
+ ad_caller.log.info("Call from %s to %s", caller_number, callee_number)
+ if not initiate_call(log, ad_caller, callee_number):
+ ad_caller.log.error("Initiate call failed")
+ return False
+
+ if not wait_and_reject_call_for_subscription(
+ log, ad_callee, subid_callee, caller_number, WAIT_TIME_REJECT_CALL,
+ reject):
+ ad_callee.log.error("Reject call fail.")
+ return False
+ # Check if incoming call is cleared on callee or not.
+ if ad_callee.droid.telephonyGetCallStateForSubscription(
+ subid_callee) == TELEPHONY_STATE_RINGING:
+ ad_callee.log.error("Incoming call is not cleared")
+ return False
+ # Hangup on caller
+ hangup_call(log, ad_caller)
+ return True
+
+
+def call_reject_leave_message(log,
+ ad_caller,
+ ad_callee,
+ verify_caller_func=None,
+ wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL):
+ """On default voice subscription, Call from caller to callee,
+ reject on callee, caller leave a voice mail.
+
+ 1. Caller call Callee.
+ 2. Callee reject incoming call.
+ 3. Caller leave a voice mail.
+ 4. Verify callee received the voice mail notification.
+
+ Args:
+ ad_caller: caller android device object.
+ ad_callee: callee android device object.
+ verify_caller_func: function to verify caller is in correct state while in-call.
+ This is optional, default is None.
+ wait_time_in_call: time to wait when leaving a voice mail.
+ This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL
+
+ Returns:
+ True: if voice message is received on callee successfully.
+ False: for errors
+ """
+ subid_caller = get_outgoing_voice_sub_id(ad_caller)
+ subid_callee = get_incoming_voice_sub_id(ad_callee)
+ return call_reject_leave_message_for_subscription(
+ log, ad_caller, ad_callee, subid_caller, subid_callee,
+ verify_caller_func, wait_time_in_call)
+
+
+def check_reject_needed_for_voice_mail(log, ad_callee):
+ """Check if the carrier requires reject call to receive voice mail or just keep ringing
+ Requested in b//155935290
+ Four Japan carriers do not need to reject
+ SBM, KDDI, Ntt Docomo, Rakuten
+ Args:
+ log: log object
+ ad_callee: android device object
+ Returns:
+ True if callee's carrier is not one of the four Japan carriers
+ False if callee's carrier is one of the four Japan carriers
+ """
+
+ operators_no_reject = [CARRIER_NTT_DOCOMO,
+ CARRIER_KDDI,
+ CARRIER_RAKUTEN,
+ CARRIER_SBM]
+ operator_name = get_operator_name(log, ad_callee)
+
+ return operator_name not in operators_no_reject
+
+
+def _is_on_message_waiting_event_true(event):
+ """Private function to return if the received EventMessageWaitingIndicatorChanged
+ event MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING field is True.
+ """
+ return event['data'][MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING]
+
+
+def call_reject_leave_message_for_subscription(
+ log,
+ ad_caller,
+ ad_callee,
+ subid_caller,
+ subid_callee,
+ verify_caller_func=None,
+ wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL):
+ """On specific voice subscription, Call from caller to callee,
+ reject on callee, caller leave a voice mail.
+
+ 1. Caller call Callee.
+ 2. Callee reject incoming call.
+ 3. Caller leave a voice mail.
+ 4. Verify callee received the voice mail notification.
+
+ Args:
+ ad_caller: caller android device object.
+ ad_callee: callee android device object.
+ subid_caller: caller's subscription id.
+ subid_callee: callee's subscription id.
+ verify_caller_func: function to verify caller is in correct state while in-call.
+ This is optional, default is None.
+ wait_time_in_call: time to wait when leaving a voice mail.
+ This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL
+
+ Returns:
+ True: if voice message is received on callee successfully.
+ False: for errors
+ """
+
+ # Currently this test utility only works for TMO and ATT and SPT.
+ # It does not work for VZW (see b/21559800)
+ # "with VVM TelephonyManager APIs won't work for vm"
+
+ caller_number = ad_caller.telephony['subscription'][subid_caller][
+ 'phone_num']
+ callee_number = ad_callee.telephony['subscription'][subid_callee][
+ 'phone_num']
+
+ ad_caller.log.info("Call from %s to %s", caller_number, callee_number)
+
+ try:
+ voice_mail_count_before = ad_callee.droid.telephonyGetVoiceMailCountForSubscription(
+ subid_callee)
+ ad_callee.log.info("voice mail count is %s", voice_mail_count_before)
+ # -1 means there are unread voice mail, but the count is unknown
+ # 0 means either this API not working (VZW) or no unread voice mail.
+ if voice_mail_count_before != 0:
+ log.warning("--Pending new Voice Mail, please clear on phone.--")
+
+ if not initiate_call(log, ad_caller, callee_number):
+ ad_caller.log.error("Initiate call failed.")
+ return False
+ if check_reject_needed_for_voice_mail(log, ad_callee):
+ carrier_specific_delay_reject = 30
+ else:
+ carrier_specific_delay_reject = 2
+ carrier_reject_call = not check_reject_needed_for_voice_mail(log, ad_callee)
+
+ if not wait_and_reject_call_for_subscription(
+ log, ad_callee, subid_callee, incoming_number=caller_number, delay_reject=carrier_specific_delay_reject,
+ reject=carrier_reject_call):
+ ad_callee.log.error("Reject call fail.")
+ return False
+
+ ad_callee.droid.telephonyStartTrackingVoiceMailStateChangeForSubscription(
+ subid_callee)
+
+ # ensure that all internal states are updated in telecom
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+ ad_callee.ed.clear_events(EventCallStateChanged)
+
+ if verify_caller_func and not verify_caller_func(log, ad_caller):
+ ad_caller.log.error("Caller not in correct state!")
+ return False
+
+ # TODO: b/26293512 Need to play some sound to leave message.
+ # Otherwise carrier voice mail server may drop this voice mail.
+ time.sleep(wait_time_in_call)
+
+ if not verify_caller_func:
+ caller_state_result = ad_caller.droid.telecomIsInCall()
+ else:
+ caller_state_result = verify_caller_func(log, ad_caller)
+ if not caller_state_result:
+ ad_caller.log.error("Caller not in correct state after %s seconds",
+ wait_time_in_call)
+
+ if not hangup_call(log, ad_caller):
+ ad_caller.log.error("Error in Hanging-Up Call")
+ return False
+
+ ad_callee.log.info("Wait for voice mail indicator on callee.")
+ try:
+ event = ad_callee.ed.wait_for_event(
+ EventMessageWaitingIndicatorChanged,
+ _is_on_message_waiting_event_true)
+ ad_callee.log.info("Got event %s", event)
+ except Empty:
+ ad_callee.log.warning("No expected event %s",
+ EventMessageWaitingIndicatorChanged)
+ return False
+ voice_mail_count_after = ad_callee.droid.telephonyGetVoiceMailCountForSubscription(
+ subid_callee)
+ ad_callee.log.info(
+ "telephonyGetVoiceMailCount output - before: %s, after: %s",
+ voice_mail_count_before, voice_mail_count_after)
+
+ # voice_mail_count_after should:
+ # either equals to (voice_mail_count_before + 1) [For ATT and SPT]
+ # or equals to -1 [For TMO]
+ # -1 means there are unread voice mail, but the count is unknown
+ if not check_voice_mail_count(log, ad_callee, voice_mail_count_before,
+ voice_mail_count_after):
+ log.error("before and after voice mail count is not incorrect.")
+ return False
+ finally:
+ ad_callee.droid.telephonyStopTrackingVoiceMailStateChangeForSubscription(
+ subid_callee)
+ return True
+
+
+def call_voicemail_erase_all_pending_voicemail(log, ad):
+ """Script for phone to erase all pending voice mail.
+ This script only works for TMO and ATT and SPT currently.
+ This script only works if phone have already set up voice mail options,
+ and phone should disable password protection for voice mail.
+
+ 1. If phone don't have pending voice message, return True.
+ 2. Dial voice mail number.
+ For TMO, the number is '123'
+ For ATT, the number is phone's number
+ For SPT, the number is phone's number
+ 3. Wait for voice mail connection setup.
+ 4. Wait for voice mail play pending voice message.
+ 5. Send DTMF to delete one message.
+ The digit is '7'.
+ 6. Repeat steps 4 and 5 until voice mail server drop this call.
+ (No pending message)
+ 6. Check telephonyGetVoiceMailCount result. it should be 0.
+
+ Args:
+ log: log object
+ ad: android device object
+ Returns:
+ False if error happens. True is succeed.
+ """
+ log.info("Erase all pending voice mail.")
+ count = ad.droid.telephonyGetVoiceMailCount()
+ if count == 0:
+ ad.log.info("No Pending voice mail.")
+ return True
+ if count == -1:
+ ad.log.info("There is pending voice mail, but the count is unknown")
+ count = MAX_SAVED_VOICE_MAIL
+ else:
+ ad.log.info("There are %s voicemails", count)
+
+ voice_mail_number = get_voice_mail_number(log, ad)
+ delete_digit = get_voice_mail_delete_digit(get_operator_name(log, ad))
+ if not initiate_call(log, ad, voice_mail_number):
+ log.error("Initiate call to voice mail failed.")
+ return False
+ time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
+ callId = ad.droid.telecomCallGetCallIds()[0]
+ time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
+ while (is_phone_in_call(log, ad) and (count > 0)):
+ ad.log.info("Press %s to delete voice mail.", delete_digit)
+ ad.droid.telecomCallPlayDtmfTone(callId, delete_digit)
+ ad.droid.telecomCallStopDtmfTone(callId)
+ time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
+ count -= 1
+ if is_phone_in_call(log, ad):
+ hangup_call(log, ad)
+
+ # wait for telephonyGetVoiceMailCount to update correct result
+ remaining_time = MAX_WAIT_TIME_VOICE_MAIL_COUNT
+ while ((remaining_time > 0)
+ and (ad.droid.telephonyGetVoiceMailCount() != 0)):
+ time.sleep(1)
+ remaining_time -= 1
+ current_voice_mail_count = ad.droid.telephonyGetVoiceMailCount()
+ ad.log.info("telephonyGetVoiceMailCount: %s", current_voice_mail_count)
+ return (current_voice_mail_count == 0)
+
+
+def call_setup_teardown(log,
+ ad_caller,
+ ad_callee,
+ ad_hangup=None,
+ verify_caller_func=None,
+ verify_callee_func=None,
+ wait_time_in_call=WAIT_TIME_IN_CALL,
+ incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
+ dialing_number_length=None,
+ video_state=None,
+ slot_id_callee=None,
+ voice_type_init=None,
+ call_stats_check=False,
+ result_info=result_dict):
+ """ Call process, including make a phone call from caller,
+ accept from callee, and hang up. The call is on default voice subscription
+
+ In call process, call from <droid_caller> to <droid_callee>,
+ accept the call, (optional)then hang up from <droid_hangup>.
+
+ Args:
+ ad_caller: Caller Android Device Object.
+ ad_callee: Callee Android Device Object.
+ ad_hangup: Android Device Object end the phone call.
+ Optional. Default value is None, and phone call will continue.
+ verify_call_mode_caller: func_ptr to verify caller in correct mode
+ Optional. Default is None
+ verify_call_mode_caller: func_ptr to verify caller in correct mode
+ Optional. Default is None
+ incall_ui_display: after answer the call, bring in-call UI to foreground or
+ background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
+ if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
+ if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
+ else, do nothing.
+ dialing_number_length: the number of digits used for dialing
+ slot_id_callee : the slot if of the callee to call to
+
+ Returns:
+ True if call process without any error.
+ False if error happened.
+
+ """
+ subid_caller = get_outgoing_voice_sub_id(ad_caller)
+ if slot_id_callee is None:
+ subid_callee = get_incoming_voice_sub_id(ad_callee)
+ else:
+ subid_callee = get_subid_from_slot_index(log, ad_callee, slot_id_callee)
+
+ return call_setup_teardown_for_subscription(
+ log, ad_caller, ad_callee, subid_caller, subid_callee, ad_hangup,
+ verify_caller_func, verify_callee_func, wait_time_in_call,
+ incall_ui_display, dialing_number_length, video_state,
+ voice_type_init, call_stats_check, result_info)
+
+
+def call_setup_teardown_for_subscription(
+ log,
+ ad_caller,
+ ad_callee,
+ subid_caller,
+ subid_callee,
+ ad_hangup=None,
+ verify_caller_func=None,
+ verify_callee_func=None,
+ wait_time_in_call=WAIT_TIME_IN_CALL,
+ incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
+ dialing_number_length=None,
+ video_state=None,
+ voice_type_init=None,
+ call_stats_check=False,
+ result_info=result_dict):
+ """ Call process, including make a phone call from caller,
+ accept from callee, and hang up. The call is on specified subscription
+
+ In call process, call from <droid_caller> to <droid_callee>,
+ accept the call, (optional)then hang up from <droid_hangup>.
+
+ Args:
+ ad_caller: Caller Android Device Object.
+ ad_callee: Callee Android Device Object.
+ subid_caller: Caller subscription ID
+ subid_callee: Callee subscription ID
+ ad_hangup: Android Device Object end the phone call.
+ Optional. Default value is None, and phone call will continue.
+ verify_call_mode_caller: func_ptr to verify caller in correct mode
+ Optional. Default is None
+ verify_call_mode_caller: func_ptr to verify caller in correct mode
+ Optional. Default is None
+ incall_ui_display: after answer the call, bring in-call UI to foreground or
+ background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
+ if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
+ if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
+ else, do nothing.
+
+ Returns:
+ TelResultWrapper which will evaluate as False if error.
+
+ """
+ CHECK_INTERVAL = 5
+ begin_time = get_current_epoch_time()
+ if not verify_caller_func:
+ verify_caller_func = is_phone_in_call
+ if not verify_callee_func:
+ verify_callee_func = is_phone_in_call
+
+ caller_number = ad_caller.telephony['subscription'][subid_caller][
+ 'phone_num']
+ callee_number = ad_callee.telephony['subscription'][subid_callee][
+ 'phone_num']
+
+ callee_number = truncate_phone_number(
+ log,
+ caller_number,
+ callee_number,
+ dialing_number_length)
+
+ tel_result_wrapper = TelResultWrapper(CallResult('SUCCESS'))
+ msg = "Call from %s to %s" % (caller_number, callee_number)
+ if video_state:
+ msg = "Video %s" % msg
+ video = True
+ else:
+ video = False
+ if ad_hangup:
+ msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
+ ad_caller.log.info(msg)
+
+ for ad in (ad_caller, ad_callee):
+ call_ids = ad.droid.telecomCallGetCallIds()
+ setattr(ad, "call_ids", call_ids)
+ if call_ids:
+ ad.log.info("Pre-exist CallId %s before making call", call_ids)
+
+ if not initiate_call(
+ log,
+ ad_caller,
+ callee_number,
+ incall_ui_display=incall_ui_display,
+ video=video):
+ ad_caller.log.error("Initiate call failed.")
+ tel_result_wrapper.result_value = CallResult('INITIATE_FAILED')
+ return tel_result_wrapper
+ else:
+ ad_caller.log.info("Caller initate call successfully")
+ if not wait_and_answer_call_for_subscription(
+ log,
+ ad_callee,
+ subid_callee,
+ incoming_number=caller_number,
+ caller=ad_caller,
+ incall_ui_display=incall_ui_display,
+ video_state=video_state):
+ ad_callee.log.error("Answer call fail.")
+ tel_result_wrapper.result_value = CallResult(
+ 'NO_RING_EVENT_OR_ANSWER_FAILED')
+ return tel_result_wrapper
+ else:
+ ad_callee.log.info("Callee answered the call successfully")
+
+ for ad, call_func in zip([ad_caller, ad_callee],
+ [verify_caller_func, verify_callee_func]):
+ call_ids = ad.droid.telecomCallGetCallIds()
+ new_call_ids = set(call_ids) - set(ad.call_ids)
+ if not new_call_ids:
+ ad.log.error(
+ "No new call ids are found after call establishment")
+ ad.log.error("telecomCallGetCallIds returns %s",
+ ad.droid.telecomCallGetCallIds())
+ tel_result_wrapper.result_value = CallResult('NO_CALL_ID_FOUND')
+ for new_call_id in new_call_ids:
+ if not wait_for_in_call_active(ad, call_id=new_call_id):
+ tel_result_wrapper.result_value = CallResult(
+ 'CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT')
+ else:
+ ad.log.info("callProperties = %s",
+ ad.droid.telecomCallGetProperties(new_call_id))
+
+ if not ad.droid.telecomCallGetAudioState():
+ ad.log.error("Audio is not in call state")
+ tel_result_wrapper.result_value = CallResult(
+ 'AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT')
+
+ if call_func(log, ad):
+ ad.log.info("Call is in %s state", call_func.__name__)
+ else:
+ ad.log.error("Call is not in %s state, voice in RAT %s",
+ call_func.__name__,
+ ad.droid.telephonyGetCurrentVoiceNetworkType())
+ tel_result_wrapper.result_value = CallResult(
+ 'CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT')
+ if not tel_result_wrapper:
+ return tel_result_wrapper
+
+ if call_stats_check:
+ voice_type_in_call = check_voice_network_type([ad_caller, ad_callee], voice_init=False)
+ phone_a_call_type = check_call_status(ad_caller,
+ voice_type_init[0],
+ voice_type_in_call[0])
+ result_info["Call Stats"] = phone_a_call_type
+ ad_caller.log.debug("Voice Call Type: %s", phone_a_call_type)
+ phone_b_call_type = check_call_status(ad_callee,
+ voice_type_init[1],
+ voice_type_in_call[1])
+ result_info["Call Stats"] = phone_b_call_type
+ ad_callee.log.debug("Voice Call Type: %s", phone_b_call_type)
+
+ return wait_for_call_end(
+ log,
+ ad_caller,
+ ad_callee,
+ ad_hangup,
+ verify_caller_func,
+ verify_callee_func,
+ begin_time,
+ check_interval=CHECK_INTERVAL,
+ tel_result_wrapper=TelResultWrapper(CallResult('SUCCESS')),
+ wait_time_in_call=wait_time_in_call)
def two_phone_call_leave_voice_mail(
@@ -495,1098 +1316,38 @@
return tel_result
-def three_phone_call_forwarding_short_seq(log,
- phone_a,
- phone_a_idle_func,
- phone_a_in_call_check_func,
- phone_b,
- phone_c,
- wait_time_in_call=WAIT_TIME_IN_CALL,
- call_forwarding_type="unconditional",
- retry=2):
- """Short sequence of call process with call forwarding.
- Test steps:
- 1. Ensure all phones are initially in idle state.
- 2. Enable call forwarding on Phone A.
- 3. Make a call from Phone B to Phone A, The call should be forwarded to
- PhoneC. Accept the call on Phone C.
- 4. Ensure the call is connected and in correct phone state.
- 5. Hang up the call on Phone B.
- 6. Ensure all phones are in idle state.
- 7. Disable call forwarding on Phone A.
- 7. Make a call from Phone B to Phone A, The call should NOT be forwarded
- to PhoneC. Accept the call on Phone A.
- 8. Ensure the call is connected and in correct phone state.
- 9. Hang up the call on Phone B.
+
+def is_phone_in_call(log, ad):
+ """Return True if phone in call.
Args:
- phone_a: android object of Phone A
- phone_a_idle_func: function to check idle state on Phone A
- phone_a_in_call_check_func: function to check in-call state on Phone A
- phone_b: android object of Phone B
- phone_c: android object of Phone C
- wait_time_in_call: time to wait in call.
- This is optional, default is WAIT_TIME_IN_CALL
- call_forwarding_type:
- - "unconditional"
- - "busy"
- - "not_answered"
- - "not_reachable"
- retry: times of retry
-
- Returns:
- True: if call sequence succeed.
- False: for errors
+ log: log object.
+ ad: android device.
"""
- ads = [phone_a, phone_b, phone_c]
-
- call_params = [
- (ads[1], ads[0], ads[2], ads[1], phone_a_in_call_check_func, False)
- ]
-
- if call_forwarding_type != "unconditional":
- call_params.append((
- ads[1],
- ads[0],
- ads[2],
- ads[1],
- phone_a_in_call_check_func,
- True))
-
- for param in call_params:
- ensure_phones_idle(log, ads)
- if phone_a_idle_func and not phone_a_idle_func(log, phone_a):
- phone_a.log.error("Phone A Failed to Reselect")
- return False
-
- time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL)
-
- log.info(
- "---> Call forwarding %s (caller: %s, callee: %s, callee forwarded:"
- " %s) <---",
- call_forwarding_type,
- param[0].serial,
- param[1].serial,
- param[2].serial)
- while not call_setup_teardown_for_call_forwarding(
- log,
- *param,
- wait_time_in_call=wait_time_in_call,
- call_forwarding_type=call_forwarding_type) and retry >= 0:
-
- if retry <= 0:
- log.error("Call forwarding %s failed." % call_forwarding_type)
- return False
- else:
- log.info(
- "RERUN the test case: 'Call forwarding %s'" %
- call_forwarding_type)
-
- retry = retry - 1
-
- return True
-
-def three_phone_call_waiting_short_seq(log,
- phone_a,
- phone_a_idle_func,
- phone_a_in_call_check_func,
- phone_b,
- phone_c,
- wait_time_in_call=WAIT_TIME_IN_CALL,
- call_waiting=True,
- scenario=None,
- retry=2):
- """Short sequence of call process with call waiting.
- Test steps:
- 1. Ensure all phones are initially in idle state.
- 2. Enable call waiting on Phone A.
- 3. Make the 1st call from Phone B to Phone A. Accept the call on Phone B.
- 4. Ensure the call is connected and in correct phone state.
- 5. Make the 2nd call from Phone C to Phone A. The call should be able to
- income correctly. Whether or not the 2nd call should be answered by
- Phone A depends on the scenario listed in the next step.
- 6. Following 8 scenarios will be tested:
- - 1st call ended first by Phone B during 2nd call incoming. 2nd call
- ended by Phone C
- - 1st call ended first by Phone B during 2nd call incoming. 2nd call
- ended by Phone A
- - 1st call ended first by Phone A during 2nd call incoming. 2nd call
- ended by Phone C
- - 1st call ended first by Phone A during 2nd call incoming. 2nd call
- ended by Phone A
- - 1st call ended by Phone B. 2nd call ended by Phone C
- - 1st call ended by Phone B. 2nd call ended by Phone A
- - 1st call ended by Phone A. 2nd call ended by Phone C
- - 1st call ended by Phone A. 2nd call ended by Phone A
- 7. Ensure all phones are in idle state.
-
- Args:
- phone_a: android object of Phone A
- phone_a_idle_func: function to check idle state on Phone A
- phone_a_in_call_check_func: function to check in-call state on Phone A
- phone_b: android object of Phone B
- phone_c: android object of Phone C
- wait_time_in_call: time to wait in call.
- This is optional, default is WAIT_TIME_IN_CALL
- call_waiting: True for call waiting enabled and False for disabled
- scenario: 1-8 for scenarios listed above
- retry: times of retry
-
- Returns:
- True: if call sequence succeed.
- False: for errors
- """
- ads = [phone_a, phone_b, phone_c]
-
- sub_test_cases = [
- {
- "description": "1st call ended first by caller1 during 2nd call"
- " incoming. 2nd call ended by caller2",
- "params": (
- ads[1],
- ads[0],
- ads[2],
- ads[1],
- ads[2],
- phone_a_in_call_check_func,
- True)},
- {
- "description": "1st call ended first by caller1 during 2nd call"
- " incoming. 2nd call ended by callee",
- "params": (
- ads[1],
- ads[0],
- ads[2],
- ads[1],
- ads[0],
- phone_a_in_call_check_func,
- True)},
- {
- "description": "1st call ended first by callee during 2nd call"
- " incoming. 2nd call ended by caller2",
- "params": (
- ads[1],
- ads[0],
- ads[2],
- ads[0],
- ads[2],
- phone_a_in_call_check_func,
- True)},
- {
- "description": "1st call ended first by callee during 2nd call"
- " incoming. 2nd call ended by callee",
- "params": (
- ads[1],
- ads[0],
- ads[2],
- ads[0],
- ads[0],
- phone_a_in_call_check_func,
- True)},
- {
- "description": "1st call ended by caller1. 2nd call ended by"
- " caller2",
- "params": (
- ads[1],
- ads[0],
- ads[2],
- ads[1],
- ads[2],
- phone_a_in_call_check_func,
- False)},
- {
- "description": "1st call ended by caller1. 2nd call ended by callee",
- "params": (
- ads[1],
- ads[0],
- ads[2],
- ads[1],
- ads[0],
- phone_a_in_call_check_func,
- False)},
- {
- "description": "1st call ended by callee. 2nd call ended by caller2",
- "params": (
- ads[1],
- ads[0],
- ads[2],
- ads[0],
- ads[2],
- phone_a_in_call_check_func,
- False)},
- {
- "description": "1st call ended by callee. 2nd call ended by callee",
- "params": (
- ads[1],
- ads[0],
- ads[2],
- ads[0],
- ads[0],
- phone_a_in_call_check_func,
- False)}
- ]
-
- if call_waiting:
- if not scenario:
- test_cases = sub_test_cases
- else:
- test_cases = [sub_test_cases[scenario-1]]
- else:
- test_cases = [
- {
- "description": "Call waiting deactivated",
- "params": (
- ads[1],
- ads[0],
- ads[2],
- ads[0],
- ads[0],
- phone_a_in_call_check_func,
- False)}
- ]
-
- results = []
-
- for test_case in test_cases:
- ensure_phones_idle(log, ads)
- if phone_a_idle_func and not phone_a_idle_func(log, phone_a):
- phone_a.log.error("Phone A Failed to Reselect")
- return False
-
- time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL)
-
- log.info(
- "---> %s (caller1: %s, caller2: %s, callee: %s) <---",
- test_case["description"],
- test_case["params"][1].serial,
- test_case["params"][2].serial,
- test_case["params"][0].serial)
-
- while not call_setup_teardown_for_call_waiting(
- log,
- *test_case["params"],
- wait_time_in_call=wait_time_in_call,
- call_waiting=call_waiting) and retry >= 0:
-
- if retry <= 0:
- log.error("Call waiting sub-case: '%s' failed." % test_case[
- "description"])
- results.append(False)
- else:
- log.info("RERUN the sub-case: '%s'" % test_case["description"])
-
- retry = retry - 1
-
- for result in results:
- if not result:
- return False
-
- return True
-
-def phone_setup_iwlan(log,
- ad,
- is_airplane_mode,
- wfc_mode,
- wifi_ssid=None,
- wifi_pwd=None,
- nw_gen=None):
- """Phone setup function for epdg call test.
- Set WFC mode according to wfc_mode.
- Set airplane mode according to is_airplane_mode.
- 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.
- is_airplane_mode: True to turn on airplane mode. False to turn off airplane mode.
- wfc_mode: WFC mode to set to.
- 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.
- nw_gen: network type selection. This is optional.
- GEN_4G for 4G, GEN_5G for 5G or None for doing nothing.
- Returns:
- True if success. False if fail.
- """
- return phone_setup_iwlan_for_subscription(log, ad,
- get_outgoing_voice_sub_id(ad),
- is_airplane_mode, wfc_mode,
- wifi_ssid, wifi_pwd, nw_gen)
-
-
-def phone_setup_iwlan_for_subscription(log,
- ad,
- sub_id,
- is_airplane_mode,
- wfc_mode,
- wifi_ssid=None,
- wifi_pwd=None,
- nw_gen=None):
- """Phone setup function for epdg call test for subscription id.
- Set WFC mode according to wfc_mode.
- Set airplane mode according to is_airplane_mode.
- 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.
- sub_id: subscription id.
- is_airplane_mode: True to turn on airplane mode. False to turn off airplane mode.
- wfc_mode: WFC mode to set to.
- 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.
- nw_gen: network type selection. This is optional.
- GEN_4G for 4G, GEN_5G for 5G or None for doing nothing.
- 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.")
-
- if nw_gen:
- if not ensure_network_generation_for_subscription(
- log, ad, sub_id, nw_gen, voice_or_data=NETWORK_SERVICE_DATA):
- ad.log.error("Failed to set to %s data.", nw_gen)
- return False
- toggle_airplane_mode(log, ad, is_airplane_mode, strict_checking=False)
-
- if not toggle_volte_for_subscription(log, ad, sub_id, new_state=True):
- return 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)
- return False
- else:
- 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_for_subscription(ad, wfc_mode, sub_id):
- ad.log.error("Unable to set WFC mode to %s.", wfc_mode)
- return False
-
- if wfc_mode != WFC_MODE_DISABLED:
- if not wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED):
- ad.log.error("WFC is not enabled")
- return False
-
- return True
-
-
-def phone_setup_iwlan_cellular_preferred(log,
- ad,
- wifi_ssid=None,
- wifi_pwd=None):
- """Phone setup function for iwlan Non-APM CELLULAR_PREFERRED test.
- Set WFC mode according to CELLULAR_PREFERRED.
- Set airplane mode according to False.
- Make sure phone connect to WiFi. (If wifi_ssid is not None.)
- Make sure phone don't report iwlan data network type.
- Make sure phone don't report wfc enabled flag to be true.
-
- Args:
- log: Log object.
- ad: Android device object.
- 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.
- """
- toggle_airplane_mode(log, ad, False, strict_checking=False)
try:
- toggle_volte(log, ad, True)
- if not wait_for_network_generation(
- log, ad, GEN_4G, voice_or_data=NETWORK_SERVICE_DATA):
- if not ensure_network_generation(
- log, ad, GEN_4G, voice_or_data=NETWORK_SERVICE_DATA):
- ad.log.error("Fail to ensure data in 4G")
- return False
- except Exception as e:
- ad.log.error(e)
- ad.droid.telephonyToggleDataConnection(True)
- if wifi_ssid is not None:
- if not ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd):
- ad.log.error("Connect to WiFi failed.")
- return False
- if not set_wfc_mode(log, ad, WFC_MODE_CELLULAR_PREFERRED):
- ad.log.error("Set WFC mode failed.")
- return False
- if not wait_for_not_network_rat(
- log, ad, RAT_FAMILY_WLAN, voice_or_data=NETWORK_SERVICE_DATA):
- ad.log.error("Data rat in iwlan mode.")
- return False
- elif not wait_for_wfc_disabled(log, ad, MAX_WAIT_TIME_WFC_ENABLED):
- ad.log.error("Should report wifi calling disabled within %s.",
- MAX_WAIT_TIME_WFC_ENABLED)
- return False
- return True
+ return ad.droid.telecomIsInCall()
+ except:
+ return "mCallState=2" in ad.adb.shell(
+ "dumpsys telephony.registry | grep mCallState")
-def phone_setup_data_for_subscription(log, ad, sub_id, network_generation):
- """Setup Phone <sub_id> Data to <network_generation>
+def is_phone_in_call_active(ad, call_id=None):
+ """Return True if phone in active call.
Args:
- log: log object
- ad: android device object
- sub_id: subscription id
- network_generation: network generation, e.g. GEN_2G, GEN_3G, GEN_4G, GEN_5G
-
- Returns:
- True if success, False if fail.
+ log: log object.
+ ad: android device.
+ call_id: the call id
"""
- toggle_airplane_mode(log, ad, False, strict_checking=False)
- set_wifi_to_default(log, ad)
- if not set_wfc_mode(log, ad, WFC_MODE_DISABLED):
- ad.log.error("Disable WFC failed.")
- return False
- if not ensure_network_generation_for_subscription(
- log,
- ad,
- sub_id,
- network_generation,
- voice_or_data=NETWORK_SERVICE_DATA):
- get_telephony_signal_strength(ad)
- return False
- return True
-
-
-def phone_setup_5g(log, ad):
- """Setup Phone default data sub_id data to 5G.
-
- Args:
- log: log object
- ad: android device object
-
- Returns:
- True if success, False if fail.
- """
- return phone_setup_5g_for_subscription(log, ad,
- get_default_data_sub_id(ad))
-
-
-def phone_setup_5g_for_subscription(log, ad, sub_id):
- """Setup Phone <sub_id> Data to 5G.
-
- Args:
- log: log object
- ad: android device object
- sub_id: subscription id
-
- Returns:
- True if success, False if fail.
- """
- return phone_setup_data_for_subscription(log, ad, sub_id, GEN_5G)
-
-
-def phone_setup_4g(log, ad):
- """Setup Phone default data sub_id data to 4G.
-
- Args:
- log: log object
- ad: android device object
-
- Returns:
- True if success, False if fail.
- """
- return phone_setup_4g_for_subscription(log, ad,
- get_default_data_sub_id(ad))
-
-
-def phone_setup_4g_for_subscription(log, ad, sub_id):
- """Setup Phone <sub_id> Data to 4G.
-
- Args:
- log: log object
- ad: android device object
- sub_id: subscription id
-
- Returns:
- True if success, False if fail.
- """
- return phone_setup_data_for_subscription(log, ad, sub_id, GEN_4G)
-
-
-def phone_setup_3g(log, ad):
- """Setup Phone default data sub_id data to 3G.
-
- Args:
- log: log object
- ad: android device object
-
- Returns:
- True if success, False if fail.
- """
- return phone_setup_3g_for_subscription(log, ad,
- get_default_data_sub_id(ad))
-
-
-def phone_setup_3g_for_subscription(log, ad, sub_id):
- """Setup Phone <sub_id> Data to 3G.
-
- Args:
- log: log object
- ad: android device object
- sub_id: subscription id
-
- Returns:
- True if success, False if fail.
- """
- return phone_setup_data_for_subscription(log, ad, sub_id, GEN_3G)
-
-
-def phone_setup_2g(log, ad):
- """Setup Phone default data sub_id data to 2G.
-
- Args:
- log: log object
- ad: android device object
-
- Returns:
- True if success, False if fail.
- """
- return phone_setup_2g_for_subscription(log, ad,
- get_default_data_sub_id(ad))
-
-
-def phone_setup_2g_for_subscription(log, ad, sub_id):
- """Setup Phone <sub_id> Data to 3G.
-
- Args:
- log: log object
- ad: android device object
- sub_id: subscription id
-
- Returns:
- True if success, False if fail.
- """
- return phone_setup_data_for_subscription(log, ad, sub_id, GEN_2G)
-
-
-def phone_setup_csfb(log, ad, nw_gen=GEN_4G):
- """Setup phone for CSFB call test.
-
- Setup Phone to be in 4G mode.
- Disabled VoLTE.
-
- Args:
- log: log object
- ad: Android device object.
- nw_gen: GEN_4G or GEN_5G
-
- Returns:
- True if setup successfully.
- False for errors.
- """
- return phone_setup_csfb_for_subscription(log, ad,
- get_outgoing_voice_sub_id(ad), nw_gen)
-
-
-def phone_setup_csfb_for_subscription(log, ad, sub_id, nw_gen=GEN_4G):
- """Setup phone for CSFB call test for subscription id.
-
- Setup Phone to be in 4G mode.
- Disabled VoLTE.
-
- Args:
- log: log object
- ad: Android device object.
- sub_id: subscription id.
- nw_gen: GEN_4G or GEN_5G
-
- Returns:
- True if setup successfully.
- False for errors.
- """
- capabilities = ad.telephony["subscription"][sub_id].get("capabilities", [])
- if capabilities:
- if "hide_enhanced_4g_lte" in capabilities:
- show_enhanced_4g_lte_mode = getattr(ad, "show_enhanced_4g_lte_mode", False)
- if show_enhanced_4g_lte_mode in ["false", "False", False]:
- ad.log.warning("'VoLTE' option is hidden. Test will be skipped.")
- raise signals.TestSkip("'VoLTE' option is hidden. Test will be skipped.")
-
- if nw_gen == GEN_4G:
- if not phone_setup_4g_for_subscription(log, ad, sub_id):
- ad.log.error("Failed to set to 4G data.")
- return False
- elif nw_gen == GEN_5G:
- if not phone_setup_5g_for_subscription(log, ad, sub_id):
- ad.log.error("Failed to set to 5G data.")
- return False
-
- toggle_volte_for_subscription(log, ad, sub_id, False)
-
- if not ensure_network_generation_for_subscription(
- log, ad, sub_id, nw_gen, voice_or_data=NETWORK_SERVICE_DATA):
- return False
-
- if not wait_for_voice_attach_for_subscription(log, ad, sub_id,
- MAX_WAIT_TIME_NW_SELECTION):
- return False
-
- return phone_idle_csfb_for_subscription(log, ad, sub_id, nw_gen)
-
-def phone_setup_volte(log, ad, nw_gen=GEN_4G):
- """Setup VoLTE enable.
-
- Args:
- log: log object
- ad: android device object.
- nw_gen: GEN_4G or GEN_5G
-
- 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.")
- return phone_setup_volte_for_subscription(log, ad,
- get_outgoing_voice_sub_id(ad), nw_gen)
-
-def phone_setup_volte_for_subscription(log, ad, sub_id, nw_gen=GEN_4G):
- """Setup VoLTE enable for subscription id.
- Args:
- log: log object
- ad: android device object.
- sub_id: subscription id.
- nw_gen: GEN_4G or GEN_5G
-
- 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 nw_gen == GEN_4G:
- if not phone_setup_4g_for_subscription(log, ad, sub_id):
- ad.log.error("Failed to set to 4G data.")
- return False
- elif nw_gen == GEN_5G:
- if not phone_setup_5g_for_subscription(log, ad, sub_id):
- ad.log.error("Failed to set to 5G data.")
- return False
- operator_name = get_operator_name(log, ad, sub_id)
- if operator_name == CARRIER_TMO:
- return True
+ if ad.droid.telecomIsInCall():
+ if not call_id:
+ call_id = ad.droid.telecomCallGetCallIds()[0]
+ call_state = ad.droid.telecomCallGetCallState(call_id)
+ ad.log.info("%s state is %s", call_id, call_state)
+ return call_state == "ACTIVE"
else:
- 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)
- return phone_idle_volte_for_subscription(log, ad, sub_id, nw_gen)
-
-
-def phone_setup_voice_3g(log, ad):
- """Setup phone voice to 3G.
-
- Args:
- log: log object
- ad: Android device object.
-
- Returns:
- True if setup successfully.
- False for errors.
- """
- return phone_setup_voice_3g_for_subscription(log, ad,
- get_outgoing_voice_sub_id(ad))
-
-
-def phone_setup_voice_3g_for_subscription(log, ad, sub_id):
- """Setup phone voice to 3G for subscription id.
-
- Args:
- log: log object
- ad: Android device object.
- sub_id: subscription id.
-
- Returns:
- True if setup successfully.
- False for errors.
- """
- if not phone_setup_3g_for_subscription(log, ad, sub_id):
- ad.log.error("Failed to set to 3G data.")
+ ad.log.info("Not in telecomIsInCall")
return False
- if not wait_for_voice_attach_for_subscription(log, ad, sub_id,
- MAX_WAIT_TIME_NW_SELECTION):
- return False
- return phone_idle_3g_for_subscription(log, ad, sub_id)
-
-
-def phone_setup_voice_2g(log, ad):
- """Setup phone voice to 2G.
-
- Args:
- log: log object
- ad: Android device object.
-
- Returns:
- True if setup successfully.
- False for errors.
- """
- return phone_setup_voice_2g_for_subscription(log, ad,
- get_outgoing_voice_sub_id(ad))
-
-
-def phone_setup_voice_2g_for_subscription(log, ad, sub_id):
- """Setup phone voice to 2G for subscription id.
-
- Args:
- log: log object
- ad: Android device object.
- sub_id: subscription id.
-
- Returns:
- True if setup successfully.
- False for errors.
- """
- if not phone_setup_2g_for_subscription(log, ad, sub_id):
- ad.log.error("Failed to set to 2G data.")
- return False
- if not wait_for_voice_attach_for_subscription(log, ad, sub_id,
- MAX_WAIT_TIME_NW_SELECTION):
- return False
- return phone_idle_2g_for_subscription(log, ad, sub_id)
-
-
-def phone_setup_voice_general(log, ad):
- """Setup phone for voice general call test.
-
- Make sure phone attached to voice.
- Make necessary delay.
-
- Args:
- ad: Android device object.
-
- Returns:
- True if setup successfully.
- False for errors.
- """
- return phone_setup_voice_general_for_subscription(
- log, ad, get_outgoing_voice_sub_id(ad))
-
-
-def phone_setup_voice_general_for_slot(log,ad,slot_id):
- return phone_setup_voice_general_for_subscription(
- log, ad, get_subid_from_slot_index(log,ad,slot_id))
-
-
-def phone_setup_voice_general_for_subscription(log, ad, sub_id):
- """Setup phone for voice general call test for subscription id.
-
- Make sure phone attached to voice.
- Make necessary delay.
-
- Args:
- ad: Android device object.
- sub_id: subscription id.
-
- Returns:
- True if setup successfully.
- False for errors.
- """
- toggle_airplane_mode(log, ad, False, strict_checking=False)
- if not wait_for_voice_attach_for_subscription(log, ad, sub_id,
- MAX_WAIT_TIME_NW_SELECTION):
- # if phone can not attach voice, try phone_setup_voice_3g
- return phone_setup_voice_3g_for_subscription(log, ad, sub_id)
- return True
-
-
-def phone_setup_data_general(log, ad):
- """Setup phone for data general test.
-
- Make sure phone attached to data.
- Make necessary delay.
-
- Args:
- ad: Android device object.
-
- Returns:
- True if setup successfully.
- False for errors.
- """
- return phone_setup_data_general_for_subscription(
- log, ad, ad.droid.subscriptionGetDefaultDataSubId())
-
-
-def phone_setup_data_general_for_subscription(log, ad, sub_id):
- """Setup phone for data general test for subscription id.
-
- Make sure phone attached to data.
- Make necessary delay.
-
- Args:
- ad: Android device object.
- sub_id: subscription id.
-
- Returns:
- True if setup successfully.
- False for errors.
- """
- toggle_airplane_mode(log, ad, False, strict_checking=False)
- if not wait_for_data_attach_for_subscription(log, ad, sub_id,
- MAX_WAIT_TIME_NW_SELECTION):
- # if phone can not attach data, try reset network preference settings
- reset_preferred_network_type_to_allowable_range(log, ad)
-
- return wait_for_data_attach_for_subscription(log, ad, sub_id,
- MAX_WAIT_TIME_NW_SELECTION)
-
-
-def phone_setup_rat_for_subscription(log, ad, sub_id, network_preference,
- rat_family):
- toggle_airplane_mode(log, ad, False, strict_checking=False)
- set_wifi_to_default(log, ad)
- if not set_wfc_mode(log, ad, WFC_MODE_DISABLED):
- ad.log.error("Disable WFC failed.")
- return False
- return ensure_network_rat_for_subscription(log, ad, sub_id,
- network_preference, rat_family)
-
-
-def phone_setup_lte_gsm_wcdma(log, ad):
- return phone_setup_lte_gsm_wcdma_for_subscription(
- log, ad, ad.droid.subscriptionGetDefaultSubId())
-
-
-def phone_setup_lte_gsm_wcdma_for_subscription(log, ad, sub_id):
- return phone_setup_rat_for_subscription(
- log, ad, sub_id, NETWORK_MODE_LTE_GSM_WCDMA, RAT_FAMILY_LTE)
-
-
-def phone_setup_gsm_umts(log, ad):
- return phone_setup_gsm_umts_for_subscription(
- log, ad, ad.droid.subscriptionGetDefaultSubId())
-
-
-def phone_setup_gsm_umts_for_subscription(log, ad, sub_id):
- return phone_setup_rat_for_subscription(
- log, ad, sub_id, NETWORK_MODE_GSM_UMTS, RAT_FAMILY_WCDMA)
-
-
-def phone_setup_gsm_only(log, ad):
- return phone_setup_gsm_only_for_subscription(
- log, ad, ad.droid.subscriptionGetDefaultSubId())
-
-
-def phone_setup_gsm_only_for_subscription(log, ad, sub_id):
- return phone_setup_rat_for_subscription(
- log, ad, sub_id, NETWORK_MODE_GSM_ONLY, RAT_FAMILY_GSM)
-
-
-def phone_setup_lte_cdma_evdo(log, ad):
- return phone_setup_lte_cdma_evdo_for_subscription(
- log, ad, ad.droid.subscriptionGetDefaultSubId())
-
-
-def phone_setup_lte_cdma_evdo_for_subscription(log, ad, sub_id):
- return phone_setup_rat_for_subscription(
- log, ad, sub_id, NETWORK_MODE_LTE_CDMA_EVDO, RAT_FAMILY_LTE)
-
-
-def phone_setup_cdma(log, ad):
- return phone_setup_cdma_for_subscription(
- log, ad, ad.droid.subscriptionGetDefaultSubId())
-
-
-def phone_setup_cdma_for_subscription(log, ad, sub_id):
- return phone_setup_rat_for_subscription(log, ad, sub_id, NETWORK_MODE_CDMA,
- RAT_FAMILY_CDMA2000)
-
-
-def phone_idle_volte(log, ad):
- """Return if phone is idle for VoLTE call test.
-
- Args:
- ad: Android device object.
- """
- return phone_idle_volte_for_subscription(log, ad,
- get_outgoing_voice_sub_id(ad))
-
-
-def phone_idle_volte_for_subscription(log, ad, sub_id, nw_gen=GEN_4G):
- """Return if phone is idle for VoLTE call test for subscription id.
- Args:
- ad: Android device object.
- sub_id: subscription id.
- nw_gen: GEN_4G or GEN_5G
- """
- if nw_gen == GEN_5G:
- if not is_current_network_5g_nsa_for_subscription(ad, sub_id=sub_id):
- ad.log.error("Not in 5G NSA coverage.")
- return False
- else:
- if not wait_for_network_rat_for_subscription(
- log, ad, sub_id, RAT_FAMILY_LTE,
- 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, sub_id):
- ad.log.error(
- "Failed to <report volte enabled true> within %s seconds.",
- MAX_WAIT_TIME_VOLTE_ENABLED)
- return False
- return True
-
-
-def phone_idle_iwlan(log, ad):
- """Return if phone is idle for WiFi calling call test.
-
- Args:
- ad: Android device object.
- """
- return phone_idle_iwlan_for_subscription(log, ad,
- get_outgoing_voice_sub_id(ad))
-
-
-def phone_idle_iwlan_for_subscription(log, ad, sub_id):
- """Return if phone is idle for WiFi calling call test for subscription id.
-
- Args:
- ad: Android device object.
- sub_id: subscription id.
- """
- if not wait_for_wfc_enabled(log, ad, MAX_WAIT_TIME_WFC_ENABLED):
- ad.log.error("Failed to <report wfc enabled true> within %s seconds.",
- MAX_WAIT_TIME_WFC_ENABLED)
- return False
- return True
-
-
-def phone_idle_not_iwlan(log, ad):
- """Return if phone is idle for non WiFi calling call test.
-
- Args:
- ad: Android device object.
- """
- return phone_idle_not_iwlan_for_subscription(log, ad,
- get_outgoing_voice_sub_id(ad))
-
-
-def phone_idle_not_iwlan_for_subscription(log, ad, sub_id):
- """Return if phone is idle for non WiFi calling call test for sub id.
-
- Args:
- ad: Android device object.
- sub_id: subscription id.
- """
- if not wait_for_not_network_rat_for_subscription(
- log, ad, sub_id, RAT_FAMILY_WLAN,
- voice_or_data=NETWORK_SERVICE_DATA):
- log.error("{} data rat in iwlan mode.".format(ad.serial))
- return False
- return True
-
-
-def phone_idle_csfb(log, ad):
- """Return if phone is idle for CSFB call test.
-
- Args:
- ad: Android device object.
- """
- return phone_idle_csfb_for_subscription(log, ad,
- get_outgoing_voice_sub_id(ad))
-
-
-def phone_idle_csfb_for_subscription(log, ad, sub_id, nw_gen=GEN_4G):
- """Return if phone is idle for CSFB call test for subscription id.
-
- Args:
- ad: Android device object.
- sub_id: subscription id.
- nw_gen: GEN_4G or GEN_5G
- """
- if nw_gen == GEN_5G:
- if not is_current_network_5g_nsa_for_subscription(ad, sub_id=sub_id):
- ad.log.error("Not in 5G NSA coverage.")
- return False
- else:
- if not wait_for_network_rat_for_subscription(
- log, ad, sub_id, RAT_FAMILY_LTE,
- voice_or_data=NETWORK_SERVICE_DATA):
- ad.log.error("Data rat not in lte mode.")
- return False
- return True
-
-
-def phone_idle_3g(log, ad):
- """Return if phone is idle for 3G call test.
-
- Args:
- ad: Android device object.
- """
- return phone_idle_3g_for_subscription(log, ad,
- get_outgoing_voice_sub_id(ad))
-
-
-def phone_idle_3g_for_subscription(log, ad, sub_id):
- """Return if phone is idle for 3G call test for subscription id.
-
- Args:
- ad: Android device object.
- sub_id: subscription id.
- """
- return wait_for_network_generation_for_subscription(
- log, ad, sub_id, GEN_3G, voice_or_data=NETWORK_SERVICE_VOICE)
-
-
-def phone_idle_2g(log, ad):
- """Return if phone is idle for 2G call test.
-
- Args:
- ad: Android device object.
- """
- return phone_idle_2g_for_subscription(log, ad,
- get_outgoing_voice_sub_id(ad))
-
-
-def phone_idle_2g_for_subscription(log, ad, sub_id):
- """Return if phone is idle for 2G call test for subscription id.
-
- Args:
- ad: Android device object.
- sub_id: subscription id.
- """
- return wait_for_network_generation_for_subscription(
- log, ad, sub_id, GEN_2G, voice_or_data=NETWORK_SERVICE_VOICE)
-
-
-def get_current_voice_rat(log, ad):
- """Return current Voice RAT
-
- Args:
- ad: Android device object.
- """
- return get_current_voice_rat_for_subscription(
- log, ad, get_outgoing_voice_sub_id(ad))
-
-
-def get_current_voice_rat_for_subscription(log, ad, sub_id):
- """Return current Voice RAT for subscription id.
-
- Args:
- ad: Android device object.
- sub_id: subscription id.
- """
- return get_network_rat_for_subscription(log, ad, sub_id,
- NETWORK_SERVICE_VOICE)
def is_phone_in_call_volte(log, ad):
@@ -1967,85 +1728,6 @@
return call
return None
-def phone_setup_on_rat(
- log,
- ad,
- rat='volte',
- sub_id=None,
- is_airplane_mode=False,
- wfc_mode=None,
- wifi_ssid=None,
- wifi_pwd=None,
- only_return_fn=None,
- sub_id_type='voice'):
-
- if sub_id is None:
- if sub_id_type == 'sms':
- sub_id = get_outgoing_message_sub_id(ad)
- else:
- sub_id = get_outgoing_voice_sub_id(ad)
-
- if rat.lower() == '5g_volte':
- if only_return_fn:
- return phone_setup_volte_for_subscription
- else:
- return phone_setup_volte_for_subscription(log, ad, sub_id, GEN_5G)
-
- elif rat.lower() == '5g_csfb':
- if only_return_fn:
- return phone_setup_csfb_for_subscription
- else:
- return phone_setup_csfb_for_subscription(log, ad, sub_id, GEN_5G)
-
- elif rat.lower() == '5g_wfc':
- if only_return_fn:
- return phone_setup_iwlan_for_subscription
- else:
- return phone_setup_iwlan_for_subscription(
- log,
- ad,
- sub_id,
- is_airplane_mode,
- wfc_mode,
- wifi_ssid,
- wifi_pwd,
- GEN_5G)
-
- elif rat.lower() == 'volte':
- if only_return_fn:
- return phone_setup_volte_for_subscription
- else:
- return phone_setup_volte_for_subscription(log, ad, sub_id)
-
- elif rat.lower() == 'csfb':
- if only_return_fn:
- return phone_setup_csfb_for_subscription
- else:
- return phone_setup_csfb_for_subscription(log, ad, sub_id)
-
- elif rat.lower() == '3g':
- if only_return_fn:
- return phone_setup_voice_3g_for_subscription
- else:
- return phone_setup_voice_3g_for_subscription(log, ad, sub_id)
-
- elif rat.lower() == 'wfc':
- if only_return_fn:
- return phone_setup_iwlan_for_subscription
- else:
- return phone_setup_iwlan_for_subscription(
- log,
- ad,
- sub_id,
- is_airplane_mode,
- wfc_mode,
- wifi_ssid,
- wifi_pwd)
- else:
- if only_return_fn:
- return phone_setup_voice_general_for_subscription
- else:
- return phone_setup_voice_general_for_subscription(log, ad, sub_id)
def is_phone_in_call_on_rat(log, ad, rat='volte', only_return_fn=None):
if rat.lower() == 'volte' or rat.lower() == '5g_volte':
@@ -2066,7 +1748,13 @@
else:
return is_phone_in_call_3g(log, ad)
- elif rat.lower() == 'wfc':
+ elif rat.lower() == '2g':
+ if only_return_fn:
+ return is_phone_in_call_2g
+ else:
+ return is_phone_in_call_2g(log, ad)
+
+ elif rat.lower() == 'wfc' or rat.lower() == '5g_wfc':
if only_return_fn:
return is_phone_in_call_iwlan
else:
@@ -2207,4 +1895,790 @@
ads[1],
ads[0],
verify_caller_func=dut_incall_check_func,
- wait_time_in_call=total_duration)
\ No newline at end of file
+ wait_time_in_call=total_duration)
+
+
+def _wait_for_ringing_event(log, ad, wait_time):
+ """Wait for ringing event.
+
+ Args:
+ log: log object.
+ ad: android device object.
+ wait_time: max time to wait for ringing event.
+
+ Returns:
+ event_ringing if received ringing event.
+ otherwise return None.
+ """
+ event_ringing = None
+
+ try:
+ event_ringing = ad.ed.wait_for_event(
+ EventCallStateChanged,
+ is_event_match,
+ timeout=wait_time,
+ field=CallStateContainer.CALL_STATE,
+ value=TELEPHONY_STATE_RINGING)
+ ad.log.info("Receive ringing event")
+ except Empty:
+ ad.log.info("No Ringing Event")
+ finally:
+ return event_ringing
+
+
+def wait_for_telecom_ringing(log, ad, max_time=MAX_WAIT_TIME_TELECOM_RINGING):
+ """Wait for android to be in telecom ringing state.
+
+ Args:
+ log: log object.
+ ad: android device.
+ max_time: maximal wait time. This is optional.
+ Default Value is MAX_WAIT_TIME_TELECOM_RINGING.
+
+ Returns:
+ If phone become in telecom ringing state within max_time, return True.
+ Return False if timeout.
+ """
+ return _wait_for_droid_in_state(
+ log, ad, max_time, lambda log, ad: ad.droid.telecomIsRinging())
+
+
+def wait_for_ringing_call(log, ad, incoming_number=None):
+ """Wait for an incoming call on default voice subscription and
+ accepts the call.
+
+ Args:
+ log: log object.
+ ad: android device object.
+ incoming_number: Expected incoming number.
+ Optional. Default is None
+
+ Returns:
+ True: if incoming call is received and answered successfully.
+ False: for errors
+ """
+ return wait_for_ringing_call_for_subscription(
+ log, ad, get_incoming_voice_sub_id(ad), incoming_number)
+
+
+def wait_for_ringing_call_for_subscription(
+ log,
+ ad,
+ sub_id,
+ incoming_number=None,
+ caller=None,
+ event_tracking_started=False,
+ timeout=MAX_WAIT_TIME_CALLEE_RINGING,
+ interval=WAIT_TIME_BETWEEN_STATE_CHECK):
+ """Wait for an incoming call on specified subscription.
+
+ Args:
+ log: log object.
+ ad: android device object.
+ sub_id: subscription ID
+ incoming_number: Expected incoming number. Default is None
+ event_tracking_started: True if event tracking already state outside
+ timeout: time to wait for ring
+ interval: checking interval
+
+ Returns:
+ True: if incoming call is received and answered successfully.
+ False: for errors
+ """
+ if not event_tracking_started:
+ ad.ed.clear_events(EventCallStateChanged)
+ ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
+ ring_event_received = False
+ end_time = time.time() + timeout
+ try:
+ while time.time() < end_time:
+ if not ring_event_received:
+ event_ringing = _wait_for_ringing_event(log, ad, interval)
+ if event_ringing:
+ if incoming_number and not check_phone_number_match(
+ event_ringing['data']
+ [CallStateContainer.INCOMING_NUMBER], incoming_number):
+ ad.log.error(
+ "Incoming Number not match. Expected number:%s, actual number:%s",
+ incoming_number, event_ringing['data'][
+ CallStateContainer.INCOMING_NUMBER])
+ return False
+ ring_event_received = True
+ telephony_state = ad.droid.telephonyGetCallStateForSubscription(
+ sub_id)
+ telecom_state = ad.droid.telecomGetCallState()
+ if telephony_state == TELEPHONY_STATE_RINGING and (
+ telecom_state == TELEPHONY_STATE_RINGING):
+ ad.log.info("callee is in telephony and telecom RINGING state")
+ if caller:
+ if caller.droid.telecomIsInCall():
+ caller.log.info("Caller telecom is in call state")
+ return True
+ else:
+ caller.log.info("Caller telecom is NOT in call state")
+ else:
+ return True
+ else:
+ ad.log.info(
+ "telephony in %s, telecom in %s, expecting RINGING state",
+ telephony_state, telecom_state)
+ time.sleep(interval)
+ finally:
+ if not event_tracking_started:
+ ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
+ sub_id)
+
+
+def wait_for_call_offhook_for_subscription(
+ log,
+ ad,
+ sub_id,
+ event_tracking_started=False,
+ timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT,
+ interval=WAIT_TIME_BETWEEN_STATE_CHECK):
+ """Wait for an incoming call on specified subscription.
+
+ Args:
+ log: log object.
+ ad: android device object.
+ sub_id: subscription ID
+ timeout: time to wait for ring
+ interval: checking interval
+
+ Returns:
+ True: if incoming call is received and answered successfully.
+ False: for errors
+ """
+ if not event_tracking_started:
+ ad.ed.clear_events(EventCallStateChanged)
+ ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
+ offhook_event_received = False
+ end_time = time.time() + timeout
+ try:
+ while time.time() < end_time:
+ if not offhook_event_received:
+ if wait_for_call_offhook_event(log, ad, sub_id, True,
+ interval):
+ offhook_event_received = True
+ telephony_state = ad.droid.telephonyGetCallStateForSubscription(
+ sub_id)
+ telecom_state = ad.droid.telecomGetCallState()
+ if telephony_state == TELEPHONY_STATE_OFFHOOK and (
+ telecom_state == TELEPHONY_STATE_OFFHOOK):
+ ad.log.info("telephony and telecom are in OFFHOOK state")
+ return True
+ else:
+ ad.log.info(
+ "telephony in %s, telecom in %s, expecting OFFHOOK state",
+ telephony_state, telecom_state)
+ if offhook_event_received:
+ time.sleep(interval)
+ finally:
+ if not event_tracking_started:
+ ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
+ sub_id)
+
+
+def wait_for_call_offhook_event(
+ log,
+ ad,
+ sub_id,
+ event_tracking_started=False,
+ timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT):
+ """Wait for an incoming call on specified subscription.
+
+ Args:
+ log: log object.
+ ad: android device object.
+ event_tracking_started: True if event tracking already state outside
+ timeout: time to wait for event
+
+ Returns:
+ True: if call offhook event is received.
+ False: if call offhook event is not received.
+ """
+ if not event_tracking_started:
+ ad.ed.clear_events(EventCallStateChanged)
+ ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
+ try:
+ ad.ed.wait_for_event(
+ EventCallStateChanged,
+ is_event_match,
+ timeout=timeout,
+ field=CallStateContainer.CALL_STATE,
+ value=TELEPHONY_STATE_OFFHOOK)
+ ad.log.info("Got event %s", TELEPHONY_STATE_OFFHOOK)
+ except Empty:
+ ad.log.info("No event for call state change to OFFHOOK")
+ return False
+ finally:
+ if not event_tracking_started:
+ ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
+ sub_id)
+ return True
+
+
+def wait_and_answer_call_for_subscription(
+ log,
+ ad,
+ sub_id,
+ incoming_number=None,
+ incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
+ timeout=MAX_WAIT_TIME_CALLEE_RINGING,
+ caller=None,
+ video_state=None):
+ """Wait for an incoming call on specified subscription and
+ accepts the call.
+
+ Args:
+ log: log object.
+ ad: android device object.
+ sub_id: subscription ID
+ incoming_number: Expected incoming number.
+ Optional. Default is None
+ incall_ui_display: after answer the call, bring in-call UI to foreground or
+ background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
+ if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
+ if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
+ else, do nothing.
+
+ Returns:
+ True: if incoming call is received and answered successfully.
+ False: for errors
+ """
+ ad.ed.clear_events(EventCallStateChanged)
+ ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
+ try:
+ if not wait_for_ringing_call_for_subscription(
+ log,
+ ad,
+ sub_id,
+ incoming_number=incoming_number,
+ caller=caller,
+ event_tracking_started=True,
+ timeout=timeout):
+ ad.log.info("Incoming call ringing check failed.")
+ return False
+ ad.log.info("Accept the ring call")
+ ad.droid.telecomAcceptRingingCall(video_state)
+
+ if wait_for_call_offhook_for_subscription(
+ log, ad, sub_id, event_tracking_started=True):
+ return True
+ else:
+ ad.log.error("Could not answer the call.")
+ return False
+ except Exception as e:
+ log.error(e)
+ return False
+ finally:
+ ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
+ if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
+ ad.droid.telecomShowInCallScreen()
+ elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
+ ad.droid.showHomeScreen()
+
+
+def wait_and_reject_call(log,
+ ad,
+ incoming_number=None,
+ delay_reject=WAIT_TIME_REJECT_CALL,
+ reject=True):
+ """Wait for an incoming call on default voice subscription and
+ reject the call.
+
+ Args:
+ log: log object.
+ ad: android device object.
+ incoming_number: Expected incoming number.
+ Optional. Default is None
+ delay_reject: time to wait before rejecting the call
+ Optional. Default is WAIT_TIME_REJECT_CALL
+
+ Returns:
+ True: if incoming call is received and reject successfully.
+ False: for errors
+ """
+ return wait_and_reject_call_for_subscription(log, ad,
+ get_incoming_voice_sub_id(ad),
+ incoming_number, delay_reject,
+ reject)
+
+
+def wait_and_reject_call_for_subscription(log,
+ ad,
+ sub_id,
+ incoming_number=None,
+ delay_reject=WAIT_TIME_REJECT_CALL,
+ reject=True):
+ """Wait for an incoming call on specific subscription and
+ reject the call.
+
+ Args:
+ log: log object.
+ ad: android device object.
+ sub_id: subscription ID
+ incoming_number: Expected incoming number.
+ Optional. Default is None
+ delay_reject: time to wait before rejecting the call
+ Optional. Default is WAIT_TIME_REJECT_CALL
+
+ Returns:
+ True: if incoming call is received and reject successfully.
+ False: for errors
+ """
+
+ if not wait_for_ringing_call_for_subscription(log, ad, sub_id,
+ incoming_number):
+ ad.log.error(
+ "Could not reject a call: incoming call in ringing check failed.")
+ return False
+
+ ad.ed.clear_events(EventCallStateChanged)
+ ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
+ if reject is True:
+ # Delay between ringing and reject.
+ time.sleep(delay_reject)
+ is_find = False
+ # Loop the call list and find the matched one to disconnect.
+ for call in ad.droid.telecomCallGetCallIds():
+ if check_phone_number_match(
+ get_number_from_tel_uri(get_call_uri(ad, call)),
+ incoming_number):
+ ad.droid.telecomCallDisconnect(call)
+ ad.log.info("Callee reject the call")
+ is_find = True
+ if is_find is False:
+ ad.log.error("Callee did not find matching call to reject.")
+ return False
+ else:
+ # don't reject on callee. Just ignore the incoming call.
+ ad.log.info("Callee received incoming call. Ignore it.")
+ try:
+ ad.ed.wait_for_event(
+ EventCallStateChanged,
+ is_event_match_for_list,
+ timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT,
+ field=CallStateContainer.CALL_STATE,
+ value_list=[TELEPHONY_STATE_IDLE, TELEPHONY_STATE_OFFHOOK])
+ except Empty:
+ ad.log.error("No onCallStateChangedIdle event received.")
+ return False
+ finally:
+ ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
+ return True
+
+
+def wait_and_answer_call(log,
+ ad,
+ incoming_number=None,
+ incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
+ caller=None,
+ video_state=None):
+ """Wait for an incoming call on default voice subscription and
+ accepts the call.
+
+ Args:
+ ad: android device object.
+ incoming_number: Expected incoming number.
+ Optional. Default is None
+ incall_ui_display: after answer the call, bring in-call UI to foreground or
+ background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
+ if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
+ if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
+ else, do nothing.
+
+ Returns:
+ True: if incoming call is received and answered successfully.
+ False: for errors
+ """
+ return wait_and_answer_call_for_subscription(
+ log,
+ ad,
+ get_incoming_voice_sub_id(ad),
+ incoming_number,
+ incall_ui_display=incall_ui_display,
+ caller=caller,
+ video_state=video_state)
+
+
+def wait_for_in_call_active(ad,
+ timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT,
+ interval=WAIT_TIME_BETWEEN_STATE_CHECK,
+ call_id=None):
+ """Wait for call reach active state.
+
+ Args:
+ log: log object.
+ ad: android device.
+ call_id: the call id
+ """
+ if not call_id:
+ call_id = ad.droid.telecomCallGetCallIds()[0]
+ args = [ad, call_id]
+ if not wait_for_state(is_phone_in_call_active, True, timeout, interval,
+ *args):
+ ad.log.error("Call did not reach ACTIVE state")
+ return False
+ else:
+ return True
+
+
+def wait_for_droid_in_call(log, ad, max_time):
+ """Wait for android to be in call state.
+
+ Args:
+ log: log object.
+ ad: android device.
+ max_time: maximal wait time.
+
+ Returns:
+ If phone become in call state within max_time, return True.
+ Return False if timeout.
+ """
+ return _wait_for_droid_in_state(log, ad, max_time, is_phone_in_call)
+
+
+def wait_for_call_id_clearing(ad,
+ previous_ids,
+ timeout=MAX_WAIT_TIME_CALL_DROP):
+ while timeout > 0:
+ new_call_ids = ad.droid.telecomCallGetCallIds()
+ if len(new_call_ids) <= len(previous_ids):
+ return True
+ time.sleep(5)
+ timeout = timeout - 5
+ ad.log.error("Call id clearing failed. Before: %s; After: %s",
+ previous_ids, new_call_ids)
+ return False
+
+
+def wait_for_call_end(
+ log,
+ ad_caller,
+ ad_callee,
+ ad_hangup,
+ verify_caller_func,
+ verify_callee_func,
+ call_begin_time,
+ check_interval=5,
+ tel_result_wrapper=TelResultWrapper(CallResult('SUCCESS')),
+ wait_time_in_call=WAIT_TIME_IN_CALL):
+ elapsed_time = 0
+ while (elapsed_time < wait_time_in_call):
+ check_interval = min(check_interval, wait_time_in_call - elapsed_time)
+ time.sleep(check_interval)
+ elapsed_time += check_interval
+ time_message = "at <%s>/<%s> second." % (elapsed_time, wait_time_in_call)
+ for ad, call_func in [(ad_caller, verify_caller_func),
+ (ad_callee, verify_callee_func)]:
+ if not call_func(log, ad):
+ ad.log.error(
+ "NOT in correct %s state at %s, voice in RAT %s",
+ call_func.__name__,
+ time_message,
+ ad.droid.telephonyGetCurrentVoiceNetworkType())
+ tel_result_wrapper.result_value = CallResult(
+ 'CALL_DROP_OR_WRONG_STATE_AFTER_CONNECTED')
+ else:
+ ad.log.info("In correct %s state at %s",
+ call_func.__name__, time_message)
+ if not ad.droid.telecomCallGetAudioState():
+ ad.log.error("Audio is not in call state at %s", time_message)
+ tel_result_wrapper.result_value = CallResult(
+ 'AUDIO_STATE_NOT_INCALL_AFTER_CONNECTED')
+
+ if not tel_result_wrapper:
+ break
+
+ if not tel_result_wrapper:
+ for ad in (ad_caller, ad_callee):
+ last_call_drop_reason(ad, call_begin_time)
+ try:
+ if ad.droid.telecomIsInCall():
+ ad.log.info("In call. End now.")
+ ad.droid.telecomEndCall()
+ except Exception as e:
+ log.error(str(e))
+ else:
+ if ad_hangup:
+ if not hangup_call(log, ad_hangup):
+ ad_hangup.log.info("Failed to hang up the call")
+ tel_result_wrapper.result_value = CallResult('CALL_HANGUP_FAIL')
+
+ if ad_hangup or not tel_result_wrapper:
+ for ad in (ad_caller, ad_callee):
+ if not wait_for_call_id_clearing(ad, getattr(ad, "caller_ids", [])):
+ tel_result_wrapper.result_value = CallResult(
+ 'CALL_ID_CLEANUP_FAIL')
+
+ return tel_result_wrapper
+
+
+def check_call(log, dut, dut_client):
+ result = True
+ if not call_setup_teardown(log, dut_client, dut,
+ dut):
+ if not call_setup_teardown(log, dut_client,
+ dut, dut):
+ dut.log.error("MT call failed")
+ result = False
+ if not call_setup_teardown(log, dut, dut_client,
+ dut):
+ dut.log.error("MO call failed")
+ result = False
+ return result
+
+
+def check_call_in_wfc(log, dut, dut_client):
+ result = True
+ if not call_setup_teardown(log, dut_client, dut,
+ dut, None, is_phone_in_call_iwlan):
+ if not call_setup_teardown(log, dut_client,
+ dut, dut, None,
+ is_phone_in_call_iwlan):
+ dut.log.error("MT WFC call failed")
+ result = False
+ if not call_setup_teardown(log, dut, dut_client,
+ dut, is_phone_in_call_iwlan):
+ dut.log.error("MO WFC call failed")
+ result = False
+ return result
+
+
+def check_call_in_volte(log, dut, dut_client):
+ result = True
+ if not call_setup_teardown(log, dut_client, dut,
+ dut, None, is_phone_in_call_volte):
+ if not call_setup_teardown(log, dut_client,
+ dut, dut, None,
+ is_phone_in_call_volte):
+ dut.log.error("MT VoLTE call failed")
+ result = False
+ if not call_setup_teardown(log, dut, dut_client,
+ dut, is_phone_in_call_volte):
+ dut.log.error("MO VoLTE call failed")
+ result = False
+ return result
+
+
+def change_ims_setting(log,
+ ad,
+ dut_client,
+ wifi_network_ssid,
+ wifi_network_pass,
+ subid,
+ dut_capabilities,
+ airplane_mode,
+ wifi_enabled,
+ volte_enabled,
+ wfc_enabled,
+ nw_gen=RAT_LTE,
+ wfc_mode=None):
+ result = True
+ ad.log.info(
+ "Setting APM %s, WIFI %s, VoLTE %s, WFC %s, WFC mode %s",
+ airplane_mode, wifi_enabled, volte_enabled, wfc_enabled, wfc_mode)
+
+ toggle_airplane_mode_by_adb(log, ad, airplane_mode)
+ if wifi_enabled:
+ if not ensure_wifi_connected(log, ad,
+ wifi_network_ssid,
+ wifi_network_pass,
+ apm=airplane_mode):
+ ad.log.error("Fail to connected to WiFi")
+ result = False
+ else:
+ if not wifi_toggle_state(log, ad, False):
+ ad.log.error("Failed to turn off WiFi.")
+ result = False
+ toggle_volte(log, ad, volte_enabled)
+ toggle_wfc(log, ad, wfc_enabled)
+ if wfc_mode:
+ set_wfc_mode(log, ad, wfc_mode)
+ wfc_mode = ad.droid.imsGetWfcMode()
+ if wifi_enabled or not airplane_mode:
+ if not ensure_phone_subscription(log, ad):
+ ad.log.error("Failed to find valid subscription")
+ result = False
+ if airplane_mode:
+ if (CAPABILITY_WFC in dut_capabilities) and (wifi_enabled
+ and wfc_enabled):
+ if not wait_for_wfc_enabled(log, ad):
+ result = False
+ elif not check_call_in_wfc(log, ad, dut_client):
+ result = False
+ else:
+ if not wait_for_state(
+ ad.droid.telephonyGetCurrentVoiceNetworkType,
+ RAT_UNKNOWN):
+ ad.log.error(
+ "Voice RAT is %s not UNKNOWN",
+ ad.droid.telephonyGetCurrentVoiceNetworkType())
+ result = False
+ else:
+ ad.log.info("Voice RAT is in UNKKNOWN")
+ else:
+ if (wifi_enabled and wfc_enabled) and (
+ wfc_mode == WFC_MODE_WIFI_PREFERRED) and (
+ CAPABILITY_WFC in dut_capabilities):
+ if not wait_for_wfc_enabled(log, ad):
+ result = False
+ if not wait_for_state(
+ ad.droid.telephonyGetCurrentVoiceNetworkType,
+ RAT_UNKNOWN):
+ ad.log.error(
+ "Voice RAT is %s, not UNKNOWN",
+ ad.droid.telephonyGetCurrentVoiceNetworkType())
+ if not check_call_in_wfc(log, ad, dut_client):
+ result = False
+ else:
+ if not wait_for_wfc_disabled(log, ad):
+ ad.log.error("WFC is not disabled")
+ result = False
+ if volte_enabled and CAPABILITY_VOLTE in dut_capabilities:
+ if not wait_for_volte_enabled(log, ad):
+ result = False
+ if not check_call_in_volte(log, ad, dut_client):
+ result = False
+ else:
+ if not wait_for_not_network_rat(
+ log,
+ ad,
+ nw_gen,
+ voice_or_data=NETWORK_SERVICE_VOICE):
+ ad.log.error(
+ "Voice RAT is %s",
+ ad.droid.telephonyGetCurrentVoiceNetworkType(
+ ))
+ result = False
+ if not wait_for_voice_attach(log, ad):
+ result = False
+ if not check_call(log, ad, dut_client):
+ result = False
+ user_config_profile = get_user_config_profile(ad)
+ ad.log.info("user_config_profile: %s ",
+ sorted(user_config_profile.items()))
+ return result
+
+
+def verify_default_ims_setting(log,
+ ad,
+ dut_client,
+ carrier_configs,
+ default_wfc_enabled,
+ default_volte,
+ wfc_mode=None):
+ result = True
+ airplane_mode = ad.droid.connectivityCheckAirplaneMode()
+ default_wfc_mode = carrier_configs.get(
+ CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT, wfc_mode)
+ if default_wfc_enabled:
+ wait_for_wfc_enabled(log, ad)
+ else:
+ wait_for_wfc_disabled(log, ad)
+ if airplane_mode:
+ wait_for_network_rat(
+ log,
+ ad,
+ RAT_UNKNOWN,
+ voice_or_data=NETWORK_SERVICE_VOICE)
+ else:
+ if default_volte:
+ wait_for_volte_enabled(log, ad)
+ else:
+ wait_for_not_network_rat(
+ log,
+ ad,
+ RAT_UNKNOWN,
+ voice_or_data=NETWORK_SERVICE_VOICE)
+
+ if not ensure_phone_subscription(log, ad):
+ ad.log.error("Failed to find valid subscription")
+ result = False
+ user_config_profile = get_user_config_profile(ad)
+ ad.log.info("user_config_profile = %s ",
+ sorted(user_config_profile.items()))
+ if user_config_profile["VoLTE Enabled"] != default_volte:
+ ad.log.error("VoLTE mode is not %s", default_volte)
+ result = False
+ else:
+ ad.log.info("VoLTE mode is %s as expected",
+ default_volte)
+ if user_config_profile["WFC Enabled"] != default_wfc_enabled:
+ ad.log.error("WFC enabled is not %s", default_wfc_enabled)
+ if user_config_profile["WFC Enabled"]:
+ if user_config_profile["WFC Mode"] != default_wfc_mode:
+ ad.log.error(
+ "WFC mode is not %s after IMS factory reset",
+ default_wfc_mode)
+ result = False
+ else:
+ ad.log.info("WFC mode is %s as expected",
+ default_wfc_mode)
+ if default_wfc_enabled and \
+ default_wfc_mode == WFC_MODE_WIFI_PREFERRED:
+ if not check_call_in_wfc(log, ad, dut_client):
+ result = False
+ elif not airplane_mode:
+ if default_volte:
+ if not check_call_in_volte(log, ad, dut_client):
+ result = False
+ else:
+ if not check_call(log, ad, dut_client):
+ result = False
+ if result == False:
+ user_config_profile = get_user_config_profile(ad)
+ ad.log.info("user_config_profile = %s ",
+ sorted(user_config_profile.items()))
+ return result
+
+
+def truncate_phone_number(
+ log,
+ caller_number,
+ callee_number,
+ dialing_number_length,
+ skip_inter_area_call=True):
+ """This function truncates the phone number of the caller/callee to test
+ 7/10/11/12 digit dialing for North American numbering plan, and distinguish
+ if this is an inter-area call by comparing the area code.
+
+ Args:
+ log: logger object
+ caller_number: phone number of the caller
+ callee_number: phone number of the callee
+ dialing_number_length: the length of phone number (usually 7/10/11/12)
+ skip_inter_area_call: True to raise a TestSkip exception to skip dialing
+ the inter-area call. Otherwise False.
+
+ Returns:
+ The truncated phone number of the callee
+ """
+
+ if not dialing_number_length:
+ return callee_number
+
+ trunc_position = 0 - int(dialing_number_length)
+ try:
+ caller_area_code = caller_number[:trunc_position]
+ callee_area_code = callee_number[:trunc_position]
+ callee_dial_number = callee_number[trunc_position:]
+
+ if caller_area_code != callee_area_code:
+ skip_inter_area_call = True
+
+ except:
+ skip_inter_area_call = True
+
+ if skip_inter_area_call:
+ msg = "Cannot make call from %s to %s by %s digits since inter-area "
+ "call is not allowed" % (
+ caller_number, callee_number, dialing_number_length)
+ log.info(msg)
+ raise signals.TestSkip(msg)
+ else:
+ callee_number = callee_dial_number
+
+ return callee_number
+
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_wifi_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_wifi_utils.py
new file mode 100644
index 0000000..997b77b
--- /dev/null
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_wifi_utils.py
@@ -0,0 +1,243 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - Google
+#
+# 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_contrib.test_utils.tel.tel_defines import TYPE_WIFI
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
+from acts_contrib.test_utils.wifi import wifi_test_utils
+
+WIFI_SSID_KEY = wifi_test_utils.WifiEnums.SSID_KEY
+WIFI_PWD_KEY = wifi_test_utils.WifiEnums.PWD_KEY
+WIFI_CONFIG_APBAND_2G = 1
+WIFI_CONFIG_APBAND_5G = 2
+WIFI_CONFIG_APBAND_AUTO = wifi_test_utils.WifiEnums.WIFI_CONFIG_APBAND_AUTO
+
+
+def get_wifi_signal_strength(ad):
+ signal_strength = ad.droid.wifiGetConnectionInfo()['rssi']
+ ad.log.info("WiFi Signal Strength is %s" % signal_strength)
+ return signal_strength
+
+
+def get_wifi_usage(ad, sid=None, apk=None):
+ if not sid:
+ sid = ad.droid.subscriptionGetDefaultDataSubId()
+ current_time = int(time.time() * 1000)
+ begin_time = current_time - 10 * 24 * 60 * 60 * 1000
+ end_time = current_time + 10 * 24 * 60 * 60 * 1000
+
+ if apk:
+ uid = ad.get_apk_uid(apk)
+ ad.log.debug("apk %s uid = %s", apk, uid)
+ try:
+ return ad.droid.connectivityQueryDetailsForUid(
+ TYPE_WIFI,
+ ad.droid.telephonyGetSubscriberIdForSubscription(sid),
+ begin_time, end_time, uid)
+ except:
+ return ad.droid.connectivityQueryDetailsForUid(
+ ad.droid.telephonyGetSubscriberIdForSubscription(sid),
+ begin_time, end_time, uid)
+ else:
+ try:
+ return ad.droid.connectivityQuerySummaryForDevice(
+ TYPE_WIFI,
+ ad.droid.telephonyGetSubscriberIdForSubscription(sid),
+ begin_time, end_time)
+ except:
+ return ad.droid.connectivityQuerySummaryForDevice(
+ ad.droid.telephonyGetSubscriberIdForSubscription(sid),
+ begin_time, end_time)
+
+
+def check_is_wifi_connected(log, ad, wifi_ssid):
+ """Check if ad is connected to wifi wifi_ssid.
+
+ Args:
+ log: Log object.
+ ad: Android device object.
+ wifi_ssid: WiFi network SSID.
+
+ Returns:
+ True if wifi is connected to wifi_ssid
+ False if wifi is not connected to wifi_ssid
+ """
+ wifi_info = ad.droid.wifiGetConnectionInfo()
+ if wifi_info["supplicant_state"] == "completed" and wifi_info["SSID"] == wifi_ssid:
+ ad.log.info("Wifi is connected to %s", wifi_ssid)
+ ad.on_mobile_data = False
+ return True
+ else:
+ ad.log.info("Wifi is not connected to %s", wifi_ssid)
+ ad.log.debug("Wifi connection_info=%s", wifi_info)
+ ad.on_mobile_data = True
+ return False
+
+
+def ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd=None, retries=3, apm=False):
+ """Ensure ad connected to wifi on network wifi_ssid.
+
+ Args:
+ log: Log object.
+ ad: Android device object.
+ wifi_ssid: WiFi network SSID.
+ wifi_pwd: optional secure network password.
+ retries: the number of retries.
+
+ Returns:
+ True if wifi is connected to wifi_ssid
+ False if wifi is not connected to wifi_ssid
+ """
+ if not toggle_airplane_mode(log, ad, apm, strict_checking=False):
+ return False
+
+ network = {WIFI_SSID_KEY: wifi_ssid}
+ if wifi_pwd:
+ network[WIFI_PWD_KEY] = wifi_pwd
+ for i in range(retries):
+ if not ad.droid.wifiCheckState():
+ ad.log.info("Wifi state is down. Turn on Wifi")
+ ad.droid.wifiToggleState(True)
+ if check_is_wifi_connected(log, ad, wifi_ssid):
+ ad.log.info("Wifi is connected to %s", wifi_ssid)
+ return verify_internet_connection(log, ad, retries=3)
+ else:
+ ad.log.info("Connecting to wifi %s", wifi_ssid)
+ try:
+ ad.droid.wifiConnectByConfig(network)
+ except Exception:
+ ad.log.info("Connecting to wifi by wifiConnect instead")
+ ad.droid.wifiConnect(network)
+ time.sleep(20)
+ if check_is_wifi_connected(log, ad, wifi_ssid):
+ ad.log.info("Connected to Wifi %s", wifi_ssid)
+ return verify_internet_connection(log, ad, retries=3)
+ ad.log.info("Fail to connected to wifi %s", wifi_ssid)
+ return False
+
+
+def forget_all_wifi_networks(log, ad):
+ """Forget all stored wifi network information
+
+ Args:
+ log: log object
+ ad: AndroidDevice object
+
+ Returns:
+ boolean success (True) or failure (False)
+ """
+ if not ad.droid.wifiGetConfiguredNetworks():
+ ad.on_mobile_data = True
+ return True
+ try:
+ old_state = ad.droid.wifiCheckState()
+ wifi_test_utils.reset_wifi(ad)
+ wifi_toggle_state(log, ad, old_state)
+ except Exception as e:
+ log.error("forget_all_wifi_networks with exception: %s", e)
+ return False
+ ad.on_mobile_data = True
+ return True
+
+
+def wifi_reset(log, ad, disable_wifi=True):
+ """Forget all stored wifi networks and (optionally) disable WiFi
+
+ Args:
+ log: log object
+ ad: AndroidDevice object
+ disable_wifi: boolean to disable wifi, defaults to True
+ Returns:
+ boolean success (True) or failure (False)
+ """
+ if not forget_all_wifi_networks(log, ad):
+ ad.log.error("Unable to forget all networks")
+ return False
+ if not wifi_toggle_state(log, ad, not disable_wifi):
+ ad.log.error("Failed to toggle WiFi state to %s!", not disable_wifi)
+ return False
+ return True
+
+
+def set_wifi_to_default(log, ad):
+ """Set wifi to default state (Wifi disabled and no configured network)
+
+ Args:
+ log: log object
+ ad: AndroidDevice object
+
+ Returns:
+ boolean success (True) or failure (False)
+ """
+ ad.droid.wifiFactoryReset()
+ ad.droid.wifiToggleState(False)
+ ad.on_mobile_data = True
+
+
+def wifi_toggle_state(log, ad, state, retries=3):
+ """Toggle the WiFi State
+
+ Args:
+ log: log object
+ ad: AndroidDevice object
+ state: True, False, or None
+
+ Returns:
+ boolean success (True) or failure (False)
+ """
+ for i in range(retries):
+ if wifi_test_utils.wifi_toggle_state(ad, state, assert_on_fail=False):
+ ad.on_mobile_data = not state
+ return True
+ time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
+ return False
+
+
+def start_wifi_tethering(log, ad, ssid, password, ap_band=None):
+ """Start a Tethering Session
+
+ Args:
+ log: log object
+ ad: AndroidDevice object
+ ssid: the name of the WiFi network
+ password: optional password, used for secure networks.
+ ap_band=DEPRECATED specification of 2G or 5G tethering
+ Returns:
+ boolean success (True) or failure (False)
+ """
+ return wifi_test_utils._assert_on_fail_handler(
+ wifi_test_utils.start_wifi_tethering,
+ False,
+ ad,
+ ssid,
+ password,
+ band=ap_band)
+
+
+def stop_wifi_tethering(log, ad):
+ """Stop a Tethering Session
+
+ Args:
+ log: log object
+ ad: AndroidDevice object
+ Returns:
+ boolean success (True) or failure (False)
+ """
+ return wifi_test_utils._assert_on_fail_handler(
+ wifi_test_utils.stop_wifi_tethering, False, ad)
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/wifi/wifi_performance_test_utils.py b/acts_tests/acts_contrib/test_utils/wifi/wifi_performance_test_utils.py
index 1862889..8afe1d5 100644
--- a/acts_tests/acts_contrib/test_utils/wifi/wifi_performance_test_utils.py
+++ b/acts_tests/acts_contrib/test_utils/wifi/wifi_performance_test_utils.py
@@ -680,7 +680,7 @@
"""
for atten in atten_list:
if path_label in atten.path:
- atten.set_atten(atten_level)
+ atten.set_atten(atten_level, retry=True)
def get_atten_for_target_rssi(target_rssi, attenuators, dut, ping_server):
@@ -701,7 +701,7 @@
logging.info('Searching attenuation for RSSI = {}dB'.format(target_rssi))
# Set attenuator to 0 dB
for atten in attenuators:
- atten.set_atten(0, strict=False)
+ atten.set_atten(0, strict=False, retry=True)
# Start ping traffic
dut_ip = dut.droid.connectivityGetIPv4Addresses('wlan0')[0]
# Measure starting RSSI
@@ -730,7 +730,7 @@
if target_atten > attenuators[0].get_max_atten():
return attenuators[0].get_max_atten()
for atten in attenuators:
- atten.set_atten(target_atten, strict=False)
+ atten.set_atten(target_atten, strict=False, retry=True)
ping_future = get_ping_stats_nb(src_device=ping_server,
dest_address=dut_ip,
ping_duration=1.5,
@@ -783,7 +783,7 @@
"""
# Set attenuator to 0 dB
for atten in attenuators:
- atten.set_atten(0, strict=False)
+ atten.set_atten(0, strict=False, retry=True)
# Start ping traffic
dut_ip = dut.droid.connectivityGetIPv4Addresses('wlan0')[0]
if ping_from_dut:
@@ -802,7 +802,7 @@
chain_map = []
for test_atten in attenuators:
# Set one attenuator to 30 dB down
- test_atten.set_atten(30, strict=False)
+ test_atten.set_atten(30, strict=False, retry=True)
# Get new RSSI
test_rssi = get_connected_rssi(dut, 4, 0.25, 1)
# Assign attenuator to path that has lower RSSI
@@ -815,7 +815,7 @@
else:
chain_map.append(None)
# Reset attenuator to 0
- test_atten.set_atten(0, strict=False)
+ test_atten.set_atten(0, strict=False, retry=True)
ping_future.result()
logging.debug('Chain Map: {}'.format(chain_map))
return chain_map
@@ -845,7 +845,7 @@
rf_map_by_atten: list of RF connections indexed by attenuator
"""
for atten in attenuators:
- atten.set_atten(0, strict=False)
+ atten.set_atten(0, strict=False, retry=True)
rf_map_by_network = collections.OrderedDict()
rf_map_by_atten = [[] for atten in attenuators]
diff --git a/acts_tests/acts_contrib/test_utils/wifi/wifi_test_utils.py b/acts_tests/acts_contrib/test_utils/wifi/wifi_test_utils.py
index 2e3f336..1729a7c 100755
--- a/acts_tests/acts_contrib/test_utils/wifi/wifi_test_utils.py
+++ b/acts_tests/acts_contrib/test_utils/wifi/wifi_test_utils.py
@@ -744,6 +744,7 @@
"Failed to remove these configured Wi-Fi networks: %s" % networks)
+
def toggle_airplane_mode_on_and_off(ad):
"""Turn ON and OFF Airplane mode.
diff --git a/acts_tests/acts_contrib/test_utils_tests/audio_analysis_integrationtest.py b/acts_tests/acts_contrib/test_utils_tests/audio_analysis_integrationtest.py
index a00a431..eb56f20 100644
--- a/acts_tests/acts_contrib/test_utils_tests/audio_analysis_integrationtest.py
+++ b/acts_tests/acts_contrib/test_utils_tests/audio_analysis_integrationtest.py
@@ -21,11 +21,6 @@
import os
import unittest
-# TODO(markdr): Remove this after soundfile is added to setup.py
-import sys
-import mock
-sys.modules['soundfile'] = mock.Mock()
-
import acts_contrib.test_utils.audio_analysis_lib.audio_analysis as audio_analysis
import acts_contrib.test_utils.audio_analysis_lib.audio_data as audio_data
diff --git a/acts_tests/acts_contrib/test_utils_tests/audio_quality_measurement_integrationtest.py b/acts_tests/acts_contrib/test_utils_tests/audio_quality_measurement_integrationtest.py
index 396e5b8..c8b4f25 100644
--- a/acts_tests/acts_contrib/test_utils_tests/audio_quality_measurement_integrationtest.py
+++ b/acts_tests/acts_contrib/test_utils_tests/audio_quality_measurement_integrationtest.py
@@ -22,11 +22,6 @@
import numpy
import unittest
-# TODO(markdr): Remove this after soundfile is added to setup.py
-import sys
-import mock
-sys.modules['soundfile'] = mock.Mock()
-
import acts_contrib.test_utils.audio_analysis_lib.audio_quality_measurement as audio_quality_measurement
diff --git a/acts_tests/setup.py b/acts_tests/setup.py
index 592fcee..6c0a4a6 100755
--- a/acts_tests/setup.py
+++ b/acts_tests/setup.py
@@ -30,8 +30,20 @@
acts_tests_dir = os.path.abspath(os.path.dirname(__file__))
-install_requires = []
+install_requires = ['soundfile']
+if sys.version_info < (3, 6):
+ # Python <= 3.5 uses bokeh up to 1.4.x
+ install_requires.append('bokeh<1.5')
+elif sys.version_info < (3, 7):
+ # Python 3.6 uses bokeh up to 2.3.x
+ install_requires.append('bokeh<2.4')
+elif sys.version_info < (3, 8):
+ # Python 3.7+ uses bokeh up to 2.4.x
+ install_requires.append('bokeh<2.5')
+else:
+ # Python 3.8+ is support by latest bokeh
+ install_requires.append('bokeh')
def _setup_acts_framework(option, *args):
@@ -68,9 +80,13 @@
Otherwise, it will attempt to locate the ACTS framework from the local
repository.
"""
+
def run(self):
- super().run()
_setup_acts_framework('install')
+ # Calling install.run() directly fails to install the dependencies as
+ # listed in install_requires. Use install.do_egg_install() instead.
+ # Ref: https://stackoverflow.com/questions/21915469
+ self.do_egg_install()
class ActsContribDevelop(develop):
@@ -78,6 +94,7 @@
See ActsContribInstall for more details.
"""
+
def run(self):
super().run()
if self.uninstall:
@@ -142,8 +159,9 @@
acts_contrib_module: The acts_contrib module to uninstall.
"""
for acts_contrib_install_dir in acts_contrib_module.__path__:
- self.announce('Deleting acts_contrib from: %s'
- % acts_contrib_install_dir, log.INFO)
+ self.announce(
+ 'Deleting acts_contrib from: %s' % acts_contrib_install_dir,
+ log.INFO)
shutil.rmtree(acts_contrib_install_dir)
def run(self):
@@ -160,8 +178,9 @@
try:
import acts_contrib as acts_contrib_module
except ImportError:
- self.announce('acts_contrib is not installed, nothing to uninstall.',
- level=log.ERROR)
+ self.announce(
+ 'acts_contrib is not installed, nothing to uninstall.',
+ level=log.ERROR)
return
while acts_contrib_module:
@@ -180,7 +199,7 @@
def main():
os.chdir(acts_tests_dir)
- packages = setuptools.find_packages(include=('acts_contrib*',))
+ packages = setuptools.find_packages(include=('acts_contrib*', ))
setuptools.setup(name='acts_contrib',
version='0.9',
description='Android Comms Test Suite',
diff --git a/acts_tests/tests/OWNERS b/acts_tests/tests/OWNERS
index c38e234..3f4ab0f 100644
--- a/acts_tests/tests/OWNERS
+++ b/acts_tests/tests/OWNERS
@@ -20,12 +20,21 @@
jerrypcchen@google.com
martschneider@google.com
timhuang@google.com
+sishichen@google.com
# Fuchsia
+belgum@google.com
+chcl@google.com
+dhobsd@google.com
haydennix@google.com
jmbrenna@google.com
-#mrwifi@google.com
+nmccracken@google.com
+mnck@google.com
+nickchee@google.com
+sakuma@google.com
+silberst@google.com
tturney@google.com
+sbalana@google.com
# TechEng
abhinavjadon@google.com
diff --git a/acts_tests/tests/google/ble/api/BleAdvertiseApiTest.py b/acts_tests/tests/google/ble/api/BleAdvertiseApiTest.py
index c044b4d..877b00e 100644
--- a/acts_tests/tests/google/ble/api/BleAdvertiseApiTest.py
+++ b/acts_tests/tests/google/ble/api/BleAdvertiseApiTest.py
@@ -20,13 +20,16 @@
then other test suites utilising Ble Advertisements will also fail.
"""
+import pprint
+
from acts.controllers.sl4a_lib import rpc_client
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
-from acts_contrib.test_utils.bt.bt_test_utils import adv_fail
+from acts_contrib.test_utils.bt.bt_test_utils import adv_fail, adv_succ, scan_result
from acts_contrib.test_utils.bt.bt_test_utils import generate_ble_advertise_objects
from acts_contrib.test_utils.bt.bt_constants import ble_advertise_settings_modes
from acts_contrib.test_utils.bt.bt_constants import ble_advertise_settings_tx_powers
+# from acts_contrib.test_utils.bt.bt_constants import ble_advertise_settings_own_address_types
from acts_contrib.test_utils.bt.bt_constants import java_integer
@@ -38,6 +41,7 @@
def setup_class(self):
super().setup_class()
self.ad_dut = self.android_devices[0]
+ self.sc_dut = self.android_devices[1]
@BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='d6d8d0a6-7b3e-4e4b-a5d0-bcfd6e207474')
@@ -498,6 +502,149 @@
exp_is_connectable)
@BluetoothBaseTest.bt_test_wrap
+ def test_adv_settings_set_adv_own_address_type_public(self):
+ """Tests advertise settings own address type public.
+
+ This advertisement settings from "set" advertisement own address type
+ should match the corresponding "get" function.
+
+ Steps:
+ 1. Build a new advertise settings object.
+ 2. Set the advertise mode attribute to own address type public.
+ 3. Get the attributes of the advertise settings object.
+ 4. Compare the attributes found against the attributes exp.
+
+ Expected Result:
+ Found attributes should match expected attributes.
+
+ Returns:
+ True is pass
+ False if fail
+
+ TAGS: LE, Advertising
+ Priority: 1
+ """
+ self.log.debug("Step 1: Setup environment.")
+ droid = self.ad_dut.droid
+ # exp_adv_own_address_type = ble_advertise_settings_own_address_types['public']
+ exp_adv_own_address_type = 0
+ self.log.debug(
+ "Step 2: Set the filtering settings object's value to {}".format(
+ exp_adv_own_address_type))
+ return self.verify_adv_settings_own_address_type(droid, exp_adv_own_address_type)
+
+ @BluetoothBaseTest.bt_test_wrap
+ def test_adv_settings_set_adv_own_address_type_random(self):
+ """Tests advertise settings own address type random.
+
+ This advertisement settings from "set" advertisement own address type
+ should match the corresponding "get" function.
+
+ Steps:
+ 1. Build a new advertise settings object.
+ 2. Set the advertise mode attribute to own address type random.
+ 3. Get the attributes of the advertise settings object.
+ 4. Compare the attributes found against the attributes exp.
+
+ Expected Result:
+ Found attributes should match expected attributes.
+
+ Returns:
+ True is pass
+ False if fail
+
+ TAGS: LE, Advertising
+ Priority: 1
+ """
+ self.log.debug("Step 1: Setup environment.")
+ droid = self.ad_dut.droid
+ # exp_adv_own_address_type = ble_advertise_settings_own_address_types['random']
+ exp_adv_own_address_type = 1
+ self.log.debug(
+ "Step 2: Set the filtering settings object's value to {}".format(
+ exp_adv_own_address_type))
+ return self.verify_adv_settings_own_address_type(droid, exp_adv_own_address_type)
+
+ @BluetoothBaseTest.bt_test_wrap
+ def test_adv_with_multiple_own_address_types(self):
+ ad_droid = self.ad_dut.droid
+ sc_droid = self.sc_dut.droid
+ sc_ed = self.sc_dut.ed
+ adv_count = 10
+ exp_adv_own_address_types = [0, 1, 1, 0, 0, 1, 1, 1, 0, 0]
+ uuid = '01234567-89ab-cdef-0123-456789abcdef'
+ service_data = []
+
+ for i in range(3):
+ service_data.append(i)
+
+ for own_add_type in exp_adv_own_address_types:
+ result = self.verify_adv_set_address_type_start_adv(ad_droid,
+ own_add_type, uuid, service_data)
+ if result is False:
+ return False
+
+ mac_list = []
+
+ filter_list = sc_droid.bleGenFilterList()
+ scan_settings = sc_droid.bleBuildScanSetting()
+ scan_callback = sc_droid.bleGenScanCallback()
+ sc_droid.bleStartBleScan(filter_list, scan_settings,
+ scan_callback)
+ event_name = scan_result.format(scan_callback)
+ self.log.info("Scan onSuccess Event")
+
+ for _ in range(1000):
+ if len(mac_list) is adv_count:
+ break
+
+ try:
+ event = sc_ed.pop_event(event_name, 10)
+ result = event['data']['Result']
+ deviceInfo = result['deviceInfo']
+ serviceUuidList = result['serviceUuidList']
+ if uuid in serviceUuidList:
+ mac_addr = deviceInfo['address']
+ if mac_addr not in mac_list:
+ self.log.info("Found device. address: {}".format(mac_addr))
+ mac_list.append(mac_addr)
+
+ except rpc_client.Sl4aApiError:
+ self.log.info("{} event was not found.".format(event_name))
+ break
+
+ return len(mac_list) is adv_count
+
+ @BluetoothBaseTest.bt_test_wrap
+ def test_adv_settings_set_invalid_adv_own_address_type(self):
+ """Tests advertise settings invalid own address type.
+
+ This advertisement settings from "set" advertisement own address type
+ should match the corresponding "get" function.
+
+ Steps:
+ 1. Build a new advertise settings object.
+ 2. Set the advertise mode attribute to invalid own address type.
+ 3. Get the attributes of the advertise settings object.
+ 4. Compare the attributes found against the attributes exp.
+
+ Expected Result:
+ Found attributes should match expected attributes.
+
+ Returns:
+ True is pass
+ False if fail
+
+ TAGS: LE, Advertising
+ Priority: 1
+ """
+ self.log.debug("Step 1: Setup environment.")
+ droid = self.ad_dut.droid
+ exp_adv_own_address_type = -100
+ self.log.debug("Step 2: Set the filtering settings own address type to -1")
+ return self.verify_invalid_adv_settings_own_address_type(droid, exp_adv_own_address_type)
+
+ @BluetoothBaseTest.bt_test_wrap
@test_tracker_info(uuid='a770ed7e-c6cd-4533-8876-e42e68f8b4fb')
def test_adv_data_set_service_uuids_empty(self):
"""Tests advertisement data's service uuids to empty.
@@ -1095,6 +1242,55 @@
" value test Passed.".format(exp_is_connectable))
return True
+ def verify_adv_settings_own_address_type(self, droid, exp_adv_own_address_type):
+ try:
+ droid.bleSetAdvertiseSettingsOwnAddressType(exp_adv_own_address_type)
+ except BleAdvertiseVerificationError as error:
+ self.log.debug(str(error))
+ return False
+ self.log.debug("Step 3: Get a filtering settings object's index.")
+ settings_index = droid.bleBuildAdvertiseSettings()
+ self.log.debug("Step 4: Get the filtering setting's own address type.")
+ adv_own_address_type = droid.bleGetAdvertiseSettingsOwnAddressType(
+ settings_index)
+ if exp_adv_own_address_type is not adv_own_address_type:
+ self.log.debug("exp value: {}, Actual value: {}".format(
+ exp_adv_own_address_type, adv_own_address_type))
+ return False
+ self.log.debug("Advertise Setting's own address type {}"
+ " value test Passed.".format(exp_adv_own_address_type))
+ return True
+
+ def verify_adv_set_address_type_start_adv(self, droid, own_address_type, uuid, service_data):
+ try:
+ droid.bleSetAdvertiseSettingsOwnAddressType(own_address_type)
+ except BleAdvertiseVerificationError as error:
+ self.log.debug(str(error))
+ return False
+
+ droid.bleAddAdvertiseDataServiceData(
+ uuid, service_data)
+ advcallback, adv_data, adv_settings = generate_ble_advertise_objects(
+ droid)
+ droid.bleStartBleAdvertising(advcallback, adv_data, adv_settings)
+
+ adv_own_address_type = droid.bleGetAdvertiseSettingsOwnAddressType(
+ adv_settings)
+ if own_address_type is not adv_own_address_type:
+ self.log.debug("exp value: {}, Actual value: {}".format(
+ own_address_type, adv_own_address_type))
+ return False
+
+ try:
+ event = self.android_devices[0].ed.pop_event(adv_succ.format(advcallback), 10)
+ self.log.info("Ble Advertise Success Event: {}".format(event))
+ except rpc_client.Sl4aApiError:
+ self.log.info("{} event was not found.".format(
+ adv_succ.format(advcallback)))
+ return False
+
+ return True
+
def verify_adv_data_service_uuids(self, droid, exp_service_uuids):
try:
droid.bleSetAdvertiseDataSetServiceUuids(exp_service_uuids)
@@ -1227,6 +1423,20 @@
"failed successfullywith input as {}".format(exp_adv_tx_power))
return True
+ def verify_invalid_adv_settings_own_address_type(self, droid,
+ exp_adv_own_address_type):
+ try:
+ droid.bleSetAdvertiseSettingsOwnAddressType(exp_adv_own_address_type)
+ droid.bleBuildAdvertiseSettings()
+ self.log.debug("Set Advertise settings invalid own address type " +
+ " with input as {}".format(exp_adv_own_address_type))
+ return False
+ except rpc_client.Sl4aApiError:
+ self.log.debug(
+ "Set Advertise settings invalid own address type "
+ "failed successfully with input as {}".format(exp_adv_own_address_type))
+ return True
+
def verify_invalid_adv_data_service_uuids(self, droid, exp_service_uuids):
try:
droid.bleSetAdvertiseDataSetServiceUuids(exp_service_uuids)
diff --git a/acts_tests/tests/google/ble/concurrency/ConcurrentGattConnectTest.py b/acts_tests/tests/google/ble/concurrency/ConcurrentGattConnectTest.py
index 6a5b861..4162b23 100644
--- a/acts_tests/tests/google/ble/concurrency/ConcurrentGattConnectTest.py
+++ b/acts_tests/tests/google/ble/concurrency/ConcurrentGattConnectTest.py
@@ -141,14 +141,14 @@
if adv_name in item
]
devices_found.append(device[0][0].serial)
- if len(device) is not 0:
+ if len(device) != 0:
address_list_tuple = (device[0][0], mac_address)
else:
continue
result = [item for item in address_list if mac_address in item]
# if length of result is 0, it indicates that we have discovered
# new mac address.
- if len(result) is 0:
+ if len(result) == 0:
self.log.info("Found new mac address: {}".format(
address_list_tuple[1]))
address_list.append(address_list_tuple)
diff --git a/acts_tests/tests/google/bt/car_bt/BtCarHfpConferenceTest.py b/acts_tests/tests/google/bt/car_bt/BtCarHfpConferenceTest.py
index edb9683..5611de3 100644
--- a/acts_tests/tests/google/bt/car_bt/BtCarHfpConferenceTest.py
+++ b/acts_tests/tests/google/bt/car_bt/BtCarHfpConferenceTest.py
@@ -26,9 +26,9 @@
from acts_contrib.test_utils.bt import bt_test_utils
from acts_contrib.test_utils.car import car_telecom_utils
from acts_contrib.test_utils.tel import tel_defines
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import wait_and_answer_call
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call
from acts_contrib.test_utils.tel.tel_test_utils import wait_for_ringing_call
from acts_contrib.test_utils.tel.tel_voice_utils import get_audio_route
from acts_contrib.test_utils.tel.tel_voice_utils import set_audio_route
diff --git a/acts_tests/tests/google/bt/car_bt/BtCarHfpConnectionTest.py b/acts_tests/tests/google/bt/car_bt/BtCarHfpConnectionTest.py
index bda7e88..e0ea79e 100644
--- a/acts_tests/tests/google/bt/car_bt/BtCarHfpConnectionTest.py
+++ b/acts_tests/tests/google/bt/car_bt/BtCarHfpConnectionTest.py
@@ -27,9 +27,9 @@
from acts_contrib.test_utils.car import car_bt_utils
from acts_contrib.test_utils.car import car_telecom_utils
from acts_contrib.test_utils.tel import tel_defines
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import wait_and_answer_call
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call
BLUETOOTH_PKG_NAME = "com.android.bluetooth"
CALL_TYPE_OUTGOING = "CALL_TYPE_OUTGOING"
diff --git a/acts_tests/tests/google/bt/performance/BtA2dpRangeTest.py b/acts_tests/tests/google/bt/performance/BtA2dpRangeTest.py
index 99e564c..d2bcb10 100644
--- a/acts_tests/tests/google/bt/performance/BtA2dpRangeTest.py
+++ b/acts_tests/tests/google/bt/performance/BtA2dpRangeTest.py
@@ -22,7 +22,7 @@
from acts_contrib.test_utils.bt import BtEnum
from acts_contrib.test_utils.bt.A2dpBaseTest import A2dpBaseTest
from acts_contrib.test_utils.bt.loggers import bluetooth_metric_logger as log
-from acts.test_utils.power.PowerBTBaseTest import ramp_attenuation
+from acts_contrib.test_utils.power.PowerBTBaseTest import ramp_attenuation
from acts.signals import TestPass
diff --git a/acts_tests/tests/google/bt/pts/cmd_input.py b/acts_tests/tests/google/bt/pts/cmd_input.py
index 2db77a7..9a90c1d 100644
--- a/acts_tests/tests/google/bt/pts/cmd_input.py
+++ b/acts_tests/tests/google/bt/pts/cmd_input.py
@@ -1023,6 +1023,18 @@
except Exception as err:
self.log.info(FAILURE.format(cmd, err))
+ def do_bta_hfp_client_connect(self, line):
+ self.pri_dut.droid.bluetoothHfpClientConnect(self.mac_addr)
+
+ def do_bta_hfp_client_disconnect(self, line):
+ self.pri_dut.droid.bluetoothHfpClientDisconnect(self.mac_addr)
+
+ def do_bta_hfp_client_connect_audio(self, line):
+ self.pri_dut.droid.bluetoothHfpClientConnectAudio(self.mac_addr)
+
+ def do_bta_hfp_client_disconnect_audio(self, line):
+ self.pri_dut.droid.bluetoothHfpClientDisconnectAudio(self.mac_addr)
+
"""End HFP/HSP wrapper"""
"""Begin HID wrappers"""
diff --git a/acts_tests/tests/google/coex/functionality_tests/WlanWithHfpFunctionalityTest.py b/acts_tests/tests/google/coex/functionality_tests/WlanWithHfpFunctionalityTest.py
index f6aadc3..3b71537 100644
--- a/acts_tests/tests/google/coex/functionality_tests/WlanWithHfpFunctionalityTest.py
+++ b/acts_tests/tests/google/coex/functionality_tests/WlanWithHfpFunctionalityTest.py
@@ -27,8 +27,8 @@
from acts_contrib.test_utils.coex.coex_test_utils import toggle_screen_state
from acts_contrib.test_utils.coex.coex_test_utils import setup_tel_config
from acts_contrib.test_utils.coex.coex_test_utils import start_fping
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
BLUETOOTH_WAIT_TIME = 2
diff --git a/acts_tests/tests/google/coex/performance_tests/CoexBtMultiProfilePerformanceTest.py b/acts_tests/tests/google/coex/performance_tests/CoexBtMultiProfilePerformanceTest.py
index de36052..a952c1a 100644
--- a/acts_tests/tests/google/coex/performance_tests/CoexBtMultiProfilePerformanceTest.py
+++ b/acts_tests/tests/google/coex/performance_tests/CoexBtMultiProfilePerformanceTest.py
@@ -33,9 +33,9 @@
from acts_contrib.test_utils.coex.coex_test_utils import pair_and_connect_headset
from acts_contrib.test_utils.coex.coex_test_utils import setup_tel_config
from acts_contrib.test_utils.coex.coex_test_utils import connect_wlan_profile
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import wait_and_answer_call
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call
class CoexBtMultiProfilePerformanceTest(CoexPerformanceBaseTest):
diff --git a/acts_tests/tests/google/coex/performance_tests/WlanWithHfpPerformanceTest.py b/acts_tests/tests/google/coex/performance_tests/WlanWithHfpPerformanceTest.py
index b56cbde..0c5b5da 100644
--- a/acts_tests/tests/google/coex/performance_tests/WlanWithHfpPerformanceTest.py
+++ b/acts_tests/tests/google/coex/performance_tests/WlanWithHfpPerformanceTest.py
@@ -22,8 +22,8 @@
from acts_contrib.test_utils.coex.coex_test_utils import initiate_disconnect_from_hf
from acts_contrib.test_utils.coex.coex_test_utils import pair_and_connect_headset
from acts_contrib.test_utils.coex.coex_test_utils import setup_tel_config
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
class WlanWithHfpPerformanceTest(CoexPerformanceBaseTest):
diff --git a/acts_tests/tests/google/coex/stress_tests/CoexHfpStressTest.py b/acts_tests/tests/google/coex/stress_tests/CoexHfpStressTest.py
index 8add009..49ee4a9 100644
--- a/acts_tests/tests/google/coex/stress_tests/CoexHfpStressTest.py
+++ b/acts_tests/tests/google/coex/stress_tests/CoexHfpStressTest.py
@@ -26,7 +26,7 @@
from acts_contrib.test_utils.tel.tel_defines import AUDIO_ROUTE_BLUETOOTH
from acts_contrib.test_utils.tel.tel_defines import AUDIO_ROUTE_SPEAKER
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
from acts_contrib.test_utils.tel.tel_voice_utils import set_audio_route
diff --git a/acts_tests/tests/google/fuchsia/bt/command_input.py b/acts_tests/tests/google/fuchsia/bt/command_input.py
index 69778c2..c993ac0 100644
--- a/acts_tests/tests/google/fuchsia/bt/command_input.py
+++ b/acts_tests/tests/google/fuchsia/bt/command_input.py
@@ -43,6 +43,9 @@
"""
+from acts_contrib.test_utils.audio_analysis_lib.check_quality import quality_analysis
+from acts_contrib.test_utils.bt.bt_constants import audio_bits_per_sample_32
+from acts_contrib.test_utils.bt.bt_constants import audio_sample_rate_48000
from acts_contrib.test_utils.abstract_devices.bluetooth_device import create_bluetooth_device
from acts_contrib.test_utils.bt.bt_constants import bt_attribute_values
from acts_contrib.test_utils.bt.bt_constants import sig_appearance_constants
@@ -2275,6 +2278,58 @@
except Exception as err:
self.log.error(FAILURE.format(cmd, err))
+ def do_audio_5_min_test(self, line):
+ """
+ Description: Capture and anlyize sine audio waves played from a Bluetooth A2DP
+ Source device.
+
+ Pre steps:
+ 1. Pair A2DP source device
+ 2. Prepare generated SOX file over preferred codec on source device.
+ Quick way to generate necessary audio files:
+ sudo apt-get install sox
+ sox -b 16 -r 48000 -c 2 -n audio_file_2k1k_5_min.wav synth 300 sine 2000 sine 3000
+
+ Usage:
+ Examples:
+ audio_5_min_test
+ """
+ cmd = "5 min audio capture test"
+ input("Press Enter once Source device is streaming audio file")
+ try:
+ result = self.pri_dut.audio_lib.startOutputSave()
+ self.log.info(result)
+ for i in range(5):
+ print("Minutes left: {}".format(10 - i))
+ time.sleep(60)
+ result = self.pri_dut.audio_lib.stopOutputSave()
+ log_time = int(time.time())
+ save_path = "{}/{}".format(self.pri_dut.log_path,
+ "{}_audio.raw".format(log_time))
+ analysis_path = "{}/{}".format(
+ self.pri_dut.log_path,
+ "{}_audio_analysis.txt".format(log_time))
+ result = self.pri_dut.audio_lib.getOutputAudio(save_path)
+
+ channels = 1
+ try:
+ quality_analysis(filename=save_path,
+ output_file=analysis_path,
+ bit_width=audio_bits_per_sample_32,
+ rate=audio_sample_rate_48000,
+ channel=channels,
+ spectral_only=False)
+
+ except Exception as err:
+ self.log.error("Failed to analyze raw audio: {}".format(err))
+ return False
+
+ self.log.info("Analysis output here: {}".format(analysis_path))
+ self.log.info("Analysis Results: {}".format(
+ open(analysis_path).readlines()))
+ except Exception as err:
+ self.log.error(FAILURE.format(cmd, err))
+
"""End Audio wrappers"""
"""Begin HFP wrappers"""
@@ -2321,7 +2376,7 @@
cmd = "Lists connected peers"
try:
result = self.pri_dut.hfp_lib.listPeers()
- self.log.info(result)
+ self.log.info(pprint.pformat(result))
except Exception as err:
self.log.error(FAILURE.format(cmd, err))
@@ -2357,7 +2412,7 @@
cmd = "Lists all calls"
try:
result = self.pri_dut.hfp_lib.listCalls()
- self.log.info(result)
+ self.log.info(pprint.pformat(result))
except Exception as err:
self.log.error(FAILURE.format(cmd, err))
@@ -2369,23 +2424,27 @@
remote: The number of the remote party on the simulated call
state: The state of the call. Must be one of "ringing", "waiting",
"dialing", "alerting", "active", "held".
+ direction: The direction of the call. Must be one of "incoming", "outgoing".
Usage:
Examples:
- hfp_new_call <remote> <state>
- hfp_new_call 14085555555 active
- hfp_new_call 14085555555 held
- hfp_new_call 14085555555 ringing
- hfp_new_call 14085555555 alerting
- hfp_new_call 14085555555 dialing
+ hfp_new_call <remote> <state> <direction>
+ hfp_new_call 14085555555 active incoming
+ hfp_new_call 14085555555 held outgoing
+ hfp_new_call 14085555555 ringing incoming
+ hfp_new_call 14085555555 waiting incoming
+ hfp_new_call 14085555555 alerting outgoing
+ hfp_new_call 14085555555 dialing outgoing
"""
cmd = "Simulates a call"
try:
info = line.strip().split()
- if len(info) != 2:
- raise ValueError("Exactly two command line arguments required: <remote> <state>")
- remote, state = info[0], info[1]
- result = self.pri_dut.hfp_lib.newCall(remote, state)
+ if len(info) != 3:
+ raise ValueError(
+ "Exactly three command line arguments required: <remote> <state> <direction>"
+ )
+ remote, state, direction = info[0], info[1], info[2]
+ result = self.pri_dut.hfp_lib.newCall(remote, state, direction)
self.log.info(result)
except Exception as err:
self.log.error(FAILURE.format(cmd, err))
@@ -2410,6 +2469,27 @@
except Exception as err:
self.log.error(FAILURE.format(cmd, err))
+ def do_hfp_waiting_call(self, line):
+ """
+ Description: Simulate an incoming call on the call manager when there is
+ an onging active call already.
+
+ Input(s):
+ remote: The number of the remote party on the incoming call
+
+ Usage:
+ Examples:
+ hfp_waiting_call <remote>
+ hfp_waiting_call 14085555555
+ """
+ cmd = "Simulates an incoming call"
+ try:
+ remote = line.strip()
+ result = self.pri_dut.hfp_lib.initiateIncomingWaitingCall(remote)
+ self.log.info(result)
+ except Exception as err:
+ self.log.error(FAILURE.format(cmd, err))
+
def do_hfp_outgoing_call(self, line):
"""
Description: Simulate an outgoing call on the call manager
@@ -2741,7 +2821,9 @@
try:
info = line.strip().split()
if len(info) != 2:
- raise ValueError("Exactly two command line arguments required: <location> <number>")
+ raise ValueError(
+ "Exactly two command line arguments required: <location> <number>"
+ )
location, number = info[0], info[1]
result = self.pri_dut.hfp_lib.setMemoryLocation(location, number)
self.log.info(result)
@@ -2784,10 +2866,12 @@
try:
info = line.strip().split()
if len(info) != 2:
- raise ValueError("Exactly two command line arguments required: <number> <status>")
+ raise ValueError(
+ "Exactly two command line arguments required: <number> <status>"
+ )
number, status = info[0], int(info[1])
result = self.pri_dut.hfp_lib.setDialResult(number, status)
- self.log.info(result)
+ self.log.info(pprint.pformat(result))
except Exception as err:
self.log.error(FAILURE.format(cmd, err))
@@ -2802,7 +2886,157 @@
cmd = "Get the call manager's state"
try:
result = self.pri_dut.hfp_lib.getState()
+ self.log.info(pprint.pformat(result))
+ except Exception as err:
+ self.log.error(FAILURE.format(cmd, err))
+
+ def do_hfp_set_connection_behavior(self, line):
+ """
+ Description: Set the Service Level Connection (SLC) behavior when a new peer connects.
+
+ Input(s):
+ autoconnect: Enable/Disable autoconnection of SLC.
+
+ Usage:
+ Examples:
+ hfp_set_connection_behavior <autoconnect>
+ hfp_set_connection_behavior true
+ hfp_set_connection_behavior false
+ """
+ cmd = "Set the Service Level Connection (SLC) behavior"
+ try:
+ autoconnect = line.strip().lower() == "true"
+ result = self.pri_dut.hfp_lib.setConnectionBehavior(autoconnect)
self.log.info(result)
except Exception as err:
self.log.error(FAILURE.format(cmd, err))
+
"""End HFP wrappers"""
+ """Begin RFCOMM wrappers"""
+
+ def do_rfcomm_init(self, line):
+ """
+ Description: Initialize the RFCOMM component services.
+
+ Usage:
+ Examples:
+ rfcomm_init
+ """
+ cmd = "Initialize RFCOMM proxy"
+ try:
+ result = self.pri_dut.rfcomm_lib.init()
+ self.log.info(result)
+ except Exception as err:
+ self.log.error(FAILURE.format(cmd, err))
+
+ def do_rfcomm_remove_service(self, line):
+ """
+ Description: Removes the RFCOMM service in use.
+
+ Usage:
+ Examples:
+ rfcomm_remove_service
+ """
+ cmd = "Remove RFCOMM service"
+ try:
+ result = self.pri_dut.rfcomm_lib.removeService()
+ self.log.info(result)
+ except Exception as err:
+ self.log.error(FAILURE.format(cmd, err))
+
+ def do_rfcomm_disconnect_session(self, line):
+ """
+ Description: Closes the RFCOMM Session.
+
+ Usage:
+ Examples:
+ rfcomm_disconnect_session
+ rfcomm_disconnect_session
+ """
+ cmd = "Disconnect the RFCOMM Session"
+ try:
+ result = self.pri_dut.rfcomm_lib.disconnectSession(
+ self.unique_mac_addr_id)
+ self.log.info(result)
+ except Exception as err:
+ self.log.error(FAILURE.format(cmd, err))
+
+ def do_rfcomm_connect_rfcomm_channel(self, line):
+ """
+ Description: Make an outgoing RFCOMM connection.
+
+ Usage:
+ Examples:
+ rfcomm_connect_rfcomm_channel <server_channel_number>
+ rfcomm_connect_rfcomm_channel 2
+ """
+ cmd = "Make an outgoing RFCOMM connection"
+ try:
+ server_channel_number = int(line.strip())
+ result = self.pri_dut.rfcomm_lib.connectRfcommChannel(
+ self.unique_mac_addr_id, server_channel_number)
+ self.log.info(result)
+ except Exception as err:
+ self.log.error(FAILURE.format(cmd, err))
+
+ def do_rfcomm_disconnect_rfcomm_channel(self, line):
+ """
+ Description: Close the RFCOMM connection with the peer
+
+ Usage:
+ Examples:
+ rfcomm_disconnect_rfcomm_channel <server_channel_number>
+ rfcomm_disconnect_rfcomm_channel 2
+ """
+ cmd = "Close the RFCOMM channel"
+ try:
+ server_channel_number = int(line.strip())
+ result = self.pri_dut.rfcomm_lib.disconnectRfcommChannel(
+ self.unique_mac_addr_id, server_channel_number)
+ self.log.info(result)
+ except Exception as err:
+ self.log.error(FAILURE.format(cmd, err))
+
+ def do_rfcomm_send_remote_line_status(self, line):
+ """
+ Description: Send a remote line status for the RFCOMM channel.
+
+ Usage:
+ Examples:
+ rfcomm_send_remote_line_status <server_channel_number>
+ rfcomm_send_remote_line_status 2
+ """
+ cmd = "Send a remote line status update for the RFCOMM channel"
+ try:
+ server_channel_number = int(line.strip())
+ result = self.pri_dut.rfcomm_lib.sendRemoteLineStatus(
+ self.unique_mac_addr_id, server_channel_number)
+ self.log.info(result)
+ except Exception as err:
+ self.log.error(FAILURE.format(cmd, err))
+
+ def do_rfcomm_write_rfcomm(self, line):
+ """
+ Description: Send data over the RFCOMM channel.
+
+ Usage:
+ Examples:
+ rfcomm_write_rfcomm <server_channel_number> <data>
+ rfcomm_write_rfcomm 2 foobar
+ """
+ cmd = "Send data using the RFCOMM channel"
+ try:
+ info = line.strip().split()
+ if len(info) != 2:
+ raise ValueError(
+ "Exactly two command line arguments required: <server_channel_number> <data>"
+ )
+ server_channel_number = int(info[0])
+ data = info[1]
+ result = self.pri_dut.rfcomm_lib.writeRfcomm(
+ self.unique_mac_addr_id, server_channel_number, data)
+ self.log.info(result)
+ except Exception as err:
+ self.log.error(FAILURE.format(cmd, err))
+
+ """End RFCOMM wrappers"""
diff --git a/acts_tests/tests/google/fuchsia/bt/ep/BtFuchsiaEPTest.py b/acts_tests/tests/google/fuchsia/bt/ep/BtFuchsiaEPTest.py
index 59da1dd..e01afd5 100644
--- a/acts_tests/tests/google/fuchsia/bt/ep/BtFuchsiaEPTest.py
+++ b/acts_tests/tests/google/fuchsia/bt/ep/BtFuchsiaEPTest.py
@@ -241,10 +241,11 @@
input_capabilities = "NONE"
output_capabilities = "NONE"
+
+ # Initialize a2dp on both devices.
self.pri_dut.avdtp_lib.init()
- self.pri_dut.control_daemon("bt-avrcp.cmx", "start")
- self.sec_dut.avdtp_lib.init(initiator_delay=2000)
- self.sec_dut.control_daemon("bt-avrcp-target.cmx", "start")
+ self.sec_dut.avdtp_lib.init()
+
self.pri_dut.bts_lib.acceptPairing(input_capabilities,
output_capabilities)
@@ -265,16 +266,9 @@
raise signals.TestFailure("Failed to connect with {}.".format(
connect_result.get("error")))
- if not verify_device_state_by_name(
- self.pri_dut, self.log, target_device_name, "CONNECTED", None):
- raise signals.TestFailure(
- "Failed to connect to device {}.".format(target_device_name))
-
- if not verify_device_state_by_name(
- self.sec_dut, self.log, source_device_name, "CONNECTED", None):
- raise signals.TestFailure(
- "Failed to connect to device {}.".format(source_device_name))
-
+ # We pair before checking the CONNECTED status because BR/EDR semantics
+ # were recently changed such that if pairing is not confirmed, then bt
+ # does not report connected = True.
security_level = "NONE"
bondable = True
transport = 1 #BREDR
@@ -285,6 +279,16 @@
raise signals.TestFailure("Failed to pair with {}.".format(
pair_result.get("error")))
+ if not verify_device_state_by_name(
+ self.pri_dut, self.log, target_device_name, "CONNECTED", None):
+ raise signals.TestFailure(
+ "Failed to connect to device {}.".format(target_device_name))
+
+ if not verify_device_state_by_name(
+ self.sec_dut, self.log, source_device_name, "CONNECTED", None):
+ raise signals.TestFailure(
+ "Failed to connect to device {}.".format(source_device_name))
+
#TODO: Validation of services and paired devices (b/175641870)
# A2DP sink: 0000110b-0000-1000-8000-00805f9b34fb
# A2DP source: 0000110a-0000-1000-8000-00805f9b34fb
diff --git a/acts_tests/tests/google/fuchsia/bt/gatt/GattServerSetupTest.py b/acts_tests/tests/google/fuchsia/bt/gatt/GattServerSetupTest.py
index 83418e4..41a4cf2 100644
--- a/acts_tests/tests/google/fuchsia/bt/gatt/GattServerSetupTest.py
+++ b/acts_tests/tests/google/fuchsia/bt/gatt/GattServerSetupTest.py
@@ -150,7 +150,7 @@
TAGS: GATT
Priority: 1
- """
+ """
self.setup_database(database.ALERT_NOTIFICATION_SERVICE)
@test_tracker_info(uuid='c42e8bc9-1ba7-4d4e-b67e-9c19cc11472c')
diff --git a/acts_tests/tests/google/fuchsia/bt/gatt/gatt_server_databases.py b/acts_tests/tests/google/fuchsia/bt/gatt/gatt_server_databases.py
index c854281..7575afd 100644
--- a/acts_tests/tests/google/fuchsia/bt/gatt/gatt_server_databases.py
+++ b/acts_tests/tests/google/fuchsia/bt/gatt/gatt_server_databases.py
@@ -13,7 +13,6 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
-
"""
GATT server dictionaries which will be setup in various tests.
"""
@@ -25,7 +24,6 @@
from acts_contrib.test_utils.bt.bt_constants import gatt_characteristic_value_format
from acts_contrib.test_utils.bt.bt_constants import gatt_char_desc_uuids
-
SINGLE_PRIMARY_SERVICE = {
'services': [{
'uuid': '00001802-0000-1000-8000-00805f9b34fb',
@@ -61,6 +59,7 @@
}
### Begin SIG defined services ###
+# yapf: disable
# TODO: Reconcile all the proper security parameters of each service.
# Some are correct, others are not.
@@ -2488,4 +2487,5 @@
}
-### End SIG defined services ###
\ No newline at end of file
+# yapf: enable
+### End SIG defined services ###
diff --git a/acts_tests/tests/google/fuchsia/dhcp/Dhcpv4InteropTest.py b/acts_tests/tests/google/fuchsia/dhcp/Dhcpv4InteropTest.py
new file mode 100644
index 0000000..3a668da
--- /dev/null
+++ b/acts_tests/tests/google/fuchsia/dhcp/Dhcpv4InteropTest.py
@@ -0,0 +1,540 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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 ipaddress
+import itertools
+import random
+import time
+import re
+
+from acts import asserts
+from acts import utils
+from acts.controllers.access_point import setup_ap, AccessPoint
+from acts.controllers.ap_lib import dhcp_config
+from acts.controllers.ap_lib import hostapd_constants
+from acts.controllers.ap_lib.hostapd_security import Security
+from acts.controllers.ap_lib.hostapd_utils import generate_random_password
+from acts.controllers.utils_lib.commands import ip
+from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device
+from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
+from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
+
+
+class Dhcpv4InteropFixture(AbstractDeviceWlanDeviceBaseTest):
+ """Test helpers for validating DHCPv4 Interop
+
+ Test Bed Requirement:
+ * One Android device or Fuchsia device
+ * One Access Point
+ """
+ access_point: AccessPoint
+
+ def __init__(self, controllers):
+ WifiBaseTest.__init__(self, controllers)
+
+ def setup_class(self):
+ super().setup_class()
+ if 'dut' in self.user_params:
+ if self.user_params['dut'] == 'fuchsia_devices':
+ self.dut = create_wlan_device(self.fuchsia_devices[0])
+ elif self.user_params['dut'] == 'android_devices':
+ self.dut = create_wlan_device(self.android_devices[0])
+ else:
+ raise ValueError('Invalid DUT specified in config. (%s)' %
+ self.user_params['dut'])
+ else:
+ # Default is an android device, just like the other tests
+ self.dut = create_wlan_device(self.android_devices[0])
+
+ self.access_point = self.access_points[0]
+ self.access_point.stop_all_aps()
+
+ def setup_test(self):
+ if hasattr(self, "android_devices"):
+ for ad in self.android_devices:
+ ad.droid.wakeLockAcquireBright()
+ ad.droid.wakeUpNow()
+ self.dut.wifi_toggle_state(True)
+
+ def teardown_test(self):
+ if hasattr(self, "android_devices"):
+ for ad in self.android_devices:
+ ad.droid.wakeLockRelease()
+ ad.droid.goToSleepNow()
+ self.dut.turn_location_off_and_scan_toggle_off()
+ self.dut.disconnect()
+ self.dut.reset_wifi()
+ self.access_point.stop_all_aps()
+
+ def connect(self, ap_params):
+ asserts.assert_true(
+ self.dut.associate(ap_params['ssid'],
+ target_pwd=ap_params['password'],
+ target_security=ap_params['target_security']),
+ 'Failed to connect.')
+
+ def setup_ap(self):
+ """Generates a hostapd config and sets up the AP with that config.
+ Does not run a DHCP server.
+
+ Returns: A dictionary of information about the AP.
+ """
+ ssid = utils.rand_ascii_str(20)
+ security_mode = hostapd_constants.WPA2_STRING
+ security_profile = Security(
+ security_mode=security_mode,
+ password=generate_random_password(length=20),
+ wpa_cipher='CCMP',
+ wpa2_cipher='CCMP')
+ password = security_profile.password
+ target_security = hostapd_constants.SECURITY_STRING_TO_DEFAULT_TARGET_SECURITY.get(
+ security_mode)
+
+ ap_ids = setup_ap(access_point=self.access_point,
+ profile_name='whirlwind',
+ mode=hostapd_constants.MODE_11N_MIXED,
+ channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G,
+ n_capabilities=[],
+ ac_capabilities=[],
+ force_wmm=True,
+ ssid=ssid,
+ security=security_profile,
+ password=password)
+
+ if len(ap_ids) > 1:
+ raise Exception("Expected only one SSID on AP")
+
+ configured_subnets = self.access_point.get_configured_subnets()
+ if len(configured_subnets) > 1:
+ raise Exception("Expected only one subnet on AP")
+ router_ip = configured_subnets[0].router
+ network = configured_subnets[0].network
+
+ self.access_point.stop_dhcp()
+
+ return {
+ 'ssid': ssid,
+ 'password': password,
+ 'target_security': target_security,
+ 'ip': router_ip,
+ 'network': network,
+ 'id': ap_ids[0],
+ }
+
+ def device_can_ping(self, dest_ip):
+ """Checks if the DUT can ping the given address.
+
+ Returns: True if can ping, False otherwise"""
+ self.log.info('Attempting to ping %s...' % dest_ip)
+ ping_result = self.dut.can_ping(dest_ip, count=2)
+ if ping_result:
+ self.log.info('Success pinging: %s' % dest_ip)
+ else:
+ self.log.info('Failure pinging: %s' % dest_ip)
+ return ping_result
+
+ def get_device_ipv4_addr(self, interface=None, timeout=20):
+ """Checks if device has an ipv4 private address. Sleeps 1 second between
+ retries.
+
+ Args:
+ interface: string, name of interface from which to get ipv4 address.
+
+ Raises:
+ ConnectionError, if DUT does not have an ipv4 address after all
+ timeout.
+
+ Returns:
+ The device's IP address
+
+ """
+ self.log.debug('Fetching updated WLAN interface list')
+ if interface is None:
+ interface = self.dut.device.wlan_client_test_interface_name
+ self.log.info(
+ 'Checking if DUT has received an ipv4 addr on iface %s. Will retry for %s '
+ 'seconds.' % (interface, timeout))
+ timeout = time.time() + timeout
+ while time.time() < timeout:
+ ip_addrs = self.dut.get_interface_ip_addresses(interface)
+
+ if len(ip_addrs['ipv4_private']) > 0:
+ ip = ip_addrs['ipv4_private'][0]
+ self.log.info('DUT has an ipv4 address: %s' % ip)
+ return ip
+ else:
+ self.log.debug(
+ 'DUT does not yet have an ipv4 address...retrying in 1 '
+ 'second.')
+ time.sleep(1)
+ else:
+ raise ConnectionError('DUT failed to get an ipv4 address.')
+
+ def run_test_case_expect_dhcp_success(self, settings):
+ """Starts the AP and DHCP server, and validates that the client
+ connects and obtains an address.
+
+ Args:
+ settings: a dictionary containing:
+ dhcp_parameters: a dictionary of DHCP parameters
+ dhcp_options: a dictionary of DHCP options
+ """
+ ap_params = self.setup_ap()
+ subnet_conf = dhcp_config.Subnet(
+ subnet=ap_params['network'],
+ router=ap_params['ip'],
+ additional_parameters=settings['dhcp_parameters'],
+ additional_options=settings['dhcp_options'])
+ dhcp_conf = dhcp_config.DhcpConfig(subnets=[subnet_conf])
+
+ self.log.debug('DHCP Configuration:\n' +
+ dhcp_conf.render_config_file() + "\n")
+
+ dhcp_logs_before = self.access_point.get_dhcp_logs()
+ self.access_point.start_dhcp(dhcp_conf=dhcp_conf)
+ self.connect(ap_params=ap_params)
+ dhcp_logs_after = self.access_point.get_dhcp_logs()
+ dhcp_logs = dhcp_logs_after.replace(dhcp_logs_before, '')
+
+ # Typical log lines look like:
+ # dhcpd[26695]: DHCPDISCOVER from f8:0f:f9:3d:ce:d1 via wlan1
+ # dhcpd[26695]: DHCPOFFER on 192.168.9.2 to f8:0f:f9:3d:ce:d1 via wlan1
+ # dhcpd[26695]: DHCPREQUEST for 192.168.9.2 (192.168.9.1) from f8:0f:f9:3d:ce:d1 via wlan1
+ # dhcpd[26695]: DHCPACK on 192.168.9.2 to f8:0f:f9:3d:ce:d1 via wlan1
+
+ try:
+ ip = self.get_device_ipv4_addr()
+ except ConnectionError:
+ self.log.warn(dhcp_logs)
+ asserts.fail(f'DUT failed to get an IP address')
+
+ expected_string = f'DHCPDISCOVER from'
+ asserts.assert_true(
+ dhcp_logs.count(expected_string) == 1,
+ f'Incorrect count of DHCP Discovers ("{expected_string}") in logs: '
+ + dhcp_logs + "\n")
+
+ expected_string = f'DHCPOFFER on {ip}'
+ asserts.assert_true(
+ dhcp_logs.count(expected_string) == 1,
+ f'Incorrect count of DHCP Offers ("{expected_string}") in logs: ' +
+ dhcp_logs + "\n")
+
+ expected_string = f'DHCPREQUEST for {ip}'
+ asserts.assert_true(
+ dhcp_logs.count(expected_string) >= 1,
+ f'Incorrect count of DHCP Requests ("{expected_string}") in logs: '
+ + dhcp_logs + "\n")
+
+ expected_string = f'DHCPACK on {ip}'
+ asserts.assert_true(
+ dhcp_logs.count(expected_string) >= 1,
+ f'Incorrect count of DHCP Acks ("{expected_string}") in logs: ' +
+ dhcp_logs + "\n")
+
+ asserts.assert_true(self.device_can_ping(ap_params['ip']),
+ f'DUT failed to ping router at {ap_params["ip"]}')
+
+
+class Dhcpv4InteropFixtureTest(Dhcpv4InteropFixture):
+ """Tests which validate the behavior of the Dhcpv4InteropFixture.
+
+ In theory, these are more similar to unit tests than ACTS tests, but
+ since they interact with hardware (specifically, the AP), we have to
+ write and run them like the rest of the ACTS tests."""
+
+ def test_invalid_options_not_accepted(self):
+ """Ensures the DHCP server doesn't accept invalid options"""
+ ap_params = self.setup_ap()
+ subnet_conf = dhcp_config.Subnet(subnet=ap_params['network'],
+ router=ap_params['ip'],
+ additional_options={'foo': 'bar'})
+ dhcp_conf = dhcp_config.DhcpConfig(subnets=[subnet_conf])
+ with asserts.assert_raises_regex(Exception, r'failed to start'):
+ self.access_point.start_dhcp(dhcp_conf=dhcp_conf)
+
+ def test_invalid_parameters_not_accepted(self):
+ """Ensures the DHCP server doesn't accept invalid parameters"""
+ ap_params = self.setup_ap()
+ subnet_conf = dhcp_config.Subnet(subnet=ap_params['network'],
+ router=ap_params['ip'],
+ additional_parameters={'foo': 'bar'})
+ dhcp_conf = dhcp_config.DhcpConfig(subnets=[subnet_conf])
+ with asserts.assert_raises_regex(Exception, r'failed to start'):
+ self.access_point.start_dhcp(dhcp_conf=dhcp_conf)
+
+ def test_no_dhcp_server_started(self):
+ """Validates that the test fixture does not start a DHCP server."""
+ ap_params = self.setup_ap()
+ self.connect(ap_params=ap_params)
+ with asserts.assert_raises(ConnectionError):
+ self.get_device_ipv4_addr()
+
+
+class Dhcpv4InteropBasicTest(Dhcpv4InteropFixture):
+ """DhcpV4 tests which validate basic DHCP client/server interactions."""
+
+ def test_basic_dhcp_assignment(self):
+ self.run_test_case_expect_dhcp_success(settings={
+ 'dhcp_options': {},
+ 'dhcp_parameters': {}
+ })
+
+ def test_pool_allows_unknown_clients(self):
+ self.run_test_case_expect_dhcp_success(settings={
+ 'dhcp_options': {},
+ 'dhcp_parameters': {
+ 'allow': 'unknown-clients'
+ }
+ })
+
+ def test_pool_disallows_unknown_clients(self):
+ ap_params = self.setup_ap()
+ subnet_conf = dhcp_config.Subnet(
+ subnet=ap_params['network'],
+ router=ap_params['ip'],
+ additional_parameters={'deny': 'unknown-clients'})
+ dhcp_conf = dhcp_config.DhcpConfig(subnets=[subnet_conf])
+ self.access_point.start_dhcp(dhcp_conf=dhcp_conf)
+
+ self.connect(ap_params=ap_params)
+ with asserts.assert_raises(ConnectionError):
+ self.get_device_ipv4_addr()
+
+ dhcp_logs = self.access_point.get_dhcp_logs()
+ asserts.assert_true(
+ re.search(r'DHCPDISCOVER from .*no free leases', dhcp_logs),
+ "Did not find expected message in dhcp logs: " + dhcp_logs + "\n")
+
+ def test_lease_renewal(self):
+ """Validates that a client renews their DHCP lease."""
+ LEASE_TIME = 30
+ ap_params = self.setup_ap()
+ subnet_conf = dhcp_config.Subnet(subnet=ap_params['network'],
+ router=ap_params['ip'])
+ dhcp_conf = dhcp_config.DhcpConfig(subnets=[subnet_conf],
+ default_lease_time=LEASE_TIME,
+ max_lease_time=LEASE_TIME)
+ self.access_point.start_dhcp(dhcp_conf=dhcp_conf)
+ self.connect(ap_params=ap_params)
+ ip = self.get_device_ipv4_addr()
+
+ dhcp_logs_before = self.access_point.get_dhcp_logs()
+ SLEEP_TIME = LEASE_TIME + 3
+ self.log.info(f'Sleeping {SLEEP_TIME}s to await DHCP renewal')
+ time.sleep(SLEEP_TIME)
+
+ dhcp_logs_after = self.access_point.get_dhcp_logs()
+ dhcp_logs = dhcp_logs_after.replace(dhcp_logs_before, '')
+ # Fuchsia renews at LEASE_TIME / 2, so there should be at least 2 DHCPREQUESTs in logs.
+ # The log lines look like:
+ # INFO dhcpd[17385]: DHCPREQUEST for 192.168.9.2 from f8:0f:f9:3d:ce:d1 via wlan1
+ # INFO dhcpd[17385]: DHCPACK on 192.168.9.2 to f8:0f:f9:3d:ce:d1 via wlan1
+ expected_string = f'DHCPREQUEST for {ip}'
+ asserts.assert_true(
+ dhcp_logs.count(expected_string) >= 2,
+ f'Not enough DHCP renewals ("{expected_string}") in logs: ' +
+ dhcp_logs + "\n")
+
+
+class Dhcpv4DuplicateAddressTest(Dhcpv4InteropFixture):
+ def setup_test(self):
+ super().setup_test()
+ self.extra_addresses = []
+ self.ap_params = self.setup_ap()
+ self.ap_ip_cmd = ip.LinuxIpCommand(self.access_point.ssh)
+
+ def teardown_test(self):
+ super().teardown_test()
+ for ip in self.extra_addresses:
+ self.ap_ip_cmd.remove_ipv4_address(self.ap_params['id'], ip)
+ pass
+
+ def test_duplicate_address_assignment(self):
+ """It's possible for a DHCP server to assign an address that already exists on the network.
+ DHCP clients are expected to perform a "gratuitous ARP" of the to-be-assigned address, and
+ refuse to assign that address. Clients should also recover by asking for a different
+ address.
+ """
+ # Modify subnet to hold fewer addresses.
+ # A '/29' has 8 addresses (6 usable excluding router / broadcast)
+ subnet = next(self.ap_params['network'].subnets(new_prefix=29))
+ subnet_conf = dhcp_config.Subnet(
+ subnet=subnet,
+ router=self.ap_params['ip'],
+ # When the DHCP server is considering dynamically allocating an IP address to a client,
+ # it first sends an ICMP Echo request (a ping) to the address being assigned. It waits
+ # for a second, and if no ICMP Echo response has been heard, it assigns the address.
+ # If a response is heard, the lease is abandoned, and the server does not respond to
+ # the client.
+ # The ping-check configuration parameter can be used to control checking - if its value
+ # is false, no ping check is done.
+ additional_parameters={'ping-check': 'false'})
+ dhcp_conf = dhcp_config.DhcpConfig(subnets=[subnet_conf])
+ self.access_point.start_dhcp(dhcp_conf=dhcp_conf)
+
+ # Add each of the usable IPs as an alias for the router's interface, such that the router
+ # will respond to any pings on it.
+ for ip in subnet.hosts():
+ self.ap_ip_cmd.add_ipv4_address(self.ap_params['id'], ip)
+ # Ensure we remove the address in self.teardown_test() even if the test fails
+ self.extra_addresses.append(ip)
+
+ self.connect(ap_params=self.ap_params)
+ with asserts.assert_raises(ConnectionError):
+ self.get_device_ipv4_addr()
+
+ # Per spec, the flow should be:
+ # Discover -> Offer -> Request -> Ack -> client optionally performs DAD
+ dhcp_logs = self.access_point.get_dhcp_logs()
+ for expected_message in [
+ r'DHCPDISCOVER from \S+',
+ r'DHCPOFFER on [0-9.]+ to \S+',
+ r'DHCPREQUEST for [0-9.]+',
+ r'DHCPACK on [0-9.]+',
+ r'DHCPDECLINE of [0-9.]+ from \S+ via .*: abandoned',
+ r'Abandoning IP address [0-9.]+: declined',
+ ]:
+ asserts.assert_true(
+ re.search(expected_message, dhcp_logs),
+ f'Did not find expected message ({expected_message}) in dhcp logs: {dhcp_logs}'
+ + "\n")
+
+ # Remove each of the IP aliases.
+ # Note: this also removes the router's address (e.g. 192.168.1.1), so pinging the
+ # router after this will not work.
+ while self.extra_addresses:
+ self.ap_ip_cmd.remove_ipv4_address(self.ap_params['id'],
+ self.extra_addresses.pop())
+
+ # Now, we should get an address successfully
+ ip = self.get_device_ipv4_addr()
+ dhcp_logs = self.access_point.get_dhcp_logs()
+
+ expected_string = f'DHCPREQUEST for {ip}'
+ asserts.assert_true(
+ dhcp_logs.count(expected_string) >= 1,
+ f'Incorrect count of DHCP Requests ("{expected_string}") in logs: '
+ + dhcp_logs + "\n")
+
+ expected_string = f'DHCPACK on {ip}'
+ asserts.assert_true(
+ dhcp_logs.count(expected_string) >= 1,
+ f'Incorrect count of DHCP Acks ("{expected_string}") in logs: ' +
+ dhcp_logs + "\n")
+
+
+class Dhcpv4InteropCombinatorialOptionsTest(Dhcpv4InteropFixture):
+ """DhcpV4 tests which validate combinations of DHCP options."""
+ OPT_NUM_DOMAIN_SEARCH = 119
+ OPT_NUM_DOMAIN_NAME = 15
+
+ def setup_class(self):
+ super().setup_class()
+ self.DHCP_OPTIONS = {
+ 'domain-name-tests': [{
+ 'domain-name':
+ '"example.invalid"',
+ 'dhcp-parameter-request-list':
+ self.OPT_NUM_DOMAIN_NAME
+ }, {
+ 'domain-name':
+ '"example.test"',
+ 'dhcp-parameter-request-list':
+ self.OPT_NUM_DOMAIN_NAME
+ }],
+ 'domain-search-tests': [{
+ 'domain-search':
+ '"example.invalid"',
+ 'dhcp-parameter-request-list':
+ self.OPT_NUM_DOMAIN_SEARCH
+ }, {
+ 'domain-search':
+ '"example.test"',
+ 'dhcp-parameter-request-list':
+ self.OPT_NUM_DOMAIN_SEARCH
+ }]
+ }
+
+ # The RFC limits DHCP payloads to 576 bytes unless the client signals it can handle larger
+ # payloads, which it does by sending DHCP option 57, "Maximum DHCP Message Size". Despite
+ # being able to accept larger payloads, clients typically don't advertise this.
+ # The test verifies that the client accepts a large message split across multiple ethernet
+ # frames.
+ # The test is created by sending many bytes of options through the domain-name-servers
+ # option, which is of unbounded length (though is compressed per RFC1035 section 4.1.4).
+ typical_ethernet_mtu = 1500
+ self.DHCP_OPTIONS['max-message-size-tests'] = []
+
+ long_dns_setting = ', '.join(
+ f'"ns{num}.example"'
+ for num in random.sample(range(100_000, 1_000_000), 250))
+ # RFC1035 compression means any shared suffix ('.example' in this case) will
+ # be deduplicated. Calculate approximate length by removing that suffix.
+ long_dns_setting_len = len(
+ long_dns_setting.replace(', ', '').replace('"', '').replace(
+ '.example', '').encode('utf-8'))
+ asserts.assert_true(
+ long_dns_setting_len > typical_ethernet_mtu,
+ "Expected to generate message greater than ethernet mtu")
+ self.DHCP_OPTIONS['max-message-size-tests'].append({
+ 'dhcp-max-message-size':
+ long_dns_setting_len * 2,
+ 'domain-search':
+ long_dns_setting,
+ 'dhcp-parameter-request-list':
+ self.OPT_NUM_DOMAIN_SEARCH
+ })
+
+ def test_domain_names(self):
+ test_list = []
+ for option_list in self.DHCP_OPTIONS['domain-name-tests']:
+ test_list.append({
+ 'dhcp_options': option_list,
+ 'dhcp_parameters': {}
+ })
+ self.run_generated_testcases(self.run_test_case_expect_dhcp_success,
+ settings=test_list)
+
+ def test_search_domains(self):
+ test_list = []
+ for option_list in self.DHCP_OPTIONS['domain-search-tests']:
+ test_list.append({
+ 'dhcp_options': option_list,
+ 'dhcp_parameters': {}
+ })
+ self.run_generated_testcases(self.run_test_case_expect_dhcp_success,
+ settings=test_list)
+
+ def test_large_messages(self):
+ test_list = []
+ for option_list in self.DHCP_OPTIONS['max-message-size-tests']:
+ test_list.append({
+ 'dhcp_options': option_list,
+ 'dhcp_parameters': {}
+ })
+ self.run_generated_testcases(self.run_test_case_expect_dhcp_success,
+ settings=test_list)
+
+ def test_dns(self):
+ pass
+
+ def test_ignored_options_singularly(self):
+ pass
+
+ def test_all_combinations(self):
+ # TODO: test all the combinations above
+ pass
diff --git a/acts_tests/tests/google/fuchsia/examples/Sl4fSanityTest.py b/acts_tests/tests/google/fuchsia/examples/Sl4fSanityTest.py
index d7491dd..91d664e 100644
--- a/acts_tests/tests/google/fuchsia/examples/Sl4fSanityTest.py
+++ b/acts_tests/tests/google/fuchsia/examples/Sl4fSanityTest.py
@@ -28,7 +28,6 @@
class Sl4fSanityTest(BaseTestClass):
-
def setup_class(self):
super().setup_class()
@@ -44,4 +43,3 @@
def test_example(self):
self.log.info("Congratulations! You've run your first test.")
return True
-
diff --git a/acts_tests/tests/google/fuchsia/flash/FlashTest.py b/acts_tests/tests/google/fuchsia/flash/FlashTest.py
new file mode 100644
index 0000000..572a431
--- /dev/null
+++ b/acts_tests/tests/google/fuchsia/flash/FlashTest.py
@@ -0,0 +1,97 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 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.
+"""
+Script for to flash Fuchsia devices and reports the DUT's version of Fuchsia in
+the Sponge test result properties. Uses the built in flashing tool for
+fuchsia_devices.
+"""
+import time
+
+import acts.libs.proc.job as job
+
+from acts import signals
+from acts.base_test import BaseTestClass
+from acts.controllers.fuchsia_lib.base_lib import DeviceOffline
+from acts.utils import get_device
+
+
+class FlashTest(BaseTestClass):
+ def setup_class(self):
+ super().setup_class()
+ success_str = ("Congratulations! Fuchsia controllers have been "
+ "initialized successfully!")
+ err_str = ("Sorry, please try verifying FuchsiaDevice is in your "
+ "config file and try again.")
+ if len(self.fuchsia_devices) > 0:
+ self.log.info(success_str)
+ else:
+ raise signals.TestAbortClass("err_str")
+
+ def teardown_class(self):
+ try:
+ dut = get_device(self.fuchsia_devices, 'DUT')
+ version = dut.version()
+ self.record_data({'sponge_properties': {
+ 'DUT_VERSION': version,
+ }})
+ self.log.info("DUT version found: {}".format(version))
+ except ValueError as err:
+ self.log.warn("Failed to determine DUT: %s" % err)
+ except DeviceOffline as err:
+ self.log.warn("Failed to get DUT's version: %s" % err)
+
+ return super().teardown_class()
+
+ def test_flash_devices(self):
+ flash_retry_max = 3
+ flash_counter = 0
+ for fuchsia_device in self.fuchsia_devices:
+ while flash_counter < flash_retry_max:
+ try:
+ fuchsia_device.reboot(reboot_type='flash',
+ use_ssh=True,
+ unreachable_timeout=120,
+ ping_timeout=120)
+ flash_counter = flash_retry_max
+ except Exception as err:
+ if fuchsia_device.device_pdu_config:
+ self.log.info(
+ 'Flashing failed with error: {}'.format(err))
+ self.log.info('Hard rebooting fuchsia_device({}) and '
+ 'retrying.'.format(
+ fuchsia_device.orig_ip))
+ fuchsia_device.reboot(reboot_type='hard',
+ testbed_pdus=self.pdu_devices)
+ flash_counter = flash_counter + 1
+ if flash_counter == flash_retry_max:
+ raise err
+ time.sleep(1)
+ else:
+ raise err
+ self.log.info("fuchsia_device(%s) has been flashed." %
+ fuchsia_device.orig_ip)
+ flash_counter = 0
+
+ return True
+
+ def test_report_dut_version(self):
+ """Empty test to ensure the version of the DUT is reported in the Sponge
+ results in the case when flashing the device is not necessary.
+
+ Useful for when flashing the device is not necessary; specify ACTS to
+ only run this test from the test class.
+ """
+ pass
diff --git a/acts_tests/tests/google/fuchsia/netstack/NetstackIfaceTest.py b/acts_tests/tests/google/fuchsia/netstack/NetstackIfaceTest.py
index d360277..7033156 100644
--- a/acts_tests/tests/google/fuchsia/netstack/NetstackIfaceTest.py
+++ b/acts_tests/tests/google/fuchsia/netstack/NetstackIfaceTest.py
@@ -33,7 +33,6 @@
"NetstackFuchsiaTest Init: Not enough fuchsia devices.")
self.log.info("Running testbed setup with one fuchsia devices")
self.dut = self.fuchsia_devices[0]
- self.dut.netstack_lib.init()
def _enable_all_interfaces(self):
interfaces = self.dut.netstack_lib.netstackListInterfaces()
@@ -76,44 +75,6 @@
self.log.info("Interfaces found: {}".format(interfaces.get('result')))
raise signals.TestPass("Success")
- def test_get_interface_by_id(self):
- """Tests getting interface information by id on all interfaces.
-
- Steps:
- 1. Call ListInterfaces FIDL api.
- 2. For each interface in the list, call GetInterfaceInfo FIDL api.
-
- Expected Result:
- There were no errors in each GetInterfaceInfo call.
-
- Returns:
- signals.TestPass if no errors
- signals.TestFailure if there are any errors during the test.
-
- TAGS: Netstack
- Priority: 1
- """
- interfaces = self.dut.netstack_lib.netstackListInterfaces()
- if interfaces.get('error') is not None:
- raise signals.TestFailure("Failed with {}".format(
- interfaces.get('error')))
- for item in interfaces.get("result"):
- identifier = item.get('id')
- interface_info_result = self.dut.netstack_lib.getInterfaceInfo(
- identifier)
- if interface_info_result.get('error') is not None:
- raise signals.TestFailure(
- "Get interfaces info failed with {}".format(
- interface_info_result.get('error')))
- else:
- result = interface_info_result.get('result')
- if result is None:
- raise signals.TestFailure(
- "Interface info returned None: {}".format(result))
- self.log.info("Interface {} info: {}".format(
- identifier, result))
- raise signals.TestPass("Success")
-
def test_toggle_wlan_interface(self):
"""Test toggling the wlan interface if it exists.
@@ -131,43 +92,60 @@
Returns:
signals.TestPass if no errors
signals.TestFailure if there are any errors during the test.
+ signals.TestSkip if there are no wlan interfaces.
TAGS: Netstack
Priority: 1
"""
- interfaces = self.dut.netstack_lib.netstackListInterfaces()
- for item in interfaces.get('result'):
- # Find the WLAN interface
- if "wlan" in item.get('name'):
- identifier = item.get('id')
- # Disable the interface by ID.
- result = self.dut.netstack_lib.disableInterface(identifier)
- if result.get('error') is not None:
- raise signals.TestFailure(
- "Unable to disable wlan interface: {}".format(
- result.get('error')))
- # Check the current state of the interface.
- interface_info_result = self.dut.netstack_lib.getInterfaceInfo(
- identifier)
- interface_info = interface_info_result.get('result')
+ def get_wlan_interfaces():
+ result = self.dut.netstack_lib.netstackListInterfaces()
+ if (error := result.get('error')):
+ raise signals.TestFailure(
+ f'unable to list interfaces: {error}')
+ return [
+ interface for interface in result.get('result')
+ if 'wlan' in interface.get('name')
+ ]
- if len(interface_info.get('ipv4_addresses')) > 0:
- raise signals.TestFailure(
- "No Ipv4 Address should be present: {}".format(
- interface_info))
+ def get_ids(interfaces):
+ return [get_id(interface) for interface in interfaces]
- # TODO (35981): Verify other values when interface down.
+ wlan_interfaces = get_wlan_interfaces()
+ if not wlan_interfaces:
+ raise signals.TestSkip('no wlan interface found')
+ interface_ids = get_ids(wlan_interfaces)
- # Re-enable the interface
- result = self.dut.netstack_lib.enableInterface(identifier)
- if result.get('error') is not None:
- raise signals.TestFailure(
- "Unable to enable wlan interface: {}".format(
- result.get('error')))
+ # Disable the interfaces.
+ for identifier in interface_ids:
+ result = self.dut.netstack_lib.disableInterface(identifier)
+ if (error := result.get('error')):
+ raise signals.TestFailure(
+ f'failed to disable wlan interface {identifier}: {error}')
- # TODO (35981): Verify other values when interface up.
+ # Retrieve the interfaces again.
+ disabled_wlan_interfaces = get_wlan_interfaces()
+ disabled_interface_ids = get_ids(wlan_interfaces)
- raise signals.TestPass("Success")
+ if not disabled_interface_ids == interface_ids:
+ raise signals.TestFailure(
+ f'disabled interface IDs do not match original interface IDs: original={interface_ids} disabled={disabled_interface_ids}'
+ )
- raise signals.TestSkip("No WLAN interface found.")
+ # Check the current state of the interfaces.
+ for interface in disabled_interfaces:
+ if len(interface_info.get('ipv4_addresses')) > 0:
+ raise signals.TestFailure(
+ f'no Ipv4 Address should be present: {interface}')
+
+ # TODO (35981): Verify other values when interface down.
+
+ # Re-enable the interfaces.
+ for identifier in disabled_interface_ids:
+ result = self.dut.netstack_lib.enableInterface(identifier)
+ if (error := result.get('error')):
+ raise signals.TestFailure(
+ f'failed to enable wlan interface {identifier}: {error}')
+
+ # TODO (35981): Verify other values when interface up.
+ raise signals.TestPass("Success")
diff --git a/acts_tests/tests/google/fuchsia/netstack/NetstackIxiaTest.py b/acts_tests/tests/google/fuchsia/netstack/NetstackIxiaTest.py
index 129d28f..260928e 100644
--- a/acts_tests/tests/google/fuchsia/netstack/NetstackIxiaTest.py
+++ b/acts_tests/tests/google/fuchsia/netstack/NetstackIxiaTest.py
@@ -165,5 +165,6 @@
access_point.remove_bridge(bridge_name='ixia_bridge0')
"""Tests"""
+
def test_do_nothing(self):
return True
diff --git a/acts_tests/tests/google/fuchsia/netstack/ToggleWlanInterfaceStressTest.py b/acts_tests/tests/google/fuchsia/netstack/ToggleWlanInterfaceStressTest.py
new file mode 100644
index 0000000..9b60998
--- /dev/null
+++ b/acts_tests/tests/google/fuchsia/netstack/ToggleWlanInterfaceStressTest.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - The Android secure 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 signals
+import time
+from acts.base_test import BaseTestClass
+from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device
+
+
+class ToggleWlanInterfaceStressTest(BaseTestClass):
+ def setup_class(self):
+ dut = self.user_params.get('dut', None)
+ if dut:
+ if dut == 'fuchsia_devices':
+ self.dut = create_wlan_device(self.fuchsia_devices[0])
+ elif dut == 'android_devices':
+ self.dut = create_wlan_device(self.android_devices[0])
+ else:
+ raise ValueError('Invalid DUT specified in config. (%s)' %
+ self.user_params['dut'])
+ else:
+ # Default is an Fuchsia device
+ self.dut = create_wlan_device(self.fuchsia_devices[0])
+
+ def test_iface_toggle_and_ping(self):
+ """Test that we don't error out when toggling WLAN interfaces.
+
+ Steps:
+ 1. Find a WLAN interface
+ 2. Destroy it
+ 3. Create a new WLAN interface
+ 4. Ping after association
+ 5. Repeat 1-4 1,000 times
+
+ Expected Result:
+ Verify there are no errors in destroying the wlan interface.
+
+ Returns:
+ signals.TestPass if no errors
+ signals.TestFailure if there are any errors during the test.
+
+ TAGS: WLAN, Stability
+ Priority: 1
+ """
+
+ # Test assumes you've already connected to some AP.
+
+ for i in range(1000):
+ wlan_interfaces = self.dut.get_wlan_interface_id_list()
+ print(wlan_interfaces)
+ if len(wlan_interfaces) < 1:
+ raise signals.TestFailure(
+ "Not enough wlan interfaces for test")
+ if not self.dut.destroy_wlan_interface(wlan_interfaces[0]):
+ raise signals.TestFailure("Failed to destroy WLAN interface")
+ # Really make sure it is dead
+ self.fuchsia_devices[0].send_command_ssh(
+ "wlan iface del {}".format(wlan_interfaces[0]))
+ # Grace period
+ time.sleep(2)
+ self.fuchsia_devices[0].send_command_ssh(
+ 'wlan iface new --phy 0 --role Client')
+ end_time = time.time() + 300
+ while time.time() < end_time:
+ time.sleep(1)
+ if self.dut.is_connected():
+ try:
+ ping_result = self.dut.ping("8.8.8.8", 10, 1000, 1000,
+ 25)
+ print(ping_result)
+ except Exception as err:
+ # TODO: Once we gain more stability, fail test when pinging fails
+ print("some err {}".format(err))
+ time.sleep(2) #give time for some traffic
+ break
+ if not self.dut.is_connected():
+ raise signals.TestFailure("Failed at iteration {}".format(i +
+ 1))
+ self.log.info("Iteration {} successful".format(i + 1))
+ raise signals.TestPass("Success")
diff --git a/acts_tests/tests/google/fuchsia/wlan/compliance/VapeInteropTest.py b/acts_tests/tests/google/fuchsia/wlan/compliance/VapeInteropTest.py
index 3cc7a74..962c1bf 100644
--- a/acts_tests/tests/google/fuchsia/wlan/compliance/VapeInteropTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/compliance/VapeInteropTest.py
@@ -32,6 +32,7 @@
* One Android or Fuchsia Device
* One Whirlwind Access Point
"""
+
def setup_class(self):
super().setup_class()
if 'dut' in self.user_params:
@@ -74,6 +75,7 @@
self.dut.turn_location_off_and_scan_toggle_off()
self.dut.disconnect()
self.dut.reset_wifi()
+ self.download_ap_logs()
self.access_point.stop_all_aps()
def on_fail(self, test_name, begin_time):
diff --git a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11ACTest.py b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11ACTest.py
index 47deadd..04adfab 100644
--- a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11ACTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11ACTest.py
@@ -115,6 +115,7 @@
* One Android device or Fuchsia device
* One Access Point
"""
+
def __init__(self, controllers):
WifiBaseTest.__init__(self, controllers)
self.tests = [
@@ -158,6 +159,7 @@
self.dut.turn_location_off_and_scan_toggle_off()
self.dut.disconnect()
self.dut.reset_wifi()
+ self.download_ap_logs()
self.access_point.stop_all_aps()
def on_fail(self, test_name, begin_time):
diff --git a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11NTest.py b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11NTest.py
index df5540f..ad0800f 100644
--- a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11NTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11NTest.py
@@ -70,6 +70,7 @@
* One Android device or Fuchsia device
* One Access Point
"""
+
def __init__(self, controllers):
WifiBaseTest.__init__(self, controllers)
self.tests = [
@@ -121,6 +122,7 @@
self.dut.turn_location_off_and_scan_toggle_off()
self.dut.disconnect()
self.dut.reset_wifi()
+ self.download_ap_logs()
self.access_point.stop_all_aps()
def on_fail(self, test_name, begin_time):
diff --git a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyComplianceABGTest.py b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyComplianceABGTest.py
index b3efacc..2d17f4b 100644
--- a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyComplianceABGTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyComplianceABGTest.py
@@ -32,6 +32,7 @@
* One Android device or Fuchsia device
* One Access Point
"""
+
def setup_class(self):
super().setup_class()
if 'dut' in self.user_params:
@@ -122,6 +123,7 @@
self.dut.turn_location_off_and_scan_toggle_off()
self.dut.disconnect()
self.dut.reset_wifi()
+ self.download_ap_logs()
self.access_point.stop_all_aps()
def on_fail(self, test_name, begin_time):
diff --git a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanSecurityComplianceABGTest.py b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanSecurityComplianceABGTest.py
index 3e72a51..a32c7c4 100644
--- a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanSecurityComplianceABGTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanSecurityComplianceABGTest.py
@@ -39,6 +39,7 @@
security_profile_generator: The function that generates the security
profile object
"""
+
@wraps(test_func)
def security_profile_generator(self, *args, **kwargs):
"""Function that looks at the name of the function and determines what
@@ -54,7 +55,7 @@
*args: args that were sent to the original test function
**kwargs: kwargs that were sent to the original test function
Returns:
- The original fuction that was called
+ The original function that was called
"""
utf8_password_2g = '2𝔤_𝔊𝔬𝔬𝔤𝔩𝔢'
utf8_password_2g_french = 'du Feÿ Château'
@@ -162,6 +163,7 @@
* One Android device or Fuchsia device
* One Access Point
"""
+
def setup_class(self):
super().setup_class()
if 'dut' in self.user_params:
@@ -199,6 +201,7 @@
self.dut.turn_location_off_and_scan_toggle_off()
self.dut.disconnect()
self.dut.reset_wifi()
+ self.download_ap_logs()
self.access_point.stop_all_aps()
def on_fail(self, test_name, begin_time):
@@ -1105,11 +1108,14 @@
password=self.client_password,
force_wmm=False)
- asserts.assert_true(
+ asserts.assert_false(
self.dut.associate(self.ssid,
target_security=self.target_security,
target_pwd=self.client_password),
- 'Failed to associate.')
+ 'Expected failure to associate. This device must support TKIP and '
+ 'PMF, which is not supported on Fuchsia. If this device is a '
+ 'mainstream device, we need to reconsider adding support for TKIP '
+ 'and PMF on Fuchsia.')
@create_security_profile
def test_associate_11a_pmf_sec_wpa2_psk_ptk_ccmp(self):
@@ -1156,11 +1162,14 @@
password=self.client_password,
force_wmm=False)
- asserts.assert_true(
+ asserts.assert_false(
self.dut.associate(self.ssid,
target_security=self.target_security,
target_pwd=self.client_password),
- 'Failed to associate.')
+ 'Expected failure to associate. This device must support TKIP and '
+ 'PMF, which is not supported on Fuchsia. If this device is a '
+ 'mainstream device, we need to reconsider adding support for TKIP '
+ 'and PMF on Fuchsia.')
@create_security_profile
def test_associate_11a_pmf_max_length_password_sec_wpa2_psk_ptk_ccmp(self):
@@ -1208,11 +1217,14 @@
password=self.client_password,
force_wmm=False)
- asserts.assert_true(
+ asserts.assert_false(
self.dut.associate(self.ssid,
target_security=self.target_security,
target_pwd=self.client_password),
- 'Failed to associate.')
+ 'Expected failure to associate. This device must support TKIP and '
+ 'PMF, which is not supported on Fuchsia. If this device is a '
+ 'mainstream device, we need to reconsider adding support for TKIP '
+ 'and PMF on Fuchsia.')
@create_security_profile
def test_associate_11a_pmf_max_length_psk_sec_wpa2_psk_ptk_ccmp(self):
@@ -1261,11 +1273,14 @@
frag_threshold=430,
force_wmm=False)
- asserts.assert_true(
+ asserts.assert_false(
self.dut.associate(self.ssid,
target_security=self.target_security,
target_pwd=self.client_password),
- 'Failed to associate.')
+ 'Expected failure to associate. This device must support TKIP and '
+ 'PMF, which is not supported on Fuchsia. If this device is a '
+ 'mainstream device, we need to reconsider adding support for TKIP '
+ 'and PMF on Fuchsia.')
@create_security_profile
def test_associate_11a_pmf_frag_430_sec_wpa2_psk_ptk_ccmp(self):
@@ -1315,11 +1330,14 @@
rts_threshold=256,
force_wmm=False)
- asserts.assert_true(
+ asserts.assert_false(
self.dut.associate(self.ssid,
target_security=self.target_security,
target_pwd=self.client_password),
- 'Failed to associate.')
+ 'Expected failure to associate. This device must support TKIP and '
+ 'PMF, which is not supported on Fuchsia. If this device is a '
+ 'mainstream device, we need to reconsider adding support for TKIP '
+ 'and PMF on Fuchsia.')
@create_security_profile
def test_associate_11a_pmf_rts_256_sec_wpa2_psk_ptk_ccmp(self):
@@ -4133,11 +4151,14 @@
password=self.client_password,
force_wmm=False)
- asserts.assert_true(
+ asserts.assert_false(
self.dut.associate(self.ssid,
target_security=self.target_security,
target_pwd=self.client_password),
- 'Failed to associate.')
+ 'Expected failure to associate. This device must support TKIP and '
+ 'PMF, which is not supported on Fuchsia. If this device is a '
+ 'mainstream device, we need to reconsider adding support for TKIP '
+ 'and PMF on Fuchsia.')
@create_security_profile
def test_associate_11bg_pmf_sec_wpa2_psk_ptk_ccmp(self):
@@ -4185,11 +4206,14 @@
password=self.client_password,
force_wmm=False)
- asserts.assert_true(
+ asserts.assert_false(
self.dut.associate(self.ssid,
target_security=self.target_security,
target_pwd=self.client_password),
- 'Failed to associate.')
+ 'Expected failure to associate. This device must support TKIP and '
+ 'PMF, which is not supported on Fuchsia. If this device is a '
+ 'mainstream device, we need to reconsider adding support for TKIP '
+ 'and PMF on Fuchsia.')
@create_security_profile
def test_associate_11bg_pmf_max_length_password_sec_wpa2_psk_ptk_ccmp(
@@ -4238,11 +4262,14 @@
password=self.client_password,
force_wmm=False)
- asserts.assert_true(
+ asserts.assert_false(
self.dut.associate(self.ssid,
target_security=self.target_security,
target_pwd=self.client_password),
- 'Failed to associate.')
+ 'Expected failure to associate. This device must support TKIP and '
+ 'PMF, which is not supported on Fuchsia. If this device is a '
+ 'mainstream device, we need to reconsider adding support for TKIP '
+ 'and PMF on Fuchsia.')
@create_security_profile
def test_associate_11bg_pmf_max_length_psk_sec_wpa2_psk_ptk_ccmp(self):
@@ -4291,11 +4318,14 @@
frag_threshold=430,
force_wmm=False)
- asserts.assert_true(
+ asserts.assert_false(
self.dut.associate(self.ssid,
target_security=self.target_security,
target_pwd=self.client_password),
- 'Failed to associate.')
+ 'Expected failure to associate. This device must support TKIP and '
+ 'PMF, which is not supported on Fuchsia. If this device is a '
+ 'mainstream device, we need to reconsider adding support for TKIP '
+ 'and PMF on Fuchsia.')
@create_security_profile
def test_associate_11bg_pmf_frag_430_sec_wpa2_psk_ptk_ccmp(self):
@@ -4345,11 +4375,14 @@
rts_threshold=256,
force_wmm=False)
- asserts.assert_true(
+ asserts.assert_false(
self.dut.associate(self.ssid,
target_security=self.target_security,
target_pwd=self.client_password),
- 'Failed to associate.')
+ 'Expected failure to associate. This device must support TKIP and '
+ 'PMF, which is not supported on Fuchsia. If this device is a '
+ 'mainstream device, we need to reconsider adding support for TKIP '
+ 'and PMF on Fuchsia.')
@create_security_profile
def test_associate_11bg_pmf_rts_256_sec_wpa2_psk_ptk_ccmp(self):
diff --git a/acts_tests/tests/google/fuchsia/wlan/facade/WlanDeprecatedConfigurationTest.py b/acts_tests/tests/google/fuchsia/wlan/facade/WlanDeprecatedConfigurationTest.py
index 574a9c9..44e6731 100644
--- a/acts_tests/tests/google/fuchsia/wlan/facade/WlanDeprecatedConfigurationTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/facade/WlanDeprecatedConfigurationTest.py
@@ -14,9 +14,10 @@
# License for the specific language governing permissions and limitations under
# the License.
-from acts.base_test import BaseTestClass
from acts import asserts
from acts import utils
+from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
+from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device
AP_ROLE = 'Ap'
DEFAULT_SSID = 'testssid'
@@ -28,11 +29,11 @@
TEST_MAC_ADDR_SECONDARY = 'bc:9a:78:56:34:12'
-class WlanDeprecatedConfigurationTest(BaseTestClass):
+class WlanDeprecatedConfigurationTest(AbstractDeviceWlanDeviceBaseTest):
"""Tests for WlanDeprecatedConfigurationFacade"""
def setup_class(self):
super().setup_class()
- self.dut = self.fuchsia_devices[0]
+ self.dut = create_wlan_device(self.fuchsia_devices[0])
def setup_test(self):
self._stop_soft_aps()
@@ -40,20 +41,6 @@
def teardown_test(self):
self._stop_soft_aps()
- def on_fail(self, test_name, begin_time):
- for fd in self.fuchsia_devices:
- try:
- fd.take_bug_report(test_name, begin_time)
- fd.get_log(test_name, begin_time)
- except Exception:
- pass
-
- try:
- if fd.device.hard_reboot_on_fail:
- fd.hard_power_cycle(self.pdu_devices)
- except AttributeError:
- pass
-
def _get_ap_interface_mac_address(self):
"""Retrieves mac address from wlan interface with role ap
@@ -64,13 +51,14 @@
ConnectionError, if SL4F calls fail
AttributeError, if no interface has role 'Ap'
"""
- wlan_ifaces = self.dut.wlan_lib.wlanGetIfaceIdList()
+ wlan_ifaces = self.dut.device.wlan_lib.wlanGetIfaceIdList()
if wlan_ifaces.get('error'):
raise ConnectionError('Failed to get wlan interface IDs: %s' %
wlan_ifaces['error'])
for wlan_iface in wlan_ifaces['result']:
- iface_info = self.dut.wlan_lib.wlanQueryInterface(wlan_iface)
+ iface_info = self.dut.device.wlan_lib.wlanQueryInterface(
+ wlan_iface)
if iface_info.get('error'):
raise ConnectionError('Failed to query wlan iface: %s' %
iface_info['error'])
@@ -87,8 +75,9 @@
Raises:
ConnectionError, if SL4F call fails.
"""
- self.log.info('Starting SoftAP on Fuchsia device (%s).' % self.dut.ip)
- response = self.dut.wlan_ap_policy_lib.wlanStartAccessPoint(
+ self.log.info('Starting SoftAP on Fuchsia device (%s).' %
+ self.dut.device.ip)
+ response = self.dut.device.wlan_ap_policy_lib.wlanStartAccessPoint(
DEFAULT_SSID, DEFAULT_SECURITY, DEFAULT_PASSWORD,
DEFAULT_CONNECTIVITY_MODE, DEFAULT_OPERATING_BAND)
if response.get('error'):
@@ -102,7 +91,7 @@
ConnectionError, if SL4F call fails.
"""
self.log.info('Stopping SoftAP.')
- response = self.dut.wlan_ap_policy_lib.wlanStopAllAccessPoint()
+ response = self.dut.device.wlan_ap_policy_lib.wlanStopAllAccessPoint()
if response.get('error'):
raise ConnectionError('Failed to stop SoftAP: %s' %
response['error'])
@@ -118,8 +107,8 @@
self.log.info(
'Suggesting AP mac addr (%s) via wlan_deprecated_configuration_lib.'
% mac_addr)
- response = self.dut.wlan_deprecated_configuration_lib.wlanSuggestAccessPointMacAddress(
- mac_addr)
+ response = (self.dut.device.wlan_deprecated_configuration_lib.
+ wlanSuggestAccessPointMacAddress(mac_addr))
if response.get('error'):
asserts.fail('Failed to suggest AP mac address (%s): %s' %
(mac_addr, response['error']))
diff --git a/acts_tests/tests/google/fuchsia/wlan/facade/WlanFacadeTest.py b/acts_tests/tests/google/fuchsia/wlan/facade/WlanFacadeTest.py
index ffe86fa..9f884b6 100644
--- a/acts_tests/tests/google/fuchsia/wlan/facade/WlanFacadeTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/facade/WlanFacadeTest.py
@@ -17,34 +17,24 @@
Script for verifying that we can invoke methods of the WlanFacade.
"""
-from acts.base_test import BaseTestClass
+import array
+
from acts import asserts, signals
+from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
+from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device
-class WlanFacadeTest(BaseTestClass):
+class WlanFacadeTest(AbstractDeviceWlanDeviceBaseTest):
def setup_class(self):
super().setup_class()
if len(self.fuchsia_devices) < 1:
raise signals.TestAbortClass(
"Sorry, please try verifying FuchsiaDevice is in your "
"config file and try again.")
-
- def on_fail(self, test_name, begin_time):
- for fd in self.fuchsia_devices:
- try:
- fd.take_bug_report(test_name, begin_time)
- fd.get_log(test_name, begin_time)
- except Exception:
- pass
-
- try:
- if fd.device.hard_reboot_on_fail:
- fd.hard_power_cycle(self.pdu_devices)
- except AttributeError:
- pass
+ self.dut = create_wlan_device(self.fuchsia_devices[0])
def test_get_phy_id_list(self):
- result = self.fuchsia_devices[0].wlan_lib.wlanPhyIdList()
+ result = self.dut.device.wlan_lib.wlanPhyIdList()
error = result['error']
asserts.assert_true(error is None, error)
@@ -52,7 +42,7 @@
return True
def test_get_country(self):
- wlan_lib = self.fuchsia_devices[0].wlan_lib
+ wlan_lib = self.dut.device.wlan_lib
result = wlan_lib.wlanPhyIdList()
error = result['error']
@@ -68,3 +58,19 @@
encoding='us-ascii')
self.log.info('Got country %s (%s)', country_string, country_bytes)
return True
+
+ def test_get_dev_path(self):
+ wlan_lib = self.dut.device.wlan_lib
+
+ result = wlan_lib.wlanPhyIdList()
+ error = result['error']
+ asserts.assert_true(error is None, error)
+ phy_id = result['result'][0]
+
+ result = wlan_lib.wlanGetDevPath(phy_id)
+ error = result['error']
+ asserts.assert_true(error is None, error)
+
+ dev_path = result['result']
+ self.log.info('Got device path: %s', dev_path)
+ return True
diff --git a/acts_tests/tests/google/fuchsia/wlan/facade/WlanStatusTest.py b/acts_tests/tests/google/fuchsia/wlan/facade/WlanStatusTest.py
index 0228940..10344b2 100644
--- a/acts_tests/tests/google/fuchsia/wlan/facade/WlanStatusTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/facade/WlanStatusTest.py
@@ -18,10 +18,10 @@
"""
from acts import signals
-from acts.base_test import BaseTestClass
+from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
-class WlanStatusTest(BaseTestClass):
+class WlanStatusTest(AbstractDeviceWlanDeviceBaseTest):
"""WLAN status test class.
Test Bed Requirements:
@@ -35,19 +35,9 @@
def on_fail(self, test_name, begin_time):
for fd in self.fuchsia_devices:
- try:
- fd.take_bug_report(test_name, begin_time)
- fd.get_log(test_name, begin_time)
- except Exception:
- pass
-
- try:
- if fd.device.hard_reboot_on_fail:
- fd.hard_power_cycle(self.pdu_devices)
- fd.configure_wlan(association_mechanism='policy',
- preserve_saved_networks=True)
- except AttributeError:
- pass
+ super().on_device_fail(fd, test_name, begin_time)
+ fd.configure_wlan(association_mechanism='policy',
+ preserve_saved_networks=True)
def test_wlan_stopped_client_status(self):
"""Queries WLAN status on DUTs with no WLAN ifaces.
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/BeaconLossTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/BeaconLossTest.py
index aaef98f..a2a763b 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/BeaconLossTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/BeaconLossTest.py
@@ -29,7 +29,6 @@
from acts import asserts
from acts import signals
from acts import utils
-from acts.base_test import BaseTestClass
from acts.controllers.access_point import setup_ap
from acts.controllers.ap_lib import hostapd_constants
@@ -71,7 +70,7 @@
else:
# Default is an android device, just like the other tests
self.dut = create_wlan_device(self.android_devices[0])
- self.ap = self.access_points[0]
+ self.access_point = self.access_points[0]
self.num_of_iterations = int(
self.user_params.get("beacon_loss_test_iterations",
self.num_of_iterations))
@@ -81,23 +80,25 @@
self.dut.disconnect()
self.dut.reset_wifi()
# ensure radio is on, in case the test failed while the radio was off
- self.ap.iwconfig.ap_iwconfig(self.in_use_interface, "txpower on")
- self.ap.stop_all_aps()
+ self.access_point.iwconfig.ap_iwconfig(self.in_use_interface,
+ "txpower on")
+ self.download_ap_logs()
+ self.access_point.stop_all_aps()
def on_fail(self, test_name, begin_time):
super().on_fail(test_name, begin_time)
- self.ap.stop_all_aps()
+ self.access_point.stop_all_aps()
def beacon_loss(self, channel):
- setup_ap(access_point=self.ap,
+ setup_ap(access_point=self.access_point,
profile_name='whirlwind',
channel=channel,
ssid=self.ssid)
time.sleep(self.wait_ap_startup_s)
if channel > 14:
- self.in_use_interface = self.ap.wlan_5g
+ self.in_use_interface = self.access_point.wlan_5g
else:
- self.in_use_interface = self.ap.wlan_2g
+ self.in_use_interface = self.access_point.wlan_2g
# TODO(b/144505723): [ACTS] update BeaconLossTest.py to handle client
# roaming, saved networks, etc.
@@ -111,7 +112,8 @@
for _ in range(0, self.num_of_iterations):
# Turn off AP radio
self.log.info("turning off radio")
- self.ap.iwconfig.ap_iwconfig(self.in_use_interface, "txpower off")
+ self.access_point.iwconfig.ap_iwconfig(self.in_use_interface,
+ "txpower off")
time.sleep(self.wait_after_ap_txoff_s)
# Did we disconnect from AP?
@@ -120,7 +122,8 @@
# Turn on AP radio
self.log.info("turning on radio")
- self.ap.iwconfig.ap_iwconfig(self.in_use_interface, "txpower on")
+ self.access_point.iwconfig.ap_iwconfig(self.in_use_interface,
+ "txpower on")
time.sleep(self.wait_to_connect_after_ap_txon_s)
# Tell the client to connect
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/ChannelSwitchTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/ChannelSwitchTest.py
new file mode 100644
index 0000000..be8e3ca
--- /dev/null
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/ChannelSwitchTest.py
@@ -0,0 +1,378 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 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.
+"""
+Tests STA handling of channel switch announcements.
+"""
+
+import random
+import time
+
+from acts import asserts
+from acts.controllers.access_point import setup_ap
+from acts.controllers.ap_lib import hostapd_constants
+from acts.utils import rand_ascii_str
+from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device
+from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
+from typing import Sequence
+
+
+class ChannelSwitchTest(AbstractDeviceWlanDeviceBaseTest):
+ # Time to wait between issuing channel switches
+ WAIT_BETWEEN_CHANNEL_SWITCHES_S = 15
+
+ # For operating class 115 tests.
+ GLOBAL_OPERATING_CLASS_115_CHANNELS = [36, 40, 44, 48]
+ # A channel outside the operating class.
+ NON_GLOBAL_OPERATING_CLASS_115_CHANNEL = 52
+
+ # For operating class 124 tests.
+ GLOBAL_OPERATING_CLASS_124_CHANNELS = [149, 153, 157, 161]
+ # A channel outside the operating class.
+ NON_GLOBAL_OPERATING_CLASS_124_CHANNEL = 52
+
+ def setup_class(self) -> None:
+ super().setup_class()
+ self.ssid = rand_ascii_str(10)
+ if 'dut' in self.user_params:
+ if self.user_params['dut'] == 'fuchsia_devices':
+ self.dut = create_wlan_device(self.fuchsia_devices[0])
+ elif self.user_params['dut'] == 'android_devices':
+ self.dut = create_wlan_device(self.android_devices[0])
+ else:
+ raise ValueError('Invalid DUT specified in config. (%s)' %
+ self.user_params['dut'])
+ else:
+ # Default is an android device, just like the other tests
+ self.dut = create_wlan_device(self.android_devices[0])
+ self.access_point = self.access_points[0]
+ self._stop_all_soft_aps()
+ self.in_use_interface = None
+
+ def teardown_test(self) -> None:
+ self.dut.disconnect()
+ self.dut.reset_wifi()
+ self.download_ap_logs()
+ self.access_point.stop_all_aps()
+
+ # TODO(fxbug.dev/85738): Change band type to an enum.
+ def channel_switch(self,
+ band: str,
+ starting_channel: int,
+ channel_switches: Sequence[int],
+ test_with_soft_ap: bool = False) -> None:
+ """Setup and run a channel switch test with the given parameters.
+
+ Creates an AP, associates to it, and then issues channel switches
+ through the provided channels. After each channel switch, the test
+ checks that the DUT is connected for a period of time before considering
+ the channel switch successful. If directed to start a SoftAP, the test
+ will also check that the SoftAP is on the expected channel after each
+ channel switch.
+
+ Args:
+ band: band that AP will use, must be a valid band (e.g.
+ hostapd_constants.BAND_2G)
+ starting_channel: channel number that AP will use at startup
+ channel_switches: ordered list of channels that the test will
+ attempt to switch to
+ test_with_soft_ap: whether to start a SoftAP before beginning the
+ channel switches (default is False); note that if a SoftAP is
+ started, the test will also check that the SoftAP handles
+ channel switches correctly
+ """
+ asserts.assert_true(
+ band in [hostapd_constants.BAND_2G, hostapd_constants.BAND_5G],
+ 'Failed to setup AP, invalid band {}'.format(band))
+
+ self.current_channel_num = starting_channel
+ if band == hostapd_constants.BAND_5G:
+ self.in_use_interface = self.access_point.wlan_5g
+ elif band == hostapd_constants.BAND_2G:
+ self.in_use_interface = self.access_point.wlan_2g
+ asserts.assert_true(
+ self._channels_valid_for_band([self.current_channel_num], band),
+ 'starting channel {} not a valid channel for band {}'.format(
+ self.current_channel_num, band))
+
+ setup_ap(access_point=self.access_point,
+ profile_name='whirlwind',
+ channel=self.current_channel_num,
+ ssid=self.ssid)
+ if test_with_soft_ap:
+ self._start_soft_ap()
+ self.log.info('sending associate command for ssid %s', self.ssid)
+ self.dut.associate(target_ssid=self.ssid)
+ asserts.assert_true(self.dut.is_connected(), 'Failed to connect.')
+
+ asserts.assert_true(channel_switches,
+ 'Cannot run test, no channels to switch to')
+ asserts.assert_true(
+ self._channels_valid_for_band(channel_switches, band),
+ 'channel_switches {} includes invalid channels for band {}'.format(
+ channel_switches, band))
+
+ for channel_num in channel_switches:
+ if channel_num == self.current_channel_num:
+ continue
+ self.log.info('channel switch: {} -> {}'.format(
+ self.current_channel_num, channel_num))
+ self.access_point.channel_switch(self.in_use_interface,
+ channel_num)
+ channel_num_after_switch = self.access_point.get_current_channel(
+ self.in_use_interface)
+ asserts.assert_true(channel_num_after_switch == channel_num,
+ 'AP failed to channel switch')
+ self.current_channel_num = channel_num
+
+ # Check periodically to see if DUT stays connected. Sometimes
+ # CSA-induced disconnects occur seconds after last channel switch.
+ for _ in range(self.WAIT_BETWEEN_CHANNEL_SWITCHES_S):
+ asserts.assert_true(
+ self.dut.is_connected(),
+ 'Failed to stay connected after channel switch.')
+ client_channel = self._client_channel()
+ asserts.assert_equal(
+ client_channel, channel_num,
+ 'Client interface on wrong channel ({})'.format(
+ client_channel))
+ if test_with_soft_ap:
+ soft_ap_channel = self._soft_ap_channel()
+ asserts.assert_equal(
+ soft_ap_channel, channel_num,
+ 'SoftAP interface on wrong channel ({})'.format(
+ soft_ap_channel))
+ time.sleep(1)
+
+ def test_channel_switch_2g(self) -> None:
+ """Channel switch through all (US only) channels in the 2 GHz band."""
+ self.channel_switch(
+ band=hostapd_constants.BAND_2G,
+ starting_channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G,
+ channel_switches=hostapd_constants.US_CHANNELS_2G)
+
+ def test_channel_switch_2g_with_soft_ap(self) -> None:
+ """Channel switch through (US only) 2 Ghz channels with SoftAP up."""
+ self.channel_switch(
+ band=hostapd_constants.BAND_2G,
+ starting_channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G,
+ channel_switches=hostapd_constants.US_CHANNELS_2G,
+ test_with_soft_ap=True)
+
+ def test_channel_switch_2g_shuffled_with_soft_ap(self) -> None:
+ """Switch through shuffled (US only) 2 Ghz channels with SoftAP up."""
+ channels = hostapd_constants.US_CHANNELS_2G
+ random.shuffle(channels)
+ self.log.info('Shuffled channel switch sequence: {}'.format(channels))
+ self.channel_switch(
+ band=hostapd_constants.BAND_2G,
+ starting_channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G,
+ channel_switches=channels,
+ test_with_soft_ap=True)
+
+ # TODO(fxbug.dev/84777): This test fails.
+ def test_channel_switch_5g(self) -> None:
+ """Channel switch through all (US only) channels in the 5 GHz band."""
+ self.channel_switch(
+ band=hostapd_constants.BAND_5G,
+ starting_channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G,
+ channel_switches=hostapd_constants.US_CHANNELS_5G)
+
+ # TODO(fxbug.dev/84777): This test fails.
+ def test_channel_switch_5g_with_soft_ap(self) -> None:
+ """Channel switch through (US only) 5 GHz channels with SoftAP up."""
+ self.channel_switch(
+ band=hostapd_constants.BAND_5G,
+ starting_channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G,
+ channel_switches=hostapd_constants.US_CHANNELS_5G,
+ test_with_soft_ap=True)
+
+ def test_channel_switch_5g_shuffled_with_soft_ap(self) -> None:
+ """Switch through shuffled (US only) 5 Ghz channels with SoftAP up."""
+ channels = hostapd_constants.US_CHANNELS_5G
+ random.shuffle(channels)
+ self.log.info('Shuffled channel switch sequence: {}'.format(channels))
+ self.channel_switch(
+ band=hostapd_constants.BAND_5G,
+ starting_channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G,
+ channel_switches=channels,
+ test_with_soft_ap=True)
+
+ # TODO(fxbug.dev/84777): This test fails.
+ def test_channel_switch_regression_global_operating_class_115(
+ self) -> None:
+ """Channel switch into, through, and out of global op. class 115 channels.
+
+ Global operating class 115 is described in IEEE 802.11-2016 Table E-4.
+ Regression test for fxbug.dev/84777.
+ """
+ channels = self.GLOBAL_OPERATING_CLASS_115_CHANNELS + [
+ self.NON_GLOBAL_OPERATING_CLASS_115_CHANNEL
+ ]
+ self.channel_switch(
+ band=hostapd_constants.BAND_5G,
+ starting_channel=self.NON_GLOBAL_OPERATING_CLASS_115_CHANNEL,
+ channel_switches=channels)
+
+ # TODO(fxbug.dev/84777): This test fails.
+ def test_channel_switch_regression_global_operating_class_115_with_soft_ap(
+ self) -> None:
+ """Test global operating class 124 channel switches, with SoftAP.
+
+ Regression test for fxbug.dev/84777.
+ """
+ channels = self.GLOBAL_OPERATING_CLASS_115_CHANNELS + [
+ self.NON_GLOBAL_OPERATING_CLASS_115_CHANNEL
+ ]
+ self.channel_switch(
+ band=hostapd_constants.BAND_5G,
+ starting_channel=self.NON_GLOBAL_OPERATING_CLASS_115_CHANNEL,
+ channel_switches=channels,
+ test_with_soft_ap=True)
+
+ # TODO(fxbug.dev/84777): This test fails.
+ def test_channel_switch_regression_global_operating_class_124(
+ self) -> None:
+ """Switch into, through, and out of global op. class 124 channels.
+
+ Global operating class 124 is described in IEEE 802.11-2016 Table E-4.
+ Regression test for fxbug.dev/64279.
+ """
+ channels = self.GLOBAL_OPERATING_CLASS_124_CHANNELS + [
+ self.NON_GLOBAL_OPERATING_CLASS_124_CHANNEL
+ ]
+ self.channel_switch(
+ band=hostapd_constants.BAND_5G,
+ starting_channel=self.NON_GLOBAL_OPERATING_CLASS_124_CHANNEL,
+ channel_switches=channels)
+
+ # TODO(fxbug.dev/84777): This test fails.
+ def test_channel_switch_regression_global_operating_class_124_with_soft_ap(
+ self) -> None:
+ """Test global operating class 124 channel switches, with SoftAP.
+
+ Regression test for fxbug.dev/64279.
+ """
+ channels = self.GLOBAL_OPERATING_CLASS_124_CHANNELS + [
+ self.NON_GLOBAL_OPERATING_CLASS_124_CHANNEL
+ ]
+ self.channel_switch(
+ band=hostapd_constants.BAND_5G,
+ starting_channel=self.NON_GLOBAL_OPERATING_CLASS_124_CHANNEL,
+ channel_switches=channels,
+ test_with_soft_ap=True)
+
+ def _channels_valid_for_band(self, channels: Sequence[int],
+ band: str) -> bool:
+ """Determine if the channels are valid for the band (US only).
+
+ Args:
+ channels: channel numbers
+ band: a valid band (e.g. hostapd_constants.BAND_2G)
+ """
+ if band == hostapd_constants.BAND_2G:
+ band_channels = frozenset(hostapd_constants.US_CHANNELS_2G)
+ elif band == hostapd_constants.BAND_5G:
+ band_channels = frozenset(hostapd_constants.US_CHANNELS_5G)
+ else:
+ asserts.fail('Invalid band {}'.format(band))
+ channels_set = frozenset(channels)
+ if channels_set <= band_channels:
+ return True
+ return False
+
+ def _start_soft_ap(self) -> None:
+ """Start a SoftAP on the DUT.
+
+ Raises:
+ EnvironmentError: if the SoftAP does not start
+ """
+ ssid = rand_ascii_str(10)
+ security_type = 'none'
+ password = ''
+ connectivity_mode = 'local_only'
+ operating_band = 'any'
+
+ self.log.info('Starting SoftAP on DUT')
+
+ response = self.dut.device.wlan_ap_policy_lib.wlanStartAccessPoint(
+ ssid, security_type, password, connectivity_mode, operating_band)
+ if response.get('error'):
+ raise EnvironmentError('SL4F: Failed to setup SoftAP. Err: %s' %
+ response['error'])
+ self.log.info('SoftAp network (%s) is up.' % ssid)
+
+ def _stop_all_soft_aps(self) -> None:
+ """Stops all SoftAPs on Fuchsia Device.
+
+ Raises:
+ EnvironmentError: if SoftAP stop call fails
+ """
+ response = self.dut.device.wlan_ap_policy_lib.wlanStopAllAccessPoint()
+ if response.get('error'):
+ raise EnvironmentError(
+ 'SL4F: Failed to stop all SoftAPs. Err: %s' %
+ response['error'])
+
+ def _client_channel(self) -> int:
+ """Determine the channel of the DUT client interface.
+
+ If the interface is not connected, the method will assert a test
+ failure.
+
+ Returns: channel number
+
+ Raises:
+ EnvironmentError: if client interface channel cannot be
+ determined
+ """
+ status = self.dut.status()
+ if status['error']:
+ raise EnvironmentError('Could not determine client channel')
+
+ result = status['result']
+ if isinstance(result, dict):
+ if result.get('Connected'):
+ return result['Connected']['channel']['primary']
+ asserts.fail('Client interface not connected')
+ raise EnvironmentError('Could not determine client channel')
+
+ def _soft_ap_channel(self) -> int:
+ """Determine the channel of the DUT SoftAP interface.
+
+ If the interface is not connected, the method will assert a test
+ failure.
+
+ Returns: channel number
+
+ Raises:
+ EnvironmentError: if SoftAP interface channel cannot be determined.
+ """
+ iface_ids = self.dut.get_wlan_interface_id_list()
+ for iface_id in iface_ids:
+ query = self.dut.device.wlan_lib.wlanQueryInterface(iface_id)
+ if query['error']:
+ continue
+ query_result = query['result']
+ if type(query_result) is dict and query_result.get('role') == 'Ap':
+ status = self.dut.device.wlan_lib.wlanStatus(iface_id)
+ if status['error']:
+ continue
+ status_result = status['result']
+ if isinstance(status_result, dict):
+ if status_result.get('Connected'):
+ return status_result['Connected']['channel']['primary']
+ asserts.fail('SoftAP interface not connected')
+ raise EnvironmentError('Could not determine SoftAP channel')
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/ConnectionStressTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/ConnectionStressTest.py
index 20e187d..64fc144 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/ConnectionStressTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/ConnectionStressTest.py
@@ -17,7 +17,6 @@
Script for testing WiFi connection and disconnection in a loop
"""
-from acts.base_test import BaseTestClass
import os
import uuid
@@ -47,7 +46,7 @@
self.ssid = rand_ascii_str(10)
self.fd = self.fuchsia_devices[0]
self.dut = create_wlan_device(self.fd)
- self.ap = self.access_points[0]
+ self.access_point = self.access_points[0]
self.num_of_iterations = int(
self.user_params.get("connection_stress_test_iterations",
self.num_of_iterations))
@@ -55,11 +54,12 @@
def teardown_test(self):
self.dut.reset_wifi()
- self.ap.stop_all_aps()
+ self.download_ap_logs()
+ self.access_point.stop_all_aps()
def on_fail(self, test_name, begin_time):
super().on_fail(test_name, begin_time)
- self.ap.stop_all_aps()
+ self.access_point.stop_all_aps()
def start_ap(self, profile, channel, security=None):
"""Starts an Access Point
@@ -69,7 +69,7 @@
channel: Channel to operate on
"""
self.log.info('Profile: %s, Channel: %d' % (profile, channel))
- setup_ap(access_point=self.ap,
+ setup_ap(access_point=self.access_point,
profile_name=profile,
channel=channel,
ssid=self.ssid,
@@ -132,7 +132,7 @@
time.sleep(1)
# Stop AP
- self.ap.stop_all_aps()
+ self.access_point.stop_all_aps()
if failed:
raise signals.TestFailure(
'One or more association attempt failed.')
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/DownloadStressTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/DownloadStressTest.py
index df83af3..5ec6290 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/DownloadStressTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/DownloadStressTest.py
@@ -21,17 +21,17 @@
import threading
import uuid
-from acts.base_test import BaseTestClass
from acts import signals
from acts.controllers.access_point import setup_ap
from acts.controllers.ap_lib import hostapd_constants
from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device
+from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
from acts_contrib.test_utils.fuchsia import utils
from acts_contrib.test_utils.tel.tel_test_utils import setup_droid_properties
from acts.utils import rand_ascii_str
-class DownloadStressTest(BaseTestClass):
+class DownloadStressTest(AbstractDeviceWlanDeviceBaseTest):
# Default number of test iterations here.
# Override using parameter in config file.
# Eg: "download_stress_test_iterations": "10"
@@ -55,24 +55,24 @@
def setup_class(self):
super().setup_class()
self.ssid = rand_ascii_str(10)
- self.fd = self.fuchsia_devices[0]
- self.wlan_device = create_wlan_device(self.fd)
- self.ap = self.access_points[0]
+ self.dut = create_wlan_device(self.fuchsia_devices[0])
+ self.access_point = self.access_points[0]
self.num_of_iterations = int(
self.user_params.get("download_stress_test_iterations",
self.num_of_iterations))
- setup_ap(access_point=self.ap,
+ setup_ap(access_point=self.access_point,
profile_name='whirlwind',
channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G,
ssid=self.ssid)
- self.wlan_device.associate(self.ssid)
+ self.dut.associate(self.ssid)
def teardown_test(self):
self.download_threads_result.clear()
- self.wlan_device.disconnect()
- self.wlan_device.reset_wifi()
- self.ap.stop_all_aps()
+ self.dut.disconnect()
+ self.dut.reset_wifi()
+ self.download_ap_logs()
+ self.access_point.stop_all_aps()
def test_download_small(self):
self.log.info("Downloading small file")
@@ -90,7 +90,7 @@
def download_file(self, url):
self.log.info("Start downloading: %s" % url)
return utils.http_file_download_by_curl(
- self.fd,
+ self.dut.device,
url,
additional_args='--max-time %d --silent' % self.download_timeout_s)
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/PingStressTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/PingStressTest.py
index 8c31e65..5f8addc 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/PingStressTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/PingStressTest.py
@@ -17,7 +17,6 @@
Script for exercising various ping scenarios
"""
-from acts.base_test import BaseTestClass
import os
import threading
@@ -27,12 +26,13 @@
from acts.controllers.access_point import setup_ap
from acts.controllers.ap_lib import hostapd_constants
from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device
+from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
from acts_contrib.test_utils.tel.tel_test_utils import setup_droid_properties
from acts_contrib.test_utils.fuchsia import utils
from acts.utils import rand_ascii_str
-class PingStressTest(BaseTestClass):
+class PingStressTest(AbstractDeviceWlanDeviceBaseTest):
# Timeout for ping thread in seconds
ping_thread_timeout_s = 60 * 5
@@ -47,20 +47,20 @@
super().setup_class()
self.ssid = rand_ascii_str(10)
- self.fd = self.fuchsia_devices[0]
- self.wlan_device = create_wlan_device(self.fd)
- self.ap = self.access_points[0]
- setup_ap(access_point=self.ap,
+ self.dut = create_wlan_device(self.fuchsia_devices[0])
+ self.access_point = self.access_points[0]
+ setup_ap(access_point=self.access_point,
profile_name='whirlwind',
channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G,
ssid=self.ssid,
setup_bridge=True)
- self.wlan_device.associate(self.ssid)
+ self.dut.associate(self.ssid)
def teardown_class(self):
- self.wlan_device.disconnect()
- self.wlan_device.reset_wifi()
- self.ap.stop_all_aps()
+ self.dut.disconnect()
+ self.dut.reset_wifi()
+ self.download_ap_logs()
+ self.access_point.stop_all_aps()
def send_ping(self,
dest_ip,
@@ -69,8 +69,8 @@
timeout=1000,
size=25):
self.log.info('Attempting to ping %s...' % dest_ip)
- ping_result = self.wlan_device.can_ping(dest_ip, count, interval,
- timeout, size)
+ ping_result = self.dut.can_ping(dest_ip, count, interval, timeout,
+ size)
if ping_result:
self.log.info('Ping was successful.')
else:
@@ -83,7 +83,7 @@
def ping_thread(self, dest_ip):
self.log.info('Attempting to ping %s...' % dest_ip)
- ping_result = self.wlan_device.can_ping(dest_ip, count=10, size=50)
+ ping_result = self.dut.can_ping(dest_ip, count=10, size=50)
if ping_result:
self.log.info('Success pinging: %s' % dest_ip)
else:
@@ -98,7 +98,7 @@
return self.send_ping('127.0.0.1')
def test_ping_AP(self):
- return self.send_ping(self.ap.ssh_settings.hostname)
+ return self.send_ping(self.access_point.ssh_settings.hostname)
def test_ping_with_params(self):
return self.send_ping(self.google_dns_1,
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/SoftApTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/SoftApTest.py
index 4f29672..ec74992 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/SoftApTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/SoftApTest.py
@@ -21,16 +21,15 @@
from acts import utils
from acts import asserts
-from acts.base_test import BaseTestClass
from acts.controllers import iperf_server
from acts.controllers import iperf_client
-from acts.controllers.access_point import setup_ap
+from acts.controllers.access_point import setup_ap, AccessPoint
from acts.controllers.ap_lib import hostapd_constants
from acts.controllers.ap_lib import hostapd_security
from acts.controllers.ap_lib.hostapd_utils import generate_random_password
from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device
+from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
-ANDROID_DEFAULT_WLAN_INTERFACE = 'wlan0'
CONNECTIVITY_MODE_LOCAL = 'local_only'
CONNECTIVITY_MODE_UNRESTRICTED = 'unrestricted'
DEFAULT_AP_PROFILE = 'whirlwind'
@@ -41,7 +40,6 @@
DEFAULT_NO_ADDR_EXPECTED_TIMEOUT = 5
INTERFACE_ROLE_AP = 'Ap'
INTERFACE_ROLE_CLIENT = 'Client'
-INTERFACE_ROLES = {INTERFACE_ROLE_AP, INTERFACE_ROLE_CLIENT}
OPERATING_BAND_2G = 'only_2_4_ghz'
OPERATING_BAND_5G = 'only_5_ghz'
OPERATING_BAND_ANY = 'any'
@@ -134,26 +132,13 @@
pass
-class SoftApClient(object):
- def __init__(self, device):
- self.w_device = create_wlan_device(device)
- self.ip_client = iperf_client.IPerfClientOverAdb(device.serial)
-
-
-class WlanInterface(object):
- def __init__(self):
- self.name = None
- self.mac_addr = None
- self.ipv4 = None
-
-
-class SoftApTest(BaseTestClass):
+class SoftApTest(AbstractDeviceWlanDeviceBaseTest):
"""Tests for Fuchsia SoftAP
Testbed requirement:
* One Fuchsia device
- * At least one dlient (Android) device
- * For multi-client tests, at least two dlient (Android) devices are
+ * At least one client (Android) device
+ * For multi-client tests, at least two client (Android) devices are
required. Test will be skipped if less than two client devices are
present.
* For any tests that exercise client-mode (e.g. toggle tests, simultaneous
@@ -164,14 +149,19 @@
self.soft_ap_test_params = self.user_params.get(
'soft_ap_test_params', {})
self.dut = create_wlan_device(self.fuchsia_devices[0])
- self.dut.device.netstack_lib.init()
# TODO(fxb/51313): Add in device agnosticity for clients
+ # Create a wlan device and iperf client for each Android client
self.clients = []
+ self.iperf_clients_map = {}
for device in self.android_devices:
- self.clients.append(SoftApClient(device))
+ client_wlan_device = create_wlan_device(device)
+ self.clients.append(client_wlan_device)
+ self.iperf_clients_map[
+ client_wlan_device] = client_wlan_device.create_iperf_client()
self.primary_client = self.clients[0]
+ # Create an iperf server on the DUT, which will be used for any streaming.
self.iperf_server_config = {
'user': self.dut.device.ssh_username,
'host': self.dut.device.ip,
@@ -181,13 +171,17 @@
self.iperf_server_config, DEFAULT_IPERF_PORT, use_killall=True)
self.iperf_server.start()
+ # Attempt to create an ap iperf server. AP is only required for tests
+ # that use client mode.
try:
self.access_point = self.access_points[0]
+ self.ap_iperf_client = iperf_client.IPerfClientOverSsh(
+ self.user_params['AccessPoint'][0]['ssh_config'])
except AttributeError:
self.access_point = None
+ self.ap_iperf_client = None
- self.ap_iperf_client = iperf_client.IPerfClientOverSsh(
- self.user_params['AccessPoint'][0]['ssh_config'])
+ self.iperf_clients_map[self.access_point] = self.ap_iperf_client
def teardown_class(self):
# Because this is using killall, it will stop all iperf processes
@@ -198,9 +192,9 @@
ad.droid.wakeLockAcquireBright()
ad.droid.wakeUpNow()
for client in self.clients:
- client.w_device.disconnect()
- client.w_device.reset_wifi()
- client.w_device.wifi_toggle_state(True)
+ client.disconnect()
+ client.reset_wifi()
+ client.wifi_toggle_state(True)
self.stop_all_soft_aps()
if self.access_point:
self.access_point.stop_all_aps()
@@ -208,19 +202,16 @@
def teardown_test(self):
for client in self.clients:
- client.w_device.disconnect()
+ client.disconnect()
for ad in self.android_devices:
ad.droid.wakeLockRelease()
ad.droid.goToSleepNow()
self.stop_all_soft_aps()
if self.access_point:
+ self.download_ap_logs()
self.access_point.stop_all_aps()
self.dut.disconnect()
- 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)
-
def start_soft_ap(self, settings):
"""Starts a softAP on Fuchsia device.
@@ -283,11 +274,11 @@
'SL4F: Failed to stop all SoftAPs. Err: %s' %
response['error'])
- def associate_with_soft_ap(self, w_device, settings):
+ def associate_with_soft_ap(self, device, soft_ap_settings):
"""Associates client device with softAP on Fuchsia device.
Args:
- w_device: wlan_device to associate with the softAP
+ device: wlan_device to associate with the softAP
settings: a dict containing softAP config params (see start_soft_ap)
for details
@@ -296,16 +287,16 @@
"""
self.log.info(
'Attempting to associate client %s with SoftAP on FuchsiaDevice '
- '(%s).' % (w_device.device.serial, self.dut.device.ip))
+ '(%s).' % (device.identifier, self.dut.identifier))
- check_connectivity = settings[
+ check_connectivity = soft_ap_settings[
'connectivity_mode'] == CONNECTIVITY_MODE_UNRESTRICTED
- associated = w_device.associate(
- settings['ssid'],
- target_pwd=settings.get('password'),
+ associated = device.associate(
+ soft_ap_settings['ssid'],
+ target_pwd=soft_ap_settings.get('password'),
target_security=hostapd_constants.
SECURITY_STRING_TO_DEFAULT_TARGET_SECURITY.get(
- settings['security_type'], None),
+ soft_ap_settings['security_type'], None),
check_connectivity=check_connectivity)
if not associated:
@@ -315,144 +306,87 @@
self.log.info('Client successfully associated with SoftAP.')
return True
- def disconnect_from_soft_ap(self, w_device):
+ def disconnect_from_soft_ap(self, device):
"""Disconnects client device from SoftAP.
Args:
- w_device: wlan_device to disconnect from SoftAP
+ device: wlan_device to disconnect from SoftAP
"""
self.log.info('Disconnecting device %s from SoftAP.' %
- w_device.device.serial)
- w_device.disconnect()
+ device.identifier)
+ device.disconnect()
- def get_dut_interface_by_role(self,
- role,
- wait_for_addr_timeout=DEFAULT_TIMEOUT):
- """Retrieves interface information from the FuchsiaDevice DUT based
- on the role.
+ def get_device_test_interface(self, device, role=None, channel=None):
+ """Retrieves test interface from a provided device, which can be the
+ FuchsiaDevice DUT, the AccessPoint, or an AndroidClient.
Args:
- role: string, the role of the interface to seek (e.g. Client or Ap)
-
- Raises:
- ConnectionError, if SL4F calls fail
- AttributeError, if device does not have an interface matching role
+ device: the device do get the test interface from. Either
+ FuchsiaDevice (DUT), Android client, or AccessPoint.
+ role: str, either "client" or "ap". Required for FuchsiaDevice (DUT)
+ channel: int, channel of the ap network. Required for AccessPoint.
Returns:
- WlanInterface object representing the interface matching role
+ String, name of test interface on given device.
"""
- if not role in INTERFACE_ROLES:
- raise ValueError('Unsupported interface role %s' % role)
- interface = WlanInterface()
-
- # Determine WLAN interface with role
- wlan_ifaces = self.dut.device.wlan_lib.wlanGetIfaceIdList()
- if wlan_ifaces.get('error'):
- raise ConnectionError('Failed to get wlan interface IDs: %s' %
- wlan_ifaces['error'])
-
- for wlan_iface in wlan_ifaces['result']:
- iface_info = self.dut.device.wlan_lib.wlanQueryInterface(
- wlan_iface)
- if iface_info.get('error'):
- raise ConnectionError('Failed to query wlan iface: %s' %
- iface_info['error'])
-
- if iface_info['result']['role'] == role:
- interface.mac_addr = iface_info['result']['mac_addr']
- break
+ if device is self.dut:
+ device.device.wlan_controller.update_wlan_interfaces()
+ if role == INTERFACE_ROLE_CLIENT:
+ return device.device.wlan_client_test_interface_name
+ elif role == INTERFACE_ROLE_AP:
+ return device.device.wlan_ap_test_interface_name
+ else:
+ raise ValueError('Unsupported interface role: %s' % role)
+ elif isinstance(device, AccessPoint):
+ if not channel:
+ raise ValueError(
+ 'Must provide a channel to get AccessPoint interface')
+ if channel < 36:
+ return device.wlan_2g
+ else:
+ return device.wlan_5g
else:
- raise LookupError('Failed to find a %s interface.' % role)
-
- # Retrieve interface info from netstack
- netstack_ifaces = self.dut.device.netstack_lib.netstackListInterfaces()
- if netstack_ifaces.get('error'):
- raise ConnectionError('Failed to get netstack ifaces: %s' %
- netstack_ifaces['error'])
-
- # TODO(fxb/51315): Once subnet information is available in
- # netstackListInterfaces store it to verify the clients ip address.
- for netstack_iface in netstack_ifaces['result']:
- if netstack_iface['mac'] == interface.mac_addr:
- interface.name = netstack_iface['name']
- if len(netstack_iface['ipv4_addresses']) > 0:
- interface.ipv4 = '.'.join(
- str(byte)
- for byte in netstack_iface['ipv4_addresses'][0])
- else:
- interface.ipv4 = self.wait_for_ipv4_address(
- self.dut,
- interface.name,
- timeout=wait_for_addr_timeout)
- self.log.info('DUT %s interface: %s. Has ipv4 address %s' %
- (role, interface.name, interface.ipv4))
- return interface
+ return device.get_default_wlan_test_interface()
def wait_for_ipv4_address(self,
- w_device,
+ device,
interface_name,
timeout=DEFAULT_TIMEOUT):
- # TODO(fxb/51315): Once subnet information is available in netstack, add a
- # subnet verification here.
""" Waits for interface on a wlan_device to get an ipv4 address.
Args:
- w_device: wlan_device to check interface
+ device: wlan_device or AccessPoint to check interface
interface_name: name of the interface to check
timeout: seconds to wait before raising an error
Raises:
ValueError, if interface does not have an ipv4 address after timeout
"""
-
+ if isinstance(device, AccessPoint):
+ comm_channel = device.ssh
+ else:
+ comm_channel = device.device
end_time = time.time() + timeout
while time.time() < end_time:
- ips = w_device.get_interface_ip_addresses(interface_name)
+ ips = utils.get_interface_ip_addresses(comm_channel,
+ interface_name)
if len(ips['ipv4_private']) > 0:
self.log.info('Device %s interface %s has ipv4 address %s' %
- (w_device.device.serial, interface_name,
+ (device.identifier, interface_name,
ips['ipv4_private'][0]))
return ips['ipv4_private'][0]
else:
time.sleep(1)
raise ConnectionError(
'After %s seconds, device %s still does not have an ipv4 address '
- 'on interface %s.' %
- (timeout, w_device.device.serial, interface_name))
+ 'on interface %s.' % (timeout, device.identifier, interface_name))
- def get_ap_ipv4_address(self, channel, timeout=DEFAULT_TIMEOUT):
- """Get APs ipv4 address (actual AP, not soft ap on DUT)
-
- Args:
- channel: int, channel of the network used to determine
- which interface to use
- """
- lowest_5ghz_channel = 36
- if channel < lowest_5ghz_channel:
- ap_interface = self.access_point.wlan_2g
- else:
- ap_interface = self.access_point.wlan_5g
- end_time = time.time() + timeout
- while time.time() < end_time:
- ap_ipv4_addresses = utils.get_interface_ip_addresses(
- self.access_point.ssh, ap_interface)['ipv4_private']
- if len(ap_ipv4_addresses) > 0:
- return ap_ipv4_addresses[0]
- else:
- self.log.debug(
- 'Access point does not have an ipv4 address on interface '
- '%s. Retrying in 1 second.' % ap_interface)
- else:
- raise ConnectionError(
- 'Access point never had an ipv4 address on interface %s.' %
- ap_interface)
-
- def device_can_ping_addr(self, w_device, dest_ip, timeout=DEFAULT_TIMEOUT):
+ def device_can_ping_addr(self, device, dest_ip, timeout=DEFAULT_TIMEOUT):
""" Verify wlan_device can ping a destination ip.
Args:
- w_device: wlan_device to initiate ping
+ device: wlan_device to initiate ping
dest_ip: ip to ping from wlan_device
Raises:
@@ -461,20 +395,20 @@
end_time = time.time() + timeout
while time.time() < end_time:
with utils.SuppressLogOutput():
- ping_result = w_device.can_ping(dest_ip)
+ ping_result = device.can_ping(dest_ip)
if ping_result:
self.log.info('Ping successful from device %s to dest ip %s.' %
- (w_device.identifier, dest_ip))
+ (device.identifier, dest_ip))
return True
else:
self.log.debug(
'Device %s could not ping dest ip %s. Retrying in 1 second.'
- % (w_device.identifier, dest_ip))
+ % (device.identifier, dest_ip))
time.sleep(1)
else:
self.log.info('Failed to ping from device %s to dest ip %s.' %
- (w_device.identifier, dest_ip))
+ (device.identifier, dest_ip))
return False
def run_iperf_traffic(self, ip_client, server_address, server_port=5201):
@@ -556,107 +490,69 @@
ip_client: iperf client to grab identifier from
"""
if type(ip_client) == iperf_client.IPerfClientOverAdb:
- return ip_client._android_device_or_serial
+ return ip_client._android_device_or_serial.serial
return ip_client._ssh_settings.hostname
- def dut_is_connected_as_client(self,
- channel,
- check_traffic=False,
- wait_for_addr_timeout=DEFAULT_TIMEOUT):
- """Checks if DUT is successfully connected to AP.
+ def device_is_connected_to_ap(self,
+ client,
+ ap,
+ channel=None,
+ check_traffic=False,
+ timeout=DEFAULT_TIMEOUT):
+ """ Returns whether client device can ping (and optionally pass traffic)
+ to the ap device.
Args:
- channel: int, channel of the AP network (to retrieve interfaces)
- check_traffic: bool, if true, verifies traffic between DUT and AP,
- else just checks ping.
- wait_for_addr_timeout: int, time, in seconds, to wait when getting
- DUT and AP addresses
-
- Returns:
- True, if connected correctly
- False, otherwise
+ client: device that should be associated. Either FuchsiaDevice (DUT)
+ or Android client
+ ap: device acting as AP. Either FuchsiaDevice (DUT) or AccessPoint.
+ channel: int, channel the AP is using. Required if ap is an
+ AccessPoint object.
+ check_traffic: bool, whether to attempt to pass traffic between
+ client and ap devices.
+ timeout: int, time in seconds to wait for devices to have ipv4
+ addresses
"""
try:
- dut_client_interface = self.get_dut_interface_by_role(
- INTERFACE_ROLE_CLIENT,
- wait_for_addr_timeout=wait_for_addr_timeout)
- ap_ipv4 = self.get_ap_ipv4_address(channel,
- timeout=wait_for_addr_timeout)
+ # Get interfaces
+ client_interface = self.get_device_test_interface(
+ client, INTERFACE_ROLE_CLIENT)
+ ap_interface = self.get_device_test_interface(
+ ap, role=INTERFACE_ROLE_AP, channel=channel)
+
+ # Get addresses
+ client_ipv4 = self.wait_for_ipv4_address(client,
+ client_interface,
+ timeout=timeout)
+ ap_ipv4 = self.wait_for_ipv4_address(ap,
+ ap_interface,
+ timeout=timeout)
except ConnectionError as err:
self.log.error(
'Failed to retrieve interfaces and addresses. Err: %s' % err)
return False
- if not self.device_can_ping_addr(self.dut, ap_ipv4):
- self.log.error('Failed to ping from DUT to AP.')
+ if not self.device_can_ping_addr(client, ap_ipv4):
+ self.log.error('Failed to ping from client to ap.')
return False
- if not self.device_can_ping_addr(self.access_point,
- dut_client_interface.ipv4):
- self.log.error('Failed to ping from AP to DUT.')
+ if not self.device_can_ping_addr(ap, client_ipv4):
+ self.log.error('Failed to ping from ap to client.')
return False
if check_traffic:
try:
- self.run_iperf_traffic(self.ap_iperf_client,
- dut_client_interface.ipv4)
+ if client is self.dut:
+ self.run_iperf_traffic(self.iperf_clients_map[ap],
+ client_ipv4)
+ else:
+ self.run_iperf_traffic(self.iperf_clients_map[client],
+ ap_ipv4)
except ConnectionError as err:
self.log.error('Failed to run traffic between DUT and AP.')
return False
return True
- def client_is_connected_to_soft_ap(
- self,
- client,
- client_interface=ANDROID_DEFAULT_WLAN_INTERFACE,
- check_traffic=False,
- wait_for_addr_timeout=DEFAULT_TIMEOUT):
- """Checks if client is successfully connected to DUT SoftAP.
-
- Args:
- client: SoftApClient to check
- client_interface: string, wlan interface name of client
- check_traffic: bool, if true, verifies traffic between client and
- DUT, else just checks ping.
- wait_for_addr_timeout: int, time, in seconds, to wait when getting
- DUT and client addresses
-
- Returns:
- True, if connected correctly
- False, otherwise
- """
-
- try:
- dut_ap_interface = self.get_dut_interface_by_role(
- INTERFACE_ROLE_AP, wait_for_addr_timeout=wait_for_addr_timeout)
- client_ipv4 = self.wait_for_ipv4_address(
- client.w_device,
- client_interface,
- timeout=wait_for_addr_timeout)
- except ConnectionError as err:
- self.log.error(
- 'Failed to retrieve interfaces and addresses. Err: %s' % err)
- return False
-
- if not self.device_can_ping_addr(self.dut, client_ipv4):
- self.log.error('Failed to ping client (%s) from DUT.' %
- client_ipv4)
- return False
- if not self.device_can_ping_addr(client.w_device,
- dut_ap_interface.ipv4):
- self.log.error('Failed to ping DUT from client (%s)' % client_ipv4)
- return False
-
- if check_traffic:
- try:
- self.run_iperf_traffic(client.ip_client, dut_ap_interface.ipv4)
- except ConnectionError as err:
- self.log.error(
- 'Failed to pass traffic between client (%s) and DUT.' %
- client_ipv4)
- return False
- return True
-
def verify_soft_ap_connectivity_from_state(self, state, client):
"""Verifies SoftAP state based on a client connection.
@@ -665,13 +561,14 @@
client: SoftApClient, to verify connectivity (or lack therof)
"""
if state == STATE_UP:
- return self.client_is_connected_to_soft_ap(client)
+ return self.device_is_connected_to_ap(client, self.dut)
else:
with utils.SuppressLogOutput():
try:
- return not self.client_is_connected_to_soft_ap(
+ return not self.device_is_connected_to_ap(
client,
- wait_for_addr_timeout=DEFAULT_NO_ADDR_EXPECTED_TIMEOUT)
+ self.dut,
+ timeout=DEFAULT_NO_ADDR_EXPECTED_TIMEOUT)
# Allow a failed to find ap interface error
except LookupError as err:
self.log.debug('Hit expected LookupError: %s' % err)
@@ -685,13 +582,17 @@
channel: int, channel of the APs network
"""
if state == STATE_UP:
- return self.dut_is_connected_as_client(channel)
+ return self.device_is_connected_to_ap(self.dut,
+ self.access_point,
+ channel=channel)
else:
with utils.SuppressLogOutput():
try:
- return not self.dut_is_connected_as_client(
- channel,
- wait_for_addr_timeout=DEFAULT_NO_ADDR_EXPECTED_TIMEOUT)
+ return not self.device_is_connected_to_ap(
+ self.dut,
+ self.access_point,
+ channel=channel,
+ timeout=DEFAULT_NO_ADDR_EXPECTED_TIMEOUT)
# Allow a failed to find client interface error
except LookupError as err:
self.log.debug('Hit expected LookupError: %s' % err)
@@ -699,18 +600,19 @@
# Test Types
- def verify_soft_ap_associate_only(self, client, settings):
- if not self.associate_with_soft_ap(client.w_device, settings):
+ def verify_soft_ap_associate_only(self, client, soft_ap_settings):
+ if not self.associate_with_soft_ap(client, soft_ap_settings):
asserts.fail('Failed to associate client with SoftAP.')
- def verify_soft_ap_associate_and_ping(self, client, settings):
- self.verify_soft_ap_associate_only(client, settings)
- if not self.client_is_connected_to_soft_ap(client):
+ def verify_soft_ap_associate_and_ping(self, client, soft_ap_settings):
+ self.verify_soft_ap_associate_only(client, soft_ap_settings)
+ if not self.device_is_connected_to_ap(client, self.dut):
asserts.fail('Client and SoftAP could not ping eachother.')
def verify_soft_ap_associate_and_pass_traffic(self, client, settings):
self.verify_soft_ap_associate_only(client, settings)
- if not self.client_is_connected_to_soft_ap(client, check_traffic=True):
+ if not self.device_is_connected_to_ap(
+ client, self.dut, check_traffic=True):
asserts.fail(
'Client and SoftAP not responding to pings and passing traffic '
'as expected.')
@@ -784,7 +686,6 @@
"""
iterations = settings['iterations']
pass_count = 0
- client = self.primary_client
current_soft_ap_state = STATE_DOWN
current_client_mode_state = STATE_DOWN
@@ -792,7 +693,8 @@
for iteration in range(iterations):
passes = True
- # Attempt to toggle SoftAP on, then off
+ # Attempt to toggle SoftAP on, then off. If the first toggle fails
+ # to occur, exit early.
for _ in range(2):
(current_soft_ap_state, err) = self.run_toggle_iteration_func(
self.soft_ap_toggle_test_iteration, settings,
@@ -804,7 +706,8 @@
if current_soft_ap_state == STATE_DOWN:
break
- # Attempt to toggle Client mode on, then off
+ # Attempt to toggle Client mode on, then off. If the first toggle,
+ # fails to occur, exit early.
for _ in range(2):
(current_client_mode_state,
err) = self.run_toggle_iteration_func(
@@ -919,8 +822,7 @@
soft_ap_params['ssid'] = utils.rand_ascii_str(
hostapd_constants.AP_SSID_LENGTH_2G)
self.start_soft_ap(soft_ap_params)
- associated = self.associate_with_soft_ap(client.w_device,
- soft_ap_params)
+ associated = self.associate_with_soft_ap(client, soft_ap_params)
if not associated:
raise StressTestIterationFailure(
'Failed to associated client to DUT SoftAP. '
@@ -1049,7 +951,9 @@
profile_name=ap_profile,
**ap_params)
# Confirms AP assigned itself an address
- self.get_ap_ipv4_address(ap_channel)
+ ap_interface = self.get_device_test_interface(self.access_point,
+ channel=ap_channel)
+ self.wait_for_ipv4_address(self.access_point, ap_interface)
def client_mode_toggle_test_iteration(self, settings, current_state):
"""Runs a single iteration of client mode toggle stress test
@@ -1064,7 +968,6 @@
functioning correctly.
EnvironmentError, if toggle fails to occur at all
"""
- # TODO(b/168054673): Use client connections and policy connect
ap_params = settings['ap_params']
self.log.info('Toggling client mode %s' %
('off' if current_state else 'on'))
@@ -1114,7 +1017,8 @@
ap_params = settings['ap_params']
ap_channel = ap_params['channel']
self.soft_ap_toggle_test_iteration(settings, current_state)
- if not self.dut_is_connected_as_client(ap_channel):
+ if not self.device_is_connected_to_ap(
+ self.dut, self.access_point, channel=ap_channel):
raise StressTestIterationFailure(
'DUT client mode is no longer functional after SoftAP toggle.')
@@ -1153,7 +1057,7 @@
EnvironmentError, if toggle fails to occur at all
"""
self.client_mode_toggle_test_iteration(settings, current_state)
- if not self.client_is_connected_to_soft_ap(self.primary_client):
+ if not self.device_is_connected_to_ap(self.primary_client, self.dut):
raise StressTestIterationFailure(
'SoftAP is no longer functional after client mode toggle.')
@@ -1596,7 +1500,6 @@
}
}
"""
- # TODO(fxb/59335): Validate clients on network can reach eachother.
asserts.skip_if(
len(self.clients) < 2, 'Test requires at least 2 SoftAPClients')
@@ -1607,55 +1510,67 @@
self.start_soft_ap(soft_ap_params)
- dut_ap_interface = self.get_dut_interface_by_role(INTERFACE_ROLE_AP)
associated = []
for client in self.clients:
# Associate new client
self.verify_soft_ap_associate_and_ping(client, soft_ap_params)
- client_ipv4 = self.wait_for_ipv4_address(
- client.w_device, ANDROID_DEFAULT_WLAN_INTERFACE)
# Verify previously associated clients still behave as expected
- for client_map in associated:
- associated_client = client_map['client']
- associated_client_ipv4 = client_map['ipv4']
+ for associated_client in associated:
self.log.info(
'Verifying previously associated client %s still functions correctly.'
- % associated_client.w_device.device.serial)
- if not self.client_is_connected_to_soft_ap(associated_client,
- check_traffic=True):
+ % associated_client['device'].identifier)
+ if not self.device_is_connected_to_ap(
+ associated_client['device'], self.dut,
+ check_traffic=True):
asserts.fail(
'Previously associated client %s failed checks after '
'client %s associated.' %
- (associated_client.w_device.device.serial,
- client.w_device.device.serial))
+ (associated_client['device'].identifier,
+ client.identifier))
- associated.append({'client': client, 'ipv4': client_ipv4})
+ client_interface = self.get_device_test_interface(client)
+ client_ipv4 = self.wait_for_ipv4_address(client, client_interface)
+ associated.append({"device": client, "address": client_ipv4})
+
+ self.log.info('All devices successfully associated.')
+
+ self.log.info('Verifying all associated clients can ping eachother.')
+ for transmitter in associated:
+ for receiver in associated:
+ if transmitter != receiver:
+ if not transmitter['device'].can_ping(receiver['address']):
+ asserts.fail(
+ 'Could not ping from one associated client (%s) to another (%s).'
+ % (transmitter['address'], receiver['address']))
+ else:
+ self.log.info(
+ 'Successfully pinged from associated client (%s) to another (%s)'
+ % (transmitter['address'], receiver['address']))
self.log.info(
- 'All devices successfully associated. Beginning disassociations.')
+ 'All associated clients can ping eachother. Beginning disassociations.'
+ )
while len(associated) > 0:
# Disassociate client
- client = associated.pop()['client']
- self.disconnect_from_soft_ap(client.w_device)
+ client = associated.pop()['device']
+ self.disconnect_from_soft_ap(client)
# Verify still connected clients still behave as expected
- for client_map in associated:
- associated_client = client_map['client']
- associated_client_ipv4 = client_map['ipv4']
-
+ for associated_client in associated:
self.log.info(
'Verifying still associated client %s still functions '
- 'correctly.' % associated_client.w_device.device.serial)
- if not self.client_is_connected_to_soft_ap(associated_client,
- check_traffic=True):
+ 'correctly.' % associated_client['device'].identifier)
+ if not self.device_is_connected_to_ap(
+ associated_client['device'], self.dut,
+ check_traffic=True):
asserts.fail(
'Previously associated client %s failed checks after'
' client %s disassociated.' %
- (associated_client.w_device.device.serial,
- client.w_device.device.serial))
+ (associated_client['device'].identifier,
+ client.identifier))
self.log.info('All disassociations occurred smoothly.')
@@ -1669,7 +1584,6 @@
TestFailure: if DUT fails to pass traffic as either a client or an
AP
"""
- # TODO(fxb/59306): Fix flakey parallel streams.
asserts.skip_if(not self.access_point, 'No access point provided.')
self.log.info('Setting up AP using hostapd.')
@@ -1696,10 +1610,16 @@
self.start_soft_ap_and_verify_connected(self.primary_client,
soft_ap_params)
- # Get FuchsiaDevice's AP interface info
- dut_ap_interface = self.get_dut_interface_by_role(INTERFACE_ROLE_AP)
- dut_client_interface = self.get_dut_interface_by_role(
- INTERFACE_ROLE_CLIENT)
+ # Get FuchsiaDevice test interfaces
+ dut_ap_interface = self.get_device_test_interface(
+ self.dut, role=INTERFACE_ROLE_AP)
+ dut_client_interface = self.get_device_test_interface(
+ self.dut, role=INTERFACE_ROLE_CLIENT)
+
+ # Get FuchsiaDevice addresses
+ dut_ap_ipv4 = self.wait_for_ipv4_address(self.dut, dut_ap_interface)
+ dut_client_ipv4 = self.wait_for_ipv4_address(self.dut,
+ dut_client_interface)
# Set up secondary iperf server of FuchsiaDevice
self.log.info('Setting up second iperf server on FuchsiaDevice DUT.')
@@ -1719,13 +1639,13 @@
iperf_soft_ap = mp.Process(
target=self.run_iperf_traffic_parallel_process,
args=[
- self.primary_client.ip_client, dut_ap_interface.ipv4,
+ self.iperf_clients_map[self.primary_client], dut_ap_ipv4,
process_errors
])
iperf_fuchsia_client = mp.Process(
target=self.run_iperf_traffic_parallel_process,
- args=[ap_iperf_client, dut_client_interface.ipv4, process_errors],
+ args=[ap_iperf_client, dut_client_ipv4, process_errors],
kwargs={'server_port': 5202})
# Run iperf processes simultaneously
@@ -1793,11 +1713,19 @@
iterations = config_settings.get('iterations',
DEFAULT_STRESS_TEST_ITERATIONS)
test_settings = {
- 'test_name': config_settings['test_name'],
- 'client': self.primary_client,
- 'soft_ap_params': soft_ap_params,
- 'test_type': test_type,
- 'iterations': iterations
+ 'test_name':
+ config_settings.get(
+ 'test_name',
+ 'test_soft_ap_association_stress_%s_iterations' %
+ iterations),
+ 'client':
+ self.primary_client,
+ 'soft_ap_params':
+ soft_ap_params,
+ 'test_type':
+ test_type,
+ 'iterations':
+ iterations
}
test_settings_list.append(test_settings)
@@ -1854,10 +1782,17 @@
DEFAULT_STRESS_TEST_ITERATIONS)
test_settings = {
- 'test_name': config_settings['test_name'],
- 'iterations': iterations,
- 'soft_ap_params': soft_ap_params,
- 'ap_params': ap_params,
+ 'test_name':
+ config_settings.get(
+ 'test_name',
+ 'test_soft_ap_and_client_mode_alternating_stress_%s_iterations'
+ % iterations),
+ 'iterations':
+ iterations,
+ 'soft_ap_params':
+ soft_ap_params,
+ 'ap_params':
+ ap_params,
}
test_settings_list.append(test_settings)
@@ -1901,10 +1836,16 @@
iterations = config_settings.get('iterations',
DEFAULT_STRESS_TEST_ITERATIONS)
test_settings = {
- 'test_name': config_settings['test_name'],
- 'test_runner_func': self.soft_ap_toggle_test_iteration,
- 'soft_ap_params': soft_ap_params,
- 'iterations': iterations
+ 'test_name':
+ config_settings.get(
+ 'test_name',
+ 'test_soft_ap_toggle_stress_%s_iterations' % iterations),
+ 'test_runner_func':
+ self.soft_ap_toggle_test_iteration,
+ 'soft_ap_params':
+ soft_ap_params,
+ 'iterations':
+ iterations
}
test_settings_list.append(test_settings)
@@ -1948,11 +1889,19 @@
iterations = config_settings.get('iterations',
DEFAULT_STRESS_TEST_ITERATIONS)
test_settings = {
- 'test_name': config_settings['test_name'],
- 'test_runner_func': self.client_mode_toggle_test_iteration,
- 'pre_test_func': self.client_mode_toggle_pre_test,
- 'ap_params': ap_params,
- 'iterations': iterations
+ 'test_name':
+ config_settings.get(
+ 'test_name',
+ 'test_client_mode_toggle_stress_%s_iterations' %
+ iterations),
+ 'test_runner_func':
+ self.client_mode_toggle_test_iteration,
+ 'pre_test_func':
+ self.client_mode_toggle_pre_test,
+ 'ap_params':
+ ap_params,
+ 'iterations':
+ iterations
}
test_settings_list.append(test_settings)
self.run_generated_testcases(self.run_toggle_stress_test,
@@ -1978,13 +1927,21 @@
iterations = config_settings.get('iterations',
DEFAULT_STRESS_TEST_ITERATIONS)
test_settings = {
- 'test_name': config_settings['test_name'],
+ 'test_name':
+ config_settings.get(
+ 'test_name',
+ 'test_soft_ap_toggle_stress_with_client_mode_%s_iterations'
+ % iterations),
'test_runner_func':
self.soft_ap_toggle_with_client_mode_iteration,
- 'pre_test_func': self.soft_ap_toggle_with_client_mode_pre_test,
- 'soft_ap_params': soft_ap_params,
- 'ap_params': ap_params,
- 'iterations': iterations
+ 'pre_test_func':
+ self.soft_ap_toggle_with_client_mode_pre_test,
+ 'soft_ap_params':
+ soft_ap_params,
+ 'ap_params':
+ ap_params,
+ 'iterations':
+ iterations
}
test_settings_list.append(test_settings)
self.run_generated_testcases(self.run_toggle_stress_test,
@@ -2010,13 +1967,21 @@
iterations = config_settings.get('iterations',
DEFAULT_STRESS_TEST_ITERATIONS)
test_settings = {
- 'test_name': config_settings['test_name'],
+ 'test_name':
+ config_settings.get(
+ 'test_name',
+ 'test_client_mode_toggle_stress_with_soft_ap_%s_iterations'
+ % iterations),
'test_runner_func':
self.client_mode_toggle_with_soft_ap_iteration,
- 'pre_test_func': self.client_mode_toggle_with_soft_ap_pre_test,
- 'soft_ap_params': soft_ap_params,
- 'ap_params': ap_params,
- 'iterations': iterations
+ 'pre_test_func':
+ self.client_mode_toggle_with_soft_ap_pre_test,
+ 'soft_ap_params':
+ soft_ap_params,
+ 'ap_params':
+ ap_params,
+ 'iterations':
+ iterations
}
test_settings_list.append(test_settings)
self.run_generated_testcases(self.run_toggle_stress_test,
@@ -2044,10 +2009,17 @@
iterations = config_settings.get('iterations',
DEFAULT_STRESS_TEST_ITERATIONS)
test_settings = {
- 'test_name': config_settings['test_name'],
- 'soft_ap_params': soft_ap_params,
- 'ap_params': ap_params,
- 'iterations': iterations
+ 'test_name':
+ config_settings.get(
+ 'test_name',
+ 'test_soft_ap_and_client_mode_random_toggle_stress_%s_iterations'
+ % iterations),
+ 'soft_ap_params':
+ soft_ap_params,
+ 'ap_params':
+ ap_params,
+ 'iterations':
+ iterations
}
test_settings_list.append(test_settings)
self.run_generated_testcases(
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/WlanRebootTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/WlanRebootTest.py
index 59060bd..8d365a7 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/WlanRebootTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/WlanRebootTest.py
@@ -35,6 +35,7 @@
from acts.controllers.ap_lib.radvd_config import RadvdConfig
from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
+from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
# Constants, for readibility
AP = 'ap'
@@ -100,7 +101,7 @@
return settings['test_name']
-class WlanRebootTest(WifiBaseTest):
+class WlanRebootTest(AbstractDeviceWlanDeviceBaseTest):
"""Tests wlan reconnects in different reboot scenarios.
Testbed Requirement:
@@ -143,9 +144,9 @@
self.iperf_server_on_ap = None
self.iperf_client_on_dut = None
if not self.skip_iperf:
- try:
+ if hasattr(self, "iperf_clients") and self.iperf_clients:
self.iperf_client_on_dut = self.iperf_clients[0]
- except AttributeError:
+ else:
self.iperf_client_on_dut = self.dut.create_iperf_client()
else:
self.log.info(
@@ -167,8 +168,14 @@
self.ssid = utils.rand_ascii_str(hostapd_constants.AP_SSID_LENGTH_2G)
def teardown_test(self):
+ self.download_ap_logs()
self.access_point.stop_all_aps()
if self.router_adv_daemon:
+ output_path = context.get_current_context().get_base_output_path()
+ full_output_path = os.path.join(output_path, "radvd_log.txt")
+ radvd_log_file = open(full_output_path, 'w')
+ radvd_log_file.write(self.router_adv_daemon.pull_logs())
+ radvd_log_file.close()
self.router_adv_daemon.stop()
self.router_adv_daemon = None
self.dut.disconnect()
@@ -178,10 +185,6 @@
self.dut.turn_location_off_and_scan_toggle_off()
self.dut.reset_wifi()
- 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)
-
def setup_ap(self,
ssid,
band,
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/WlanScanTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/WlanScanTest.py
index dda04a5..6133f0b 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/WlanScanTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/WlanScanTest.py
@@ -24,7 +24,6 @@
import pprint
import time
-import acts.base_test
import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
from acts import signals
@@ -32,10 +31,10 @@
from acts.controllers.ap_lib import hostapd_bss_settings
from acts.controllers.ap_lib import hostapd_constants
from acts.controllers.ap_lib import hostapd_security
-from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
+from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
-class WlanScanTest(WifiBaseTest):
+class WlanScanTest(AbstractDeviceWlanDeviceBaseTest):
"""WLAN scan test class.
Test Bed Requirement:
@@ -46,6 +45,7 @@
def setup_class(self):
super().setup_class()
+ self.access_point = self.access_points[0]
self.start_access_point = False
for fd in self.fuchsia_devices:
fd.configure_wlan(association_mechanism='drivers')
@@ -85,14 +85,14 @@
security_mode=self.wpa2_network_5g["security"],
password=self.wpa2_network_5g["password"])))
self.ap_2g = hostapd_ap_preset.create_ap_preset(
- iface_wlan_2g=self.access_points[0].wlan_2g,
- iface_wlan_5g=self.access_points[0].wlan_5g,
+ iface_wlan_2g=self.access_point.wlan_2g,
+ iface_wlan_5g=self.access_point.wlan_5g,
channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G,
ssid=self.open_network_2g['SSID'],
bss_settings=bss_settings_2g)
self.ap_5g = hostapd_ap_preset.create_ap_preset(
- iface_wlan_2g=self.access_points[0].wlan_2g,
- iface_wlan_5g=self.access_points[0].wlan_5g,
+ iface_wlan_2g=self.access_point.wlan_2g,
+ iface_wlan_5g=self.access_point.wlan_5g,
channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G,
ssid=self.open_network_5g['SSID'],
bss_settings=bss_settings_5g)
@@ -134,10 +134,10 @@
# previously saved ssid on the device.
if self.start_access_point_2g:
self.start_access_point = True
- self.access_points[0].start_ap(hostapd_config=self.ap_2g)
+ self.access_point.start_ap(hostapd_config=self.ap_2g)
if self.start_access_point_5g:
self.start_access_point = True
- self.access_points[0].start_ap(hostapd_config=self.ap_5g)
+ self.access_point.start_ap(hostapd_config=self.ap_5g)
def setup_test(self):
for fd in self.fuchsia_devices:
@@ -150,7 +150,13 @@
def teardown_class(self):
if self.start_access_point:
- self.access_points[0].stop_all_aps()
+ self.download_ap_logs()
+ self.access_point.stop_all_aps()
+
+ def on_fail(self, test_name, begin_time):
+ for fd in self.fuchsia_devices:
+ super().on_device_fail(fd, test_name, begin_time)
+ fd.configure_wlan(association_mechanism='drivers')
"""Helper Functions"""
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/WlanTargetSecurityTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/WlanTargetSecurityTest.py
index a8d44f4..2debf65 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/WlanTargetSecurityTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/WlanTargetSecurityTest.py
@@ -16,16 +16,16 @@
from acts import asserts
from acts import utils
-from acts.base_test import BaseTestClass
from acts.controllers.access_point import setup_ap
from acts.controllers.ap_lib import hostapd_constants
from acts.controllers.ap_lib.hostapd_security import Security
from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device
+from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
# TODO(fxb/68956): Add security protocol check to mixed mode tests when info is
# available.
-class WlanTargetSecurityTest(BaseTestClass):
+class WlanTargetSecurityTest(AbstractDeviceWlanDeviceBaseTest):
"""Tests Fuchsia's target security concept and security upgrading
Testbed Requirements:
@@ -49,8 +49,9 @@
self.dut.disconnect()
self.access_point.stop_all_aps()
- def setup_test(self):
+ def teardown_test(self):
self.dut.disconnect()
+ self.download_ap_logs()
self.access_point.stop_all_aps()
def on_fail(self, test_name, begin_time):
@@ -288,10 +289,14 @@
def test_associate_wpa3_ap_with_wpa_target_security(self):
ssid, password = self.setup_ap(hostapd_constants.WPA3_STRING)
- asserts.assert_true(
+ asserts.assert_false(
self.dut.associate(ssid,
target_security=hostapd_constants.WPA_STRING,
- target_pwd=password), 'Failed to associate.')
+ target_pwd=password),
+ 'Expected failure to associate. WPA credentials for WPA3 was '
+ 'temporarily disabled, see https://fxbug.dev/85817 for context. '
+ 'If this feature was reenabled, please update this test\'s '
+ 'expectation.')
def test_associate_wpa3_ap_with_wpa2_target_security(self):
ssid, password = self.setup_ap(hostapd_constants.WPA3_STRING)
@@ -325,10 +330,14 @@
def test_associate_wpa2_wpa3_ap_with_wpa_target_security(self):
ssid, password = self.setup_ap(
hostapd_constants.WPA2_WPA3_MIXED_STRING)
- asserts.assert_true(
+ asserts.assert_false(
self.dut.associate(ssid,
target_security=hostapd_constants.WPA_STRING,
- target_pwd=password), 'Failed to associate.')
+ target_pwd=password),
+ 'Expected failure to associate. WPA credentials for WPA3 was '
+ 'temporarily disabled, see https://fxbug.dev/85817 for context. '
+ 'If this feature was reenabled, please update this test\'s '
+ 'expectation.')
def test_associate_wpa2_wpa3_ap_with_wpa2_target_security(self):
ssid, password = self.setup_ap(
diff --git a/acts_tests/tests/google/fuchsia/wlan/misc/WlanInterfaceTest.py b/acts_tests/tests/google/fuchsia/wlan/misc/WlanInterfaceTest.py
index 4994dd2..3e2b707 100644
--- a/acts_tests/tests/google/fuchsia/wlan/misc/WlanInterfaceTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/misc/WlanInterfaceTest.py
@@ -16,7 +16,6 @@
from acts import signals
-from acts.base_test import BaseTestClass
from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device
from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
@@ -37,9 +36,6 @@
# Default is an Fuchsia device
self.dut = create_wlan_device(self.fuchsia_devices[0])
- def on_fail(self, test_name, begin_time):
- super().on_fail(test_name, begin_time)
-
def test_destroy_iface(self):
"""Test that we don't error out when destroying the WLAN interface.
diff --git a/acts_tests/tests/google/fuchsia/wlan/misc/WlanMiscScenarioTest.py b/acts_tests/tests/google/fuchsia/wlan/misc/WlanMiscScenarioTest.py
index 24b62dd..950015d 100644
--- a/acts_tests/tests/google/fuchsia/wlan/misc/WlanMiscScenarioTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/misc/WlanMiscScenarioTest.py
@@ -29,6 +29,7 @@
fit into a specific test category, but should still be run in CI to catch
regressions.
"""
+
def setup_class(self):
super().setup_class()
dut = self.user_params.get('dut', None)
@@ -49,8 +50,9 @@
self.dut.disconnect()
self.access_point.stop_all_aps()
- def setup_test(self):
+ def teardown_test(self):
self.dut.disconnect()
+ self.download_ap_logs()
self.access_point.stop_all_aps()
def on_fail(self, test_name, begin_time):
diff --git a/acts_tests/tests/google/fuchsia/wlan/performance/ChannelSweepTest.py b/acts_tests/tests/google/fuchsia/wlan/performance/ChannelSweepTest.py
index b9f26bf..8ea7891 100644
--- a/acts_tests/tests/google/fuchsia/wlan/performance/ChannelSweepTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/performance/ChannelSweepTest.py
@@ -35,6 +35,7 @@
from acts.controllers.ap_lib.hostapd_security import Security
from acts.controllers.iperf_server import IPerfResult
from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device
+from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
N_CAPABILITIES_DEFAULT = [
@@ -75,7 +76,7 @@
return settings.get('test_name')
-class ChannelSweepTest(WifiBaseTest):
+class ChannelSweepTest(AbstractDeviceWlanDeviceBaseTest):
"""Tests channel performance and regulatory compliance..
Testbed Requirement:
@@ -124,11 +125,16 @@
try:
self.iperf_server = self.iperf_servers[0]
self.iperf_server.start()
- self.iperf_client = self.iperf_clients[0]
except AttributeError:
self.log.warn(
'Missing iperf config. Throughput cannot be measured, so only '
'association will be tested.')
+
+ if hasattr(self, "iperf_clients") and self.iperf_clients:
+ self.iperf_client = self.iperf_clients[0]
+ else:
+ self.iperf_client = self.dut.create_iperf_client()
+
self.regulatory_results = "====CountryCode,Channel,Frequency,ChannelBandwith,Connected/Not-Connected====\n"
def teardown_class(self):
@@ -169,12 +175,9 @@
ad.droid.goToSleepNow()
self.dut.turn_location_off_and_scan_toggle_off()
self.dut.disconnect()
+ self.download_ap_logs()
self.access_point.stop_all_aps()
- 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)
-
def set_dut_country_code(self, country_code):
"""Set the country code on the DUT. Then verify that the country
code was set successfully
diff --git a/acts_tests/tests/google/fuchsia/wlan/performance/WlanRvrTest.py b/acts_tests/tests/google/fuchsia/wlan/performance/WlanRvrTest.py
index 0147b7b..545bbc5 100644
--- a/acts_tests/tests/google/fuchsia/wlan/performance/WlanRvrTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/performance/WlanRvrTest.py
@@ -13,6 +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.
+import os
import time
from acts import asserts
@@ -41,6 +42,8 @@
RVR_GRAPH_SUMMARY_FILE = 'rvr_summary.html'
+DAD_TIMEOUT_SEC = 30
+
def create_rvr_graph(test_name, graph_path, graph_data):
"""Creates the RvR graphs
@@ -107,6 +110,7 @@
* One attenuator
* One Linux iPerf Server
"""
+
def __init__(self, controllers):
WifiBaseTest.__init__(self, controllers)
self.rvr_graph_summary = []
@@ -157,7 +161,6 @@
'debug_post_traffic_cmd', None))
self.router_adv_daemon = None
- self.check_if_has_private_local_ipv6_address = True
if self.ending_attn == 'auto':
self.use_auto_end = True
@@ -176,7 +179,11 @@
self.attenuators, 'attenuator_ports_wifi_5g')
self.iperf_server = self.iperf_servers[0]
- self.dut_iperf_client = self.iperf_clients[0]
+
+ if hasattr(self, "iperf_clients") and self.iperf_clients:
+ self.dut_iperf_client = self.iperf_clients[0]
+ else:
+ self.dut_iperf_client = self.dut.create_iperf_client()
self.access_point.stop_all_aps()
@@ -207,6 +214,8 @@
'to Exception')
self.log.info(e)
+ super().teardown_class()
+
def on_fail(self, test_name, begin_time):
super().on_fail(test_name, begin_time)
self.cleanup_tests()
@@ -218,6 +227,11 @@
"""
if self.router_adv_daemon:
+ output_path = context.get_current_context().get_base_output_path()
+ full_output_path = os.path.join(output_path, "radvd_log.txt")
+ radvd_log_file = open(full_output_path, 'w')
+ radvd_log_file.write(self.router_adv_daemon.pull_logs())
+ radvd_log_file.close()
self.router_adv_daemon.stop()
if hasattr(self, "android_devices"):
for ad in self.android_devices:
@@ -228,8 +242,87 @@
self.dut.turn_location_off_and_scan_toggle_off()
self.dut.disconnect()
self.dut.reset_wifi()
+ self.download_ap_logs()
self.access_point.stop_all_aps()
+ def _wait_for_ipv4_addrs(self):
+ """Wait for an IPv4 addresses to become available on the DUT and iperf
+ server.
+
+ Returns:
+ A string containing the private IPv4 address of the iperf server.
+
+ Raises:
+ TestFailure: If unable to acquire a IPv4 address.
+ """
+ ip_address_checker_counter = 0
+ ip_address_checker_max_attempts = 3
+ while ip_address_checker_counter < ip_address_checker_max_attempts:
+ self.iperf_server.renew_test_interface_ip_address()
+ iperf_server_ip_addresses = (
+ self.iperf_server.get_interface_ip_addresses(
+ self.iperf_server.test_interface))
+ dut_ip_addresses = self.dut.get_interface_ip_addresses(
+ self.dut_iperf_client.test_interface)
+
+ self.log.info(
+ 'IPerf server IP info: {}'.format(iperf_server_ip_addresses))
+ self.log.info('DUT IP info: {}'.format(dut_ip_addresses))
+
+ if not iperf_server_ip_addresses['ipv4_private']:
+ self.log.warn('Unable to get the iperf server IPv4 '
+ 'address. Retrying...')
+ ip_address_checker_counter += 1
+ time.sleep(1)
+ continue
+
+ if dut_ip_addresses['ipv4_private']:
+ return iperf_server_ip_addresses['ipv4_private'][0]
+
+ self.log.warn('Unable to get the DUT IPv4 address starting at '
+ 'attenuation "{}". Retrying...'.format(
+ self.starting_attn))
+ ip_address_checker_counter += 1
+ time.sleep(1)
+
+ asserts.fail(
+ 'IPv4 addresses are not available on both the DUT and iperf server.'
+ )
+
+ def _wait_for_dad(self, device, test_interface):
+ """Wait for Duplicate Address Detection to resolve so that an
+ private-local IPv6 address is available for test.
+
+ Args:
+ device: implementor of get_interface_ip_addresses
+ test_interface: name of interface that DAD is operating on
+
+ Returns:
+ A string containing the private-local IPv6 address of the device.
+
+ Raises:
+ TestFailure: If unable to acquire an IPv6 address.
+ """
+ now = time.time()
+ start = now
+ elapsed = now - start
+
+ while elapsed < DAD_TIMEOUT_SEC:
+ addrs = device.get_interface_ip_addresses(test_interface)
+ now = time.time()
+ elapsed = now - start
+ if addrs['ipv6_private_local']:
+ # DAD has completed
+ addr = addrs['ipv6_private_local'][0]
+ self.log.info('DAD resolved with "{}" after {}s'.format(
+ addr, elapsed))
+ return addr
+ time.sleep(1)
+ else:
+ asserts.fail(
+ 'Unable to acquire a private-local IPv6 address for testing '
+ 'after {}s'.format(elapsed))
+
def run_rvr(self,
ssid,
security_mode=None,
@@ -251,7 +344,6 @@
"""
throughput = []
relative_attn = []
- self.check_if_has_private_local_ipv6_address = True
if band == '2g':
rvr_attenuators = self.attenuators_2g
elif band == '5g':
@@ -259,7 +351,7 @@
else:
raise ValueError('Invalid WLAN band specified: %s' % band)
if ip_version == 6:
- ravdvd_config = RadvdConfig(
+ radvd_config = RadvdConfig(
prefix=RADVD_PREFIX,
adv_send_advert=radvd_constants.ADV_SEND_ADVERT_ON,
adv_on_link=radvd_constants.ADV_ON_LINK_ON,
@@ -267,7 +359,7 @@
self.router_adv_daemon = Radvd(
self.access_point.ssh,
self.access_point.interfaces.get_bridge_interface()[0])
- self.router_adv_daemon.start(ravdvd_config)
+ self.router_adv_daemon.start(radvd_config)
for rvr_loop_counter in range(0, self.debug_loop_count):
for rvr_attenuator in rvr_attenuators:
@@ -286,66 +378,27 @@
break
else:
associate_counter += 1
- if associate_counter == associate_max_attempts:
+ else:
asserts.fail('Unable to associate at starting '
'attenuation: %s' % self.starting_attn)
- ip_address_checker_counter = 0
- ip_address_checker_max_attempts = 3
- while ip_address_checker_counter < ip_address_checker_max_attempts:
+ if ip_version == 4:
+ iperf_server_ip_address = self._wait_for_ipv4_addrs()
+ elif ip_version == 6:
self.iperf_server.renew_test_interface_ip_address()
- iperf_server_ip_addresses = (
- self.iperf_server.get_interface_ip_addresses(
- self.iperf_server.test_interface))
- dut_ip_addresses = self.dut.get_interface_ip_addresses(
- self.dut_iperf_client.test_interface)
- self.log.info('IPerf server IP info: %s' %
- iperf_server_ip_addresses)
- self.log.info('DUT IP info: %s' % dut_ip_addresses)
- if ip_version == 4:
- if iperf_server_ip_addresses['ipv4_private']:
- iperf_server_ip_address = (
- iperf_server_ip_addresses['ipv4_private'][0])
- if not dut_ip_addresses['ipv4_private']:
- self.log.warn('Unable to get IPv4 address at starting '
- 'attenuation: %s Retrying.' %
- self.starting_attn)
- ip_address_checker_counter += 1
- time.sleep(1)
- else:
- break
- elif ip_version == 6:
- if iperf_server_ip_addresses['ipv6_private_local']:
- iperf_server_ip_address = (
- iperf_server_ip_addresses['ipv6_private_local'][0])
- else:
- self.check_if_has_private_local_ipv6_address = False
- iperf_server_ip_address = (
- '%s%%%s' %
- (iperf_server_ip_addresses['ipv6_link_local'][0],
- self.dut_iperf_client.test_interface))
- if self.check_if_has_private_local_ipv6_address:
- if not dut_ip_addresses['ipv6_private_local']:
- self.log.warn('Unable to get IPv6 address at '
- 'starting attenuation: %s' %
- self.starting_attn)
- ip_address_checker_counter += 1
- time.sleep(1)
- else:
- break
- else:
- break
- else:
- raise ValueError('Invalid IP version: %s' % ip_version)
- if ip_address_checker_counter == ip_address_checker_max_attempts:
- if self.dut.can_ping(iperf_server_ip_address):
- self.log.error('IPerf server is pingable. Continuing with '
- 'test. The missing IP address information '
- 'should be marked as a bug.')
- else:
- asserts.fail('DUT was unable to get IPv%s address and '
- 'could not ping the IPerf server.' %
- str(ip_version))
+ self.log.info('Waiting for iperf server to complete Duplicate '
+ 'Address Detection...')
+ iperf_server_ip_address = self._wait_for_dad(
+ self.iperf_server, self.iperf_server.test_interface)
+
+ self.log.info('Waiting for DUT to complete Duplicate Address '
+ 'Detection for "{}"...'.format(
+ self.dut_iperf_client.test_interface))
+ _ = self._wait_for_dad(self.dut,
+ self.dut_iperf_client.test_interface)
+ else:
+ raise ValueError('Invalid IP version: {}'.format(ip_version))
+
throughput, relative_attn = (self.rvr_loop(
traffic_dir,
rvr_attenuators,
@@ -472,19 +525,13 @@
self.log.info('DUT has the following IPv4 address: "%s"' %
dut_ip_addresses['ipv4_private'][0])
elif ip_version == 6:
- if self.check_if_has_private_local_ipv6_address:
- if not dut_ip_addresses['ipv6_private_local']:
- self.log.info(
- 'DUT does not have an IPv6 address. '
- 'Traffic attempt to be run if the server '
- 'is pingable.')
- else:
- self.log.info(
- 'DUT has the following IPv6 address: "%s"' %
- dut_ip_addresses['ipv6_private_local'][0])
+ if not dut_ip_addresses['ipv6_private_local']:
+ self.log.info('DUT does not have an IPv6 address. '
+ 'Traffic attempt to be run if the server '
+ 'is pingable.')
else:
self.log.info('DUT has the following IPv6 address: "%s"' %
- dut_ip_addresses['ipv6_link_local'][0])
+ dut_ip_addresses['ipv6_private_local'][0])
server_pingable = self.dut.can_ping(iperf_server_ip_address)
if not server_pingable:
self.log.info('Iperf server "%s" is not pingable. Marking '
diff --git a/acts_tests/tests/google/fuchsia/wlan/performance/WlanWmmTest.py b/acts_tests/tests/google/fuchsia/wlan/performance/WlanWmmTest.py
index 64e5431..adbb5f6 100644
--- a/acts_tests/tests/google/fuchsia/wlan/performance/WlanWmmTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/performance/WlanWmmTest.py
@@ -190,14 +190,17 @@
tc.wlan_device.disconnect()
tc.wlan_device.reset_wifi()
if tc.access_point:
+ self.download_ap_logs()
tc.access_point.stop_all_aps()
def teardown_class(self):
for tc in self.wmm_transceivers:
tc.destroy_resources()
+ super().teardown_class()
def on_fail(self, test_name, begin_time):
- super().on_fail(test_name, begin_time)
+ for wlan_device in self.wlan_devices:
+ super().on_device_fail(wlan_device.device, test_name, begin_time)
def start_ap_with_wmm_params(self, ap_parameters, wmm_parameters):
"""Sets up WMM network on AP.
diff --git a/acts_tests/tests/google/fuchsia/wlan_policy/HiddenNetworksTest.py b/acts_tests/tests/google/fuchsia/wlan_policy/HiddenNetworksTest.py
index 98d8a19..7d294d2 100644
--- a/acts_tests/tests/google/fuchsia/wlan_policy/HiddenNetworksTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan_policy/HiddenNetworksTest.py
@@ -41,6 +41,7 @@
* One or more Fuchsia devices
* One Access Point
"""
+
def setup_class(self):
super().setup_class()
# Start an AP with a hidden network
diff --git a/acts_tests/tests/google/fuchsia/wlan_policy/PolicyScanTest.py b/acts_tests/tests/google/fuchsia/wlan_policy/PolicyScanTest.py
index c174bc7..efd8729 100644
--- a/acts_tests/tests/google/fuchsia/wlan_policy/PolicyScanTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan_policy/PolicyScanTest.py
@@ -31,6 +31,7 @@
* One or more Fuchsia devices
* One Whirlwind Access Point
"""
+
def setup_class(self):
super().setup_class()
if len(self.fuchsia_devices) < 1:
diff --git a/acts_tests/tests/google/fuchsia/wlan_policy/RegulatoryRecoveryTest.py b/acts_tests/tests/google/fuchsia/wlan_policy/RegulatoryRecoveryTest.py
index 5cf9ad7..9cfaf84 100644
--- a/acts_tests/tests/google/fuchsia/wlan_policy/RegulatoryRecoveryTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan_policy/RegulatoryRecoveryTest.py
@@ -32,6 +32,7 @@
If no configuration information is provided, the test will default to
toggling between WW and US.
"""
+
def setup_class(self):
super().setup_class()
if len(self.fuchsia_devices) < 1:
@@ -40,13 +41,16 @@
self.config_test_params = self.user_params.get(
"regulatory_recovery_test_params", {})
self.country_code = self.config_test_params.get("country_code", "US")
+ self.negative_test = self.config_test_params.get(
+ "negative_test", False)
for fd in self.fuchsia_devices:
fd.configure_wlan(association_mechanism='policy')
def teardown_class(self):
- for fd in self.fuchsia_devices:
- fd.wlan_controller.set_country_code(self.country_code)
+ if not self.negative_test:
+ for fd in self.fuchsia_devices:
+ fd.wlan_controller.set_country_code(self.country_code)
super().teardown_class()
@@ -66,6 +70,27 @@
fd.wlan_policy_controller.stop_client_connections()
fd.wlan_ap_policy_lib.wlanStopAllAccessPoint()
+ def set_country_code(self, fd):
+ try:
+ fd.wlan_controller.set_country_code(self.country_code)
+ except EnvironmentError as e:
+ if self.negative_test:
+ # In the negative case, setting the country code for an
+ # invalid country should fail.
+ pass
+ else:
+ # If this is not a negative test case, re-raise the
+ # exception.
+ raise e
+ else:
+ # The negative test case should have failed to set the country
+ # code and the positive test case should succeed.
+ if self.negative_test:
+ raise EnvironmentError(
+ "Setting invalid country code succeeded.")
+ else:
+ pass
+
def test_interfaces_not_recreated_when_initially_disabled(self):
"""This test ensures that after a new regulatory region is applied
while client connections and access points are disabled, no new
@@ -73,7 +98,7 @@
"""
for fd in self.fuchsia_devices:
# Set the region code.
- fd.wlan_controller.set_country_code(self.country_code)
+ self.set_country_code(fd)
# Reset the listeners and verify the current state.
fd.wlan_policy_lib.wlanSetNewListener()
@@ -116,7 +141,7 @@
"local_only", "any")
# Set the country code.
- fd.wlan_controller.set_country_code(self.country_code)
+ self.set_country_code(fd)
# Reset the listeners and verify the current state.
fd.wlan_policy_lib.wlanSetNewListener()
diff --git a/acts_tests/tests/google/fuchsia/wlan_policy/SavedNetworksTest.py b/acts_tests/tests/google/fuchsia/wlan_policy/SavedNetworksTest.py
index 8b256c3..b9d9721 100644
--- a/acts_tests/tests/google/fuchsia/wlan_policy/SavedNetworksTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan_policy/SavedNetworksTest.py
@@ -55,6 +55,7 @@
* One or more Fuchsia devices
* One Access Point
"""
+
def setup_class(self):
super().setup_class()
# Keep track of whether we have started an access point in a test
@@ -86,8 +87,9 @@
password: The password to save for the network. Empty string represents
no password, and PSK should be provided as 64 character hex string.
"""
- if not fd.wlan_policy_controller.save_network(
- ssid, security_type, password=password):
+ if fd.wlan_policy_controller.save_network(ssid,
+ security_type,
+ password=password):
self.log.info(
"Attempting to save bad network config %s did not give an error"
% ssid)
diff --git a/acts_tests/tests/google/fuchsia/wlan_policy/StartStopClientConnectionsTest.py b/acts_tests/tests/google/fuchsia/wlan_policy/StartStopClientConnectionsTest.py
index 3f585a2..7643a05 100644
--- a/acts_tests/tests/google/fuchsia/wlan_policy/StartStopClientConnectionsTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan_policy/StartStopClientConnectionsTest.py
@@ -20,12 +20,14 @@
from acts.controllers.ap_lib import hostapd_security
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
from acts.utils import rand_ascii_str
+import time
DISCONNECTED = "Disconnected"
CONNECTION_STOPPED = "ConnectionStopped"
CONNECTIONS_ENABLED = "ConnectionsEnabled"
CONNECTIONS_DISABLED = "ConnectionsDisabled"
WPA2 = "wpa2"
+UPDATE_TIMEOUT_SEC = 5
class StartStopClientConnectionsTest(WifiBaseTest):
@@ -36,6 +38,7 @@
* One or more Fuchsia devices
* One Access Point
"""
+
def setup_class(self):
super().setup_class()
# Start an AP with a hidden network
@@ -88,6 +91,42 @@
raise signals.TestFailure(
"Failed to get expected connect response")
+ def await_state_update(self, fd, desired_state, timeout):
+ """ This function polls the policy client state until it converges to
+ the caller's desired state.
+
+ Args:
+ fd: A FuchsiaDevice
+ desired_state: The expected client policy state.
+ timeout: Number of seconds to wait for the policy state to become
+ the desired_state.
+ Returns:
+ None assuming the desired state has been reached.
+ Raises:
+ TestFailure if the desired state is not reached by the timeout.
+ """
+ start_time = time.time()
+ curr_state = None
+ while time.time() < start_time + timeout:
+ fd.wlan_policy_lib.wlanSetNewListener()
+ curr_state = fd.wlan_policy_lib.wlanGetUpdate()
+ if curr_state.get("error"):
+ self.log.error("Error occurred getting status update: %s" %
+ curr_state.get("error"))
+ raise EnvironmentError("Failed to get update")
+
+ if curr_state.get("result") and curr_state.get(
+ "result") == desired_state:
+ return
+
+ time.sleep(1)
+
+ self.log.error(
+ "Client state did not converge to the expected state in %s "
+ "seconds. Expected update: %s Actual update: %s" %
+ (timeout, desired_state, curr_state))
+ raise signals.TestFailure("Client policy layer is in unexpected state")
+
def test_stop_client_connections_update(self):
for fd in self.fuchsia_devices:
if not fd.wlan_policy_controller.stop_client_connections():
@@ -95,21 +134,8 @@
# Check that the most recent update says that the device is not
# connected to anything and client connections are disabled
- fd.wlan_policy_lib.wlanSetNewListener()
- result_update = fd.wlan_policy_lib.wlanGetUpdate()
- if result_update.get("error") != None:
- self.log.error("Error occurred getting status update: %s" %
- result_update.get("error"))
- raise EnvironmentError("Failed to get update")
-
expected_update = {"networks": [], "state": CONNECTIONS_DISABLED}
- if result_update.get("result") != expected_update:
- self.log.error(
- "Most recent status update does not indicate client "
- "connections have stopped. Expected update: %s Actual update: %s"
- % (expected_update, result_update.get('result')))
- raise signals.TestFailure(
- "Incorrect update after stopping client connections")
+ self.await_state_update(fd, expected_update, UPDATE_TIMEOUT_SEC)
def test_start_client_connections_update(self):
for fd in self.fuchsia_devices:
@@ -118,21 +144,8 @@
# Check that the most recent update says that the device is not
# connected to anything and client connections are disabled
- fd.wlan_policy_lib.wlanSetNewListener()
- result_update = fd.wlan_policy_lib.wlanGetUpdate()
- if result_update.get("error") != None:
- self.log.error("Error occurred getting status update: %s" %
- result_update.get("error"))
- raise EnvironmentError("Failed to get update")
-
expected_update = {"networks": [], "state": CONNECTIONS_ENABLED}
- if result_update.get("result") != expected_update:
- self.log.error(
- "Most recent status update does not indicate client "
- "connections are enabled. Expected update: %s\nActual update:"
- % (expected_update, result_update))
- raise signals.TestFailure(
- "Incorrect update after starting client connections")
+ self.await_state_update(fd, expected_update, UPDATE_TIMEOUT_SEC)
def test_stop_client_connections_rejects_connections(self):
# Test that if we turn client connections off, our requests to connect
diff --git a/acts_tests/tests/google/gnss/FlpTtffTest.py b/acts_tests/tests/google/gnss/FlpTtffTest.py
index 59b19b5..0a30fe8 100644
--- a/acts_tests/tests/google/gnss/FlpTtffTest.py
+++ b/acts_tests/tests/google/gnss/FlpTtffTest.py
@@ -14,20 +14,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from acts import utils
from acts import asserts
from acts import signals
from acts.base_test import BaseTestClass
from acts.test_decorators import test_tracker_info
from acts.utils import get_current_epoch_time
from acts_contrib.test_utils.wifi.wifi_test_utils import wifi_toggle_state
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_logger
-from acts_contrib.test_utils.tel.tel_test_utils import stop_qxdm_logger
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_logger
+from acts_contrib.test_utils.tel.tel_logging_utils import stop_qxdm_logger
+from acts_contrib.test_utils.tel.tel_logging_utils import start_adb_tcpdump
+from acts_contrib.test_utils.tel.tel_logging_utils import stop_adb_tcpdump
+from acts_contrib.test_utils.tel.tel_logging_utils import get_tcpdump_log
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import abort_all_tests
from acts_contrib.test_utils.gnss.gnss_test_utils import get_baseband_and_gms_version
from acts_contrib.test_utils.gnss.gnss_test_utils import _init_device
-from acts_contrib.test_utils.gnss.gnss_test_utils import check_location_service
from acts_contrib.test_utils.gnss.gnss_test_utils import clear_logd_gnss_qxdm_log
from acts_contrib.test_utils.gnss.gnss_test_utils import set_mobile_data
from acts_contrib.test_utils.gnss.gnss_test_utils import get_gnss_qxdm_log
@@ -40,9 +40,6 @@
from acts_contrib.test_utils.gnss.gnss_test_utils import connect_to_wifi_network
from acts_contrib.test_utils.gnss.gnss_test_utils import gnss_tracking_via_gtw_gpstool
from acts_contrib.test_utils.gnss.gnss_test_utils import parse_gtw_gpstool_log
-from acts_contrib.test_utils.tel.tel_test_utils import start_adb_tcpdump
-from acts_contrib.test_utils.tel.tel_test_utils import stop_adb_tcpdump
-from acts_contrib.test_utils.tel.tel_test_utils import get_tcpdump_log
class FlpTtffTest(BaseTestClass):
diff --git a/acts_tests/tests/google/gnss/GnssConcurrencyTest.py b/acts_tests/tests/google/gnss/GnssConcurrencyTest.py
index 0eb714d..c03ea08 100644
--- a/acts_tests/tests/google/gnss/GnssConcurrencyTest.py
+++ b/acts_tests/tests/google/gnss/GnssConcurrencyTest.py
@@ -17,13 +17,12 @@
import time
import datetime
from acts import utils
-from acts import asserts
from acts import signals
from acts.base_test import BaseTestClass
-from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.tel_logging_utils import start_adb_tcpdump
+from acts_contrib.test_utils.tel.tel_logging_utils import stop_adb_tcpdump
+from acts_contrib.test_utils.tel.tel_logging_utils import get_tcpdump_log
from acts_contrib.test_utils.gnss import gnss_test_utils as gutils
-from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
-from acts_contrib.test_utils.tel import tel_test_utils as tutils
CONCURRENCY_TYPE = {
"gnss": "GNSS location received",
@@ -47,7 +46,7 @@
def setup_test(self):
gutils.start_pixel_logger(self.ad)
- tutils.start_adb_tcpdump(self.ad)
+ start_adb_tcpdump(self.ad)
# related properties
gutils.check_location_service(self.ad)
gutils.get_baseband_and_gms_version(self.ad)
@@ -55,12 +54,12 @@
def teardown_test(self):
gutils.stop_pixel_logger(self.ad)
- tutils.stop_adb_tcpdump(self.ad)
+ stop_adb_tcpdump(self.ad)
def on_fail(self, test_name, begin_time):
self.ad.take_bug_report(test_name, begin_time)
gutils.get_gnss_qxdm_log(self.ad, self.qdsp6m_path)
- tutils.get_tcpdump_log(self.ad, test_name, begin_time)
+ get_tcpdump_log(self.ad, test_name, begin_time)
def load_chre_nanoapp(self):
""" Load CHRE nanoapp to target Android Device. """
diff --git a/acts_tests/tests/google/gnss/GnssFunctionTest.py b/acts_tests/tests/google/gnss/GnssFunctionTest.py
index 1c48601..706acca 100644
--- a/acts_tests/tests/google/gnss/GnssFunctionTest.py
+++ b/acts_tests/tests/google/gnss/GnssFunctionTest.py
@@ -36,8 +36,8 @@
from acts_contrib.test_utils.tel.tel_test_utils import abort_all_tests
from acts_contrib.test_utils.tel.tel_test_utils import stop_qxdm_logger
from acts_contrib.test_utils.tel.tel_test_utils import check_call_state_connected_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
from acts_contrib.test_utils.tel.tel_test_utils import http_file_download_by_sl4a
from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_logger
from acts_contrib.test_utils.tel.tel_test_utils import trigger_modem_crash
diff --git a/acts_tests/tests/google/gnss/LocationPlatinumTest.py b/acts_tests/tests/google/gnss/LocationPlatinumTest.py
index 110748f..ec80d87 100644
--- a/acts_tests/tests/google/gnss/LocationPlatinumTest.py
+++ b/acts_tests/tests/google/gnss/LocationPlatinumTest.py
@@ -22,7 +22,11 @@
from acts.base_test import BaseTestClass
from acts_contrib.test_utils.gnss import gnss_test_utils as gutils
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
-from acts_contrib.test_utils.tel import tel_test_utils as tutils
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_logger
+from acts_contrib.test_utils.tel.tel_logging_utils import stop_qxdm_logger
+from acts_contrib.test_utils.tel.tel_logging_utils import start_adb_tcpdump
+from acts_contrib.test_utils.tel.tel_logging_utils import stop_adb_tcpdump
+from acts_contrib.test_utils.tel.tel_logging_utils import get_tcpdump_log
BACKGROUND_LOCATION_PERMISSION = 'android.permission.ACCESS_BACKGROUND_LOCATION'
APP_CLEAN_UP_TIME = 60
@@ -61,8 +65,8 @@
gutils._init_device(self.ad)
self.begin_time = utils.get_current_epoch_time()
gutils.clear_logd_gnss_qxdm_log(self.ad)
- tutils.start_qxdm_logger(self.ad, self.begin_time)
- tutils.start_adb_tcpdump(self.ad)
+ start_qxdm_logger(self.ad, self.begin_time)
+ start_adb_tcpdump(self.ad)
def setup_test(self):
"""Prepare device with mobile data, wifi and gps ready for test """
@@ -78,10 +82,10 @@
BACKGROUND_LOCATION_PERMISSION)
def teardown_class(self):
- tutils.stop_qxdm_logger(self.ad)
+ stop_qxdm_logger(self.ad)
gutils.get_gnss_qxdm_log(self.ad, self.qdsp6m_path)
- tutils.stop_adb_tcpdump(self.ad)
- tutils.get_tcpdump_log(self.ad, 'location_platinum', self.begin_time)
+ stop_adb_tcpdump(self.ad)
+ get_tcpdump_log(self.ad, 'location_platinum', self.begin_time)
self.ad.take_bug_report('location_platinum', self.begin_time)
def get_and_verify_ttff(self, mode):
diff --git a/acts_tests/tests/google/net/ApfCountersTest.py b/acts_tests/tests/google/net/ApfCountersTest.py
index 0b4f3dc..4d602b2 100755
--- a/acts_tests/tests/google/net/ApfCountersTest.py
+++ b/acts_tests/tests/google/net/ApfCountersTest.py
@@ -35,12 +35,11 @@
WifiEnums = wutils.WifiEnums
RA_SCRIPT = 'sendra.py'
-SCAPY = 'scapy-2.2.0.tar.gz'
-SCAPY_INSTALL_COMMAND = 'sudo python setup.py install'
PROC_NET_SNMP6 = '/proc/net/snmp6'
LIFETIME_FRACTION = 6
LIFETIME = 180
INTERVAL = 2
+WLAN0= "wlan0"
class ApfCountersTest(WifiBaseTest):
@@ -51,10 +50,11 @@
"test_IPv6_RA_with_RTT", )
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", ]
+ req_params = ["scapy"]
+ opt_param = ["reference_networks"]
self.unpack_userparams(
req_param_names=req_params, opt_param_names=opt_param)
@@ -73,13 +73,12 @@
# install scapy
current_dir = os.path.dirname(os.path.realpath(__file__))
send_ra = os.path.join(current_dir, RA_SCRIPT)
- send_scapy = os.path.join(current_dir, SCAPY)
- self.access_points[0].install_scapy(send_scapy, send_ra)
+ self.access_points[0].install_scapy(self.scapy[0], send_ra)
self.tcpdump_pid = None
def setup_test(self):
if 'RTT' not in self.test_name:
- self.tcpdump_pid = start_tcpdump(self.dut, self.test_name)
+ self.tcpdump_pid = start_tcpdump(self.dut, self.test_name, WLAN0)
def teardown_test(self):
if 'RTT' not in self.test_name:
@@ -94,6 +93,7 @@
del self.user_params["reference_networks"]
self.access_points[0].cleanup_scapy()
wutils.reset_wifi(self.dut)
+ self.dut.adb.shell("settings put global stay_on_while_plugged_in 7")
""" Helper methods """
@@ -163,6 +163,8 @@
ra_count_latest = self._get_icmp6intype134()
asserts.assert_true(ra_count_latest == ra_count + 1,
"Device dropped the first RA in sequence")
+ self.dut.adb.shell("settings put global stay_on_while_plugged_in 0")
+ self.dut.droid.goToSleepNow()
# Generate and send 'x' number of duplicate RAs, for 1/6th of the the
# lifetime of the original RA. Test assumes that the original RA has a
@@ -212,7 +214,7 @@
ra_count = self._get_icmp6intype134()
# start tcpdump on the device
- tcpdump_pid = start_tcpdump(self.dut, self.test_name)
+ tcpdump_pid = start_tcpdump(self.dut, self.test_name, WLAN0)
# send RA with differnt re-trans time
for rtt in rtt_list:
diff --git a/acts_tests/tests/google/net/BluetoothTetheringTest.py b/acts_tests/tests/google/net/BluetoothTetheringTest.py
index e4d3c67..318ed53 100644
--- a/acts_tests/tests/google/net/BluetoothTetheringTest.py
+++ b/acts_tests/tests/google/net/BluetoothTetheringTest.py
@@ -22,7 +22,7 @@
from acts_contrib.test_utils.bt.bt_test_utils import orchestrate_and_verify_pan_connection
from acts_contrib.test_utils.bt.bt_test_utils import setup_multiple_devices_for_bt_test
from acts_contrib.test_utils.net import net_test_utils as nutils
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_cell_data_connection
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
DEFAULT_PING_URL = "https://www.google.com/robots.txt"
diff --git a/acts_tests/tests/google/net/CaptivePortalTest.py b/acts_tests/tests/google/net/CaptivePortalTest.py
index 7542ee9..c44ff9b 100644
--- a/acts_tests/tests/google/net/CaptivePortalTest.py
+++ b/acts_tests/tests/google/net/CaptivePortalTest.py
@@ -17,7 +17,6 @@
from acts import asserts
from acts.controllers.openwrt_ap import MOBLY_CONTROLLER_CONFIG_NAME as OPENWRT
-from acts import base_test
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.net import connectivity_const as cconst
from acts_contrib.test_utils.net import connectivity_test_utils as cutils
@@ -32,6 +31,7 @@
ACCEPT_CONTINUE = "Accept and Continue"
CONNECTED = "Connected"
SIGN_IN_NOTIFICATION = "Sign in to network"
+FAS_FDQN = "netsplashpage.net"
class CaptivePortalTest(WifiBaseTest):
@@ -61,7 +61,7 @@
else:
self.configure_openwrt_ap_and_start(wpa_network=True)
self.wifi_network = self.openwrt.get_wifi_network()
- self.openwrt.network_setting.setup_captive_portal()
+ self.openwrt.network_setting.setup_captive_portal(FAS_FDQN)
def teardown_class(self):
"""Reset devices."""
@@ -87,7 +87,11 @@
uutils.has_element(self.dut, text="Network & internet"),
"Failed to find 'Network & internet' icon")
uutils.wait_and_click(self.dut, text="Network & internet")
- uutils.wait_and_click(self.dut, text="Internet")
+ android_version = self.dut.adb.getprop("ro.build.version.release")
+ if int(android_version) < 12:
+ uutils.wait_and_click(self.dut, text="Wi‑Fi")
+ else:
+ uutils.wait_and_click(self.dut, text="Internet")
def _verify_sign_in_notification(self):
"""Verify sign in notification shows for captive portal."""
@@ -102,7 +106,9 @@
return
asserts.fail("Failed to get sign in notification")
- def _verify_captive_portal(self, network, click_accept=ACCEPT_CONTINUE):
+ def _verify_captive_portal(self, network, user="username",
+ mail="user@example.net",
+ click_accept=ACCEPT_CONTINUE):
"""Connect to captive portal network using uicd workflow.
Steps:
@@ -112,15 +118,24 @@
Args:
network: captive portal network to connect to
+ user: Option for captive portal login in
+ mail: Option for captive portal login in
click_accept: Notification to select to accept captive portal
"""
# connect to captive portal wifi network
wutils.connect_to_wifi_network(
self.dut, network, check_connectivity=False)
-
+ # Wait for captive portal detection.
+ time.sleep(10)
# run ui automator
self._verify_sign_in_notification()
uutils.wait_and_click(self.dut, text="%s" % network["SSID"])
+ if uutils.has_element(self.dut, class_name="android.widget.EditText"):
+ uutils.wait_and_click(self.dut, class_name="android.widget.EditText")
+ self.dut.adb.shell("input text %s" % user)
+ self.dut.adb.shell("input keyevent 20")
+ self.dut.adb.shell("input text %s" % mail)
+ uutils.wait_and_click(self.dut, text="Accept Terms of Service")
if uutils.has_element(self.dut, text="%s" % click_accept):
uutils.wait_and_click(self.dut, text="%s" % click_accept)
@@ -185,7 +200,7 @@
# set private dns to strict mode
cutils.set_private_dns(self.dut,
cconst.PRIVATE_DNS_MODE_STRICT,
- cconst.DNS_GOOGLE)
+ cconst.DNS_GOOGLE_HOSTNAME)
# verify connection to captive portal network
self._verify_captive_portal(self.rk_captive_portal)
@@ -232,7 +247,7 @@
# set private dns to strict mode
cutils.set_private_dns(self.dut,
cconst.PRIVATE_DNS_MODE_STRICT,
- cconst.DNS_GOOGLE)
+ cconst.DNS_GOOGLE_HOSTNAME)
# verify connection to captive portal network
self._verify_captive_portal(self.gg_captive_portal)
@@ -247,7 +262,7 @@
3. Verify connectivity
"""
cutils.set_private_dns(self.dut, cconst.PRIVATE_DNS_MODE_OPPORTUNISTIC)
- self.openwrt.network_setting.service_manager.restart("nodogsplash")
+ self.openwrt.network_setting.service_manager.restart("opennds")
self._verify_captive_portal(self.wifi_network, click_accept="Continue")
@test_tracker_info(uuid="1419e36d-0303-44ba-bc60-4d707b45ef48")
@@ -260,7 +275,7 @@
3. Verify connectivity
"""
cutils.set_private_dns(self.dut, cconst.PRIVATE_DNS_MODE_OFF)
- self.openwrt.network_setting.service_manager.restart("nodogsplash")
+ self.openwrt.network_setting.service_manager.restart("opennds")
self._verify_captive_portal(self.wifi_network, click_accept="Continue")
@test_tracker_info(uuid="5aae44ee-fa62-47b9-9b3d-8121f9f92da1")
@@ -274,6 +289,8 @@
"""
cutils.set_private_dns(self.dut,
cconst.PRIVATE_DNS_MODE_STRICT,
- cconst.DNS_GOOGLE)
- self.openwrt.network_setting.service_manager.restart("nodogsplash")
+ cconst.DNS_GOOGLE_HOSTNAME)
+ self.openwrt.network_setting.service_manager.restart("opennds")
self._verify_captive_portal(self.wifi_network, click_accept="Continue")
+
+
diff --git a/acts_tests/tests/google/net/DNSTest.py b/acts_tests/tests/google/net/DNSTest.py
index d0f99d9..f4e23ec 100644
--- a/acts_tests/tests/google/net/DNSTest.py
+++ b/acts_tests/tests/google/net/DNSTest.py
@@ -17,6 +17,9 @@
from acts import asserts
from acts.controllers.openwrt_ap import MOBLY_CONTROLLER_CONFIG_NAME as OPENWRT
+from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.net import connectivity_const as cconst
+from acts_contrib.test_utils.net import connectivity_test_utils as cutils
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
from scapy.all import rdpcap, DNSRR, DNSQR, IP, IPv6
@@ -76,6 +79,52 @@
"""Return a random query name."""
return "%s-ds.metric.gstatic.com" % random.randint(0, 99999999)
+ def _block_dns_response_and_ping(self, test_qname):
+ """Block the DNS response and ping
+
+ Args:
+ test_qname: Address to ping
+ Returns:
+ Packets for the ping result
+ """
+ # Start tcpdump on OpenWrt
+ remote_pcap_path = \
+ self.openwrt.network_setting.start_tcpdump(self.test_name)
+ self.dut.log.info("Test query name = %s" % test_qname)
+ # Block the DNS response only before sending the DNS query
+ self.openwrt.network_setting.block_dns_response()
+ # Start send a query
+ self.ping(test_qname)
+ # Un-block the DNS response right after DNS query
+ self.openwrt.network_setting.unblock_dns_response()
+ local_pcap_path = self.openwrt.network_setting.stop_tcpdump(
+ remote_pcap_path, self.dut.device_log_path)
+ self.dut.log.info("pcap file path : %s" % local_pcap_path)
+ # Check DNSQR.qname in tcpdump to verify device retransmit the query
+ packets = rdpcap(local_pcap_path)
+ return packets
+
+ def _get_dnsqr_packets(self, packets, layer, qname):
+ """Filter the DNSQR packets with specific layer
+
+ Args:
+ packets: Packets that came from rdpcap function
+ layer: Keep the packets that contains this layer
+ qname: Keep the packets that related to this qname
+ Returns:
+ List of filtered packets
+ """
+ filtered_packets = []
+ for pkt in packets:
+ if not pkt.haslayer(DNSQR):
+ continue
+ if pkt[DNSQR].qname.decode().strip(".") != qname:
+ continue
+ if pkt.haslayer(layer):
+ filtered_packets.append(pkt)
+ return filtered_packets
+
+ @test_tracker_info(uuid="dd7b8c92-c0f4-4403-a0ae-57a703162d83")
def test_dns_query(self):
# Setup environment
wutils.connect_to_wifi_network(self.dut, self.wifi_network)
@@ -101,32 +150,32 @@
"Did not find match standard query response in tcpdump.")
asserts.assert_true(ping_result, "Device ping fail.")
+ @test_tracker_info(uuid="cd20c6e7-9c2e-4286-b08e-c8e40e413da5")
def test_dns_query_retransmit(self):
# Setup environment
wutils.connect_to_wifi_network(self.dut, self.wifi_network)
- self.openwrt.network_setting.block_dns_response()
- # Start tcpdump on OpenWrt
- remote_pcap_path = self.openwrt.network_setting.start_tcpdump(self.test_name)
- # Generate query name
test_qname = self.generate_query_qname()
- self.dut.log.info("Test query name = %s" % test_qname)
- # Start send a query
- self.ping(test_qname)
- local_pcap_path = self.openwrt.network_setting.stop_tcpdump(remote_pcap_path,
- self.dut.device_log_path)
- # Check DNSQR.qname in tcpdump to verify device retransmit the query
- packets = rdpcap(local_pcap_path)
- self.dut.log.info("pcap file path : %s" % local_pcap_path)
- pkt_count = 0
- pkt6_count = 0
- for pkt in packets:
- if pkt.haslayer(DNSQR) and pkt[DNSQR].qname.decode().strip(".") == test_qname:
- if pkt.haslayer(IP):
- pkt_count = pkt_count + 1
- if pkt.haslayer(IPv6):
- pkt6_count = pkt6_count + 1
- self.dut.log.info("IPv4 DNS query count : %s" % pkt_count)
- self.dut.log.info("IPv6 DNS query count : %s" % pkt6_count)
- self.openwrt.network_setting.unblock_dns_response()
- asserts.assert_true(pkt_count >= 2 or pkt6_count >= 2,
+ packets = self._block_dns_response_and_ping(test_qname)
+ pkts = self._get_dnsqr_packets(packets, IP, test_qname)
+ pkts6 = self._get_dnsqr_packets(packets, IPv6, test_qname)
+ self.dut.log.info("IPv4 DNS query count : %s" % len(pkts))
+ self.dut.log.info("IPv6 DNS query count : %s" % len(pkts6))
+ asserts.assert_true(len(pkts) >= 2 or len(pkts6) >= 2,
"Did not find match standard query in tcpdump.")
+
+ @test_tracker_info(uuid="5f58775d-ee7b-4d2e-8e77-77d41e821415")
+ def test_private_dns_query_retransmit(self):
+ # set private DNS mode
+ cutils.set_private_dns(self.dut, cconst.PRIVATE_DNS_MODE_STRICT)
+
+ # Setup environment
+ wutils.connect_to_wifi_network(self.dut, self.wifi_network)
+ test_qname = self.generate_query_qname()
+ packets = self._block_dns_response_and_ping(test_qname)
+ pkts = self._get_dnsqr_packets(packets, IP, test_qname)
+ pkts6 = self._get_dnsqr_packets(packets, IPv6, test_qname)
+ self.dut.log.info("IPv4 DNS query count : %s" % len(pkts))
+ self.dut.log.info("IPv6 DNS query count : %s" % len(pkts6))
+ asserts.assert_true(len(pkts) >= 2 or len(pkts6) >= 2,
+ "Did not find match standard query in tcpdump.")
+
diff --git a/acts_tests/tests/google/net/DataCostTest.py b/acts_tests/tests/google/net/DataCostTest.py
index 6174009..c8089d9 100644
--- a/acts_tests/tests/google/net/DataCostTest.py
+++ b/acts_tests/tests/google/net/DataCostTest.py
@@ -1,5 +1,5 @@
#
-# Copyright 2018 - The Android Open Source Project
+# Copyright 2022 - 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.
@@ -28,7 +28,7 @@
from acts.controllers import adb
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.net import net_test_utils as nutils
-from acts_contrib.test_utils.tel.tel_test_utils import _check_file_existance
+from acts_contrib.test_utils.tel.tel_test_utils import _check_file_existence
from acts_contrib.test_utils.tel.tel_test_utils import _generate_file_directory_and_file_name
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
from acts_contrib.test_utils.net.connectivity_const import MULTIPATH_PREFERENCE_NONE as NONE
@@ -252,7 +252,7 @@
self.download_file, DOWNLOAD_PATH)
file_path = os.path.join(file_folder, file_name)
self.log.info("File path: %s" % file_path)
- if _check_file_existance(ad, file_path):
+ if _check_file_existence(ad, file_path):
self.log.info("File exists. Removing file %s" % file_name)
ad.adb.shell("rm -rf %s%s" % (DOWNLOAD_PATH, file_name))
diff --git a/acts_tests/tests/google/net/DataUsageTest.py b/acts_tests/tests/google/net/DataUsageTest.py
index 1582886..e6b3fca 100644
--- a/acts_tests/tests/google/net/DataUsageTest.py
+++ b/acts_tests/tests/google/net/DataUsageTest.py
@@ -1,5 +1,5 @@
#
-# Copyright 2018 - The Android Open Source Project
+# Copyright 2022 - 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.
@@ -30,7 +30,7 @@
from acts_contrib.test_utils.net.net_test_utils import stop_tcpdump
from acts_contrib.test_utils.tel import tel_test_utils as ttutils
from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
-from acts_contrib.test_utils.tel.tel_test_utils import http_file_download_by_chrome
+from acts_contrib.test_utils.tel.tel_data_utils import http_file_download_by_chrome
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
import queue
from queue import Empty
@@ -143,7 +143,7 @@
download_status = False
end_time = time.time() + TIMEOUT
while time.time() < end_time:
- download_status = ttutils._check_file_existance(
+ download_status = ttutils._check_file_existence(
ad, self.file_path, self.file_size * BYTE_TO_MB)
if download_status:
self.log.info("Delete file: %s", self.file_path)
diff --git a/acts_tests/tests/google/net/DhcpTest.py b/acts_tests/tests/google/net/DhcpTest.py
index 739f6ca..08aa983 100644
--- a/acts_tests/tests/google/net/DhcpTest.py
+++ b/acts_tests/tests/google/net/DhcpTest.py
@@ -16,12 +16,14 @@
from acts import asserts
from acts.controllers.openwrt_ap import MOBLY_CONTROLLER_CONFIG_NAME as OPENWRT
+from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
+from scapy.all import rdpcap, DHCP
WLAN = "wlan0"
PING_ADDR = "google.com"
-
+RAPID_COMMIT_OPTION = (80, b'')
class DhcpTest(WifiBaseTest):
"""DHCP related test for Android."""
@@ -30,20 +32,30 @@
self.dut = self.android_devices[0]
wutils.wifi_test_device_init(self.dut)
+ req_params = []
+ opt_param = ["wifi_network", "configure_OpenWrt"]
+ self.unpack_userparams(
+ req_param_names=req_params, opt_param_names=opt_param)
asserts.assert_true(OPENWRT in self.user_params,
"OpenWrtAP is not in testbed.")
+
self.openwrt = self.access_points[0]
- self.configure_openwrt_ap_and_start(wpa_network=True)
- self.wifi_network = self.openwrt.get_wifi_network()
+ if hasattr(self, "configure_OpenWrt") and self.configure_OpenWrt == "skip":
+ self.dut.log.info("Skip configure Wifi interface due to config setup.")
+ else:
+ self.configure_openwrt_ap_and_start(wpa_network=True)
+ self.wifi_network = self.openwrt.get_wifi_network()
self.openwrt.network_setting.setup_ipv6_bridge()
asserts.assert_true(self.openwrt.verify_wifi_status(),
"OpenWrt Wifi interface is not ready.")
+
def teardown_class(self):
- """Reset wifi to make sure VPN tears down cleanly."""
+ """Reset wifi and stop tcpdump cleanly."""
wutils.reset_wifi(self.dut)
+ self.openwrt.network_setting.clear_tcpdump()
def teardown_test(self):
- """Reset wifi to make sure VPN tears down cleanly."""
+ """Reset wifi to make sure DUT tears down cleanly."""
wutils.reset_wifi(self.dut)
def _verify_ping(self, option="", dest=PING_ADDR):
@@ -70,6 +82,25 @@
time.sleep(1)
return False
+ def verify_dhcp_packet(self, packets, support_rapid_commit):
+ for pkt in packets:
+ if pkt.haslayer(DHCP):
+ if pkt[DHCP].options[0][1]==1:
+ send_option = RAPID_COMMIT_OPTION in pkt[DHCP].options
+ asserts.assert_true(send_option == support_rapid_commit,
+ "Unexpected result in DHCP DISCOVER.")
+ elif pkt[DHCP].options[0][1]==2:
+ asserts.assert_true( not support_rapid_commit,
+ "Should not find DHCP OFFER when RAPID_COMMIT_OPTION supported.")
+ elif pkt[DHCP].options[0][1]==3:
+ asserts.assert_true( not support_rapid_commit,
+ "Should not find DHCP REQUEST when RAPID_COMMIT_OPTION supported.")
+ elif pkt[DHCP].options[0][1]==5:
+ send_option = RAPID_COMMIT_OPTION in pkt[DHCP].options
+ asserts.assert_true(send_option == support_rapid_commit,
+ "Unexpected result in DHCP ACK.")
+
+ @test_tracker_info(uuid="01148659-6a3d-4a74-88b6-04b19c4acaaa")
def test_ipv4_ipv6_network(self):
"""Verify device can get both ipv4 ipv6 address."""
wutils.connect_to_wifi_network(self.dut, self.wifi_network)
@@ -79,6 +110,7 @@
asserts.assert_true(self._verify_ping(), "Fail to ping on ipv4.")
asserts.assert_true(self._verify_ping("6"), "Fail to ping on ipv6.")
+ @test_tracker_info(uuid="d3f37ba7-504e-48fc-95be-6eca9a148e4a")
def test_ipv6_only_prefer_option(self):
"""Verify DUT can only get ipv6 address and ping out."""
self.openwrt.network_setting.add_ipv6_prefer_option()
@@ -90,3 +122,32 @@
"Should not ping on success on ipv4.")
asserts.assert_true(self._verify_ping("6"),
"Fail to ping on ipv6.")
+ self.openwrt.network_setting.remove_ipv6_prefer_option()
+
+ @test_tracker_info(uuid="a16f2a3c-e3ca-4fca-b3ee-bccb5cf34bab")
+ def test_dhcp_rapid_commit(self):
+ """Verify DUT can run with rapid commit on IPv4."""
+ self.dut.adb.shell("device_config put connectivity dhcp_rapid_commit_version 1")
+ self.openwrt.network_setting.add_dhcp_rapid_commit()
+ remote_pcap_path = \
+ self.openwrt.network_setting.start_tcpdump(self.test_name)
+ wutils.connect_to_wifi_network(self.dut, self.wifi_network)
+ local_pcap_path = self.openwrt.network_setting.stop_tcpdump(
+ remote_pcap_path, self.dut.device_log_path)
+ self.dut.log.info("pcap file path : %s" % local_pcap_path)
+ packets = rdpcap(local_pcap_path)
+ self.verify_dhcp_packet(packets, True)
+ self.openwrt.network_setting.remove_dhcp_rapid_commit()
+
+ @test_tracker_info(uuid="cddb3d33-e5ef-4efd-8ae5-1325010a05c8")
+ def test_dhcp_4_way_handshake(self):
+ """Verify DUT can run with rapid commit on IPv4."""
+ self.dut.adb.shell("device_config put connectivity dhcp_rapid_commit_version 0")
+ remote_pcap_path = \
+ self.openwrt.network_setting.start_tcpdump(self.test_name)
+ wutils.connect_to_wifi_network(self.dut, self.wifi_network)
+ local_pcap_path = self.openwrt.network_setting.stop_tcpdump(
+ remote_pcap_path, self.dut.device_log_path)
+ self.dut.log.info("pcap file path : %s" % local_pcap_path)
+ packets = rdpcap(local_pcap_path)
+ self.verify_dhcp_packet(packets, False)
diff --git a/acts_tests/tests/google/net/DnsOverTlsTest.py b/acts_tests/tests/google/net/DnsOverTlsTest.py
index 13d8fe1..0bb1e28 100644
--- a/acts_tests/tests/google/net/DnsOverTlsTest.py
+++ b/acts_tests/tests/google/net/DnsOverTlsTest.py
@@ -21,11 +21,11 @@
from acts_contrib.test_utils.net import connectivity_const as cconst
from acts_contrib.test_utils.net import connectivity_test_utils as cutils
from acts_contrib.test_utils.net import net_test_utils as nutils
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
from acts_contrib.test_utils.net.net_test_utils import start_tcpdump
from acts_contrib.test_utils.net.net_test_utils import stop_tcpdump
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
from scapy.all import rdpcap
@@ -37,6 +37,7 @@
RST = 0x04
SSID = wutils.WifiEnums.SSID_KEY
+
class DnsOverTlsTest(WifiBaseTest):
"""Tests for DNS-over-TLS."""
@@ -48,22 +49,28 @@
self.dut_b = self.android_devices[1]
for ad in self.android_devices:
ad.droid.setPrivateDnsMode(True)
- nutils.verify_lte_data_and_tethering_supported(ad)
+ if OPENWRT not in self.user_params:
+ nutils.verify_lte_data_and_tethering_supported(ad)
set_wfc_mode(self.log, ad, WFC_MODE_DISABLED)
req_params = ("ping_hosts",)
- opt_params = ("ipv4_only_network", "ipv4_ipv6_network", "dns_name")
+ opt_params = ("ipv4_only_network", "ipv4_ipv6_network",
+ "dns_name", "configure_OpenWrt", "wifi_network")
self.unpack_userparams(req_param_names=req_params,
opt_param_names=opt_params)
if OPENWRT in self.user_params:
self.openwrt = self.access_points[0]
+ if hasattr(self, "configure_OpenWrt") and self.configure_OpenWrt == "skip":
+ self.dut.log.info("Skip configure Wifi interface due to config setup.")
+ else:
+ self.configure_openwrt_ap_and_start(wpa_network=True)
+ self.wifi_network = self.openwrt.get_wifi_network()
self.private_dns_servers = [self.dns_name]
- self.configure_openwrt_ap_and_start(wpa_network=True)
self.openwrt.network_setting.setup_dns_server(self.dns_name)
else:
- self.private_dns_servers = [cconst.DNS_GOOGLE,
- cconst.DNS_QUAD9,
- cconst.DNS_CLOUDFLARE]
+ self.private_dns_servers = [cconst.DNS_GOOGLE_HOSTNAME,
+ cconst.DNS_QUAD9_HOSTNAME,
+ cconst.DNS_CLOUDFLARE_HOSTNAME]
self.tcpdump_pid = None
def teardown_test(self):
@@ -179,6 +186,42 @@
# reset wifi
wutils.reset_wifi(self.dut)
+ def _test_invalid_private_dns(self, net, dns_mode, dns_hostname):
+ """Test private DNS with invalid hostname, which should failed the ping.
+
+ :param net: Wi-Fi network to connect to
+ :param dns_mode: private DNS mode
+ :param dns_hostname: private DNS hostname
+ :return:
+ """
+
+ cutils.set_private_dns(self.dut, dns_mode, dns_hostname)
+ if net:
+ wutils.start_wifi_connection_scan_and_ensure_network_found(
+ self.dut, net[SSID])
+ wutils.wifi_connect(
+ self.dut, net, assert_on_fail=False, check_connectivity=False)
+
+ self._start_tcp_dump(self.dut)
+
+ # ping hosts should NOT pass
+ ping_result = False
+ for host in self.ping_hosts:
+ self.log.info("Pinging %s" % host)
+ try:
+ ping_result = self.dut.droid.httpPing(host)
+ except:
+ pass
+ # Ping result should keep negative with invalid DNS,
+ # so once it's positive we should break, and the test should fail
+ if ping_result:
+ break
+
+ pcap_file = self._stop_tcp_dump(self.dut)
+ self._verify_dns_queries_over_tls(pcap_file, True)
+ wutils.reset_wifi(self.dut)
+ return ping_result
+
@test_tracker_info(uuid="2957e61c-d333-45fb-9ff9-2250c9c8535a")
def test_private_dns_mode_off_wifi_ipv4_only_network(self):
"""Verify private dns mode off on ipv4 only network.
@@ -477,7 +520,7 @@
# set private DNS to strict mode
cutils.set_private_dns(
- self.dut, cconst.PRIVATE_DNS_MODE_STRICT, cconst.DNS_GOOGLE)
+ self.dut, cconst.PRIVATE_DNS_MODE_STRICT, cconst.DNS_GOOGLE_HOSTNAME)
# connect DUT to wifi network
wutils.start_wifi_connection_scan_and_ensure_network_found(
@@ -506,9 +549,9 @@
pcap_file = self._stop_tcp_dump(self.dut)
# Verify DNS server in link properties
- asserts.assert_true(cconst.DNS_GOOGLE in wifi_dns_servers,
+ asserts.assert_true(cconst.DNS_GOOGLE_HOSTNAME in wifi_dns_servers,
"Hostname not in link properties - wifi network")
- asserts.assert_true(cconst.DNS_GOOGLE in lte_dns_servers,
+ asserts.assert_true(cconst.DNS_GOOGLE_HOSTNAME in lte_dns_servers,
"Hostname not in link properites - cell network")
@test_tracker_info(uuid="525a6f2d-9751-474e-a004-52441091e427")
@@ -532,6 +575,7 @@
for host in self.ping_hosts:
wutils.validate_connection(self.dut, host)
+
# stop tcpdump on device
pcap_file = self._stop_tcp_dump(self.dut)
@@ -540,18 +584,17 @@
@test_tracker_info(uuid="af6e34f1-3ad5-4ab0-b3b9-53008aa08294")
def test_private_dns_mode_strict_invalid_hostnames(self):
- """Verify that invalid hostnames are not saved for strict mode.
+ """Verify that invalid hostnames are not able to ping for strict mode.
Steps:
1. Set private DNS to strict mode with invalid hostname
2. Verify that invalid hostname is not saved
"""
invalid_hostnames = ["!%@&!*", "12093478129", "9.9.9.9", "sdkfjhasdf"]
- for hostname in invalid_hostnames:
- cutils.set_private_dns(
- self.dut, cconst.PRIVATE_DNS_MODE_STRICT, hostname)
- mode = self.dut.droid.getPrivateDnsMode()
- specifier = self.dut.droid.getPrivateDnsSpecifier()
- asserts.assert_true(
- mode == cconst.PRIVATE_DNS_MODE_STRICT and specifier != hostname,
- "Able to set invalid private DNS strict mode")
+ for dns_hostname in invalid_hostnames:
+ ping_result = self._test_invalid_private_dns(
+ self.get_wifi_network(False),
+ cconst.PRIVATE_DNS_MODE_STRICT,
+ dns_hostname)
+ asserts.assert_false(ping_result, "Ping success with invalid DNS.")
+
diff --git a/acts_tests/tests/google/net/IKEv2VpnOverWifiTest.py b/acts_tests/tests/google/net/IKEv2VpnOverWifiTest.py
index 6196f61..22fa780 100644
--- a/acts_tests/tests/google/net/IKEv2VpnOverWifiTest.py
+++ b/acts_tests/tests/google/net/IKEv2VpnOverWifiTest.py
@@ -13,39 +13,69 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import time
-from acts import base_test
+from acts.controllers.openwrt_ap import MOBLY_CONTROLLER_CONFIG_NAME as OPENWRT
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.net import connectivity_const
from acts_contrib.test_utils.net import net_test_utils as nutils
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
+from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
+
VPN_CONST = connectivity_const.VpnProfile
VPN_TYPE = connectivity_const.VpnProfileType
VPN_PARAMS = connectivity_const.VpnReqParams
-class IKEv2VpnOverWifiTest(base_test.BaseTestClass):
+class IKEv2VpnOverWifiTest(WifiBaseTest):
"""IKEv2 VPN tests."""
def setup_class(self):
+ """Setup wi-fi connection and unpack params."""
self.dut = self.android_devices[0]
-
- required_params = dir(VPN_PARAMS)
- required_params = [x for x in required_params if not x.startswith("__")]
- self.unpack_userparams(req_param_names=required_params)
- self.vpn_params = {
- "vpn_username": self.vpn_username,
- "vpn_password": self.vpn_password,
- "psk_secret": self.psk_secret,
- "client_pkcs_file_name": self.client_pkcs_file_name,
- "cert_path_vpnserver": self.cert_path_vpnserver,
- "cert_password": self.cert_password,
- "vpn_identity": self.vpn_identity,
- }
+ req_params = dir(VPN_PARAMS)
+ req_params = [
+ x for x in req_params if not x.startswith("__")
+ ]
+ opt_params = ["wifi_network", "vpn_cert_country",
+ "vpn_cert_org", "configure_OpenWrt"]
+ self.unpack_userparams(req_param_names=req_params,
+ opt_param_names=opt_params)
wutils.wifi_test_device_init(self.dut)
- wutils.connect_to_wifi_network(self.dut, self.wifi_network)
+ wutils.wifi_toggle_state(self.dut, True)
+ if OPENWRT in self.user_params:
+ self.openwrt = self.access_points[0]
+ if hasattr(self, "configure_OpenWrt") and self.configure_OpenWrt == "skip":
+ self.dut.log.info("Skip configure Wifi interface due to config setup.")
+ else:
+ self.configure_openwrt_ap_and_start(wpa_network=True)
+ self.wifi_network = self.openwrt.get_wifi_network()
+ # Wait for OpenWrt statement update
+ time.sleep(10)
+ self.openwrt.network_setting.setup_vpn_l2tp_server(
+ self.vpn_server_hostname,
+ self.vpn_verify_addresses["IKEV2_IPSEC_RSA"][0],
+ self.vpn_username,
+ self.vpn_password,
+ self.vpn_identity,
+ "ikev2-server",
+ self.vpn_cert_country,
+ self.vpn_cert_org
+ )
+ wutils.start_wifi_connection_scan_and_ensure_network_found(
+ self.dut, self.wifi_network["SSID"])
+ wutils.wifi_connect(self.dut, self.wifi_network)
+ time.sleep(3)
+
+ self.vpn_params = {"vpn_username": self.vpn_username,
+ "vpn_password": self.vpn_password,
+ "psk_secret": self.psk_secret,
+ "client_pkcs_file_name": self.client_pkcs_file_name,
+ "cert_path_vpnserver": self.cert_path_vpnserver,
+ "cert_password": self.cert_password,
+ "vpn_identity": self.vpn_identity}
def teardown_class(self):
wutils.reset_wifi(self.dut)
@@ -54,6 +84,7 @@
self.dut.take_bug_report(test_name, begin_time)
### Helper methods ###
+
def _test_ikev2_vpn(self, vpn, hostname=None):
"""Verify IKEv2 VPN connection.
@@ -86,7 +117,8 @@
@test_tracker_info(uuid="bdd8a967-8dac-4e48-87b7-2ce9f7d32158")
def test_ikev2_psk_vpn_wifi_with_hostname(self):
- self._test_ikev2_vpn(VPN_TYPE.IKEV2_IPSEC_PSK, self.vpn_server_hostname)
+ self._test_ikev2_vpn(VPN_TYPE.IKEV2_IPSEC_PSK,
+ self.vpn_server_hostname)
@test_tracker_info(uuid="19692520-c123-4b42-8549-08dda9c4873e")
def test_ikev2_mschapv2_vpn_wifi_with_hostname(self):
@@ -95,4 +127,5 @@
@test_tracker_info(uuid="bdaaf6e3-6671-4533-baba-2951009c7d69")
def test_ikev2_rsa_vpn_wifi_with_hostname(self):
- self._test_ikev2_vpn(VPN_TYPE.IKEV2_IPSEC_RSA, self.vpn_server_hostname)
+ self._test_ikev2_vpn(VPN_TYPE.IKEV2_IPSEC_RSA,
+ self.vpn_server_hostname)
diff --git a/acts_tests/tests/google/net/UsbTetheringTest.py b/acts_tests/tests/google/net/UsbTetheringTest.py
index e02611e..1f1d4cf 100644
--- a/acts_tests/tests/google/net/UsbTetheringTest.py
+++ b/acts_tests/tests/google/net/UsbTetheringTest.py
@@ -3,25 +3,47 @@
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.net import net_test_utils as nutils
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
-from scapy.all import get_if_list
from scapy.all import get_if_raw_hwaddr
+from scapy.layers.dns import DNS, DNSQR
+from scapy.layers.inet import IP, ICMP, UDP, TCP, RandShort, sr1
+from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest
DUMSYS_CMD = "dumpsys connectivity tethering"
UPSTREAM_WANTED_STRING = "Upstream wanted"
CURRENT_UPSTREAM_STRING = "Current upstream interface"
SSID = wutils.WifiEnums.SSID_KEY
+GOOGLE_DNS_IP_ADDRESS = "8.8.8.8"
+DEFAULT_DOMAIN_NAME = "www.google.com"
+DEFAULT_DOMAIN_NAME_IPV4 = "ipv4.google.com"
+DEFAULT_DOMAIN_NAME_IPV6 = "ipv6.google.com"
class UsbTetheringTest(base_test.BaseTestClass):
- """Tests for tethering."""
+ """Tests for USB tethering.
+
+ Prerequisite:
+ 1. Android phone should connect to the desktop with USB cable
+ 2. DUT should be able to connect to cellular network and Wi-Fi network
+ 3. Set the CAP_NET_RAW capability before run the test.
+ e.g., `sudo setcap cap_net_raw=eip /usr/local/bin/act.py`
+ """
def setup_class(self):
self.dut = self.android_devices[0]
self.USB_TETHERED = False
nutils.verify_lte_data_and_tethering_supported(self.dut)
+ nutils.set_cap_net_raw_capability()
req_params = ("wifi_network",)
self.unpack_userparams(req_params)
+ # Enable USB tethering and get the USB network interface
+ iflist_before = nutils.get_if_list()
+ serial = self.dut.device_info['serial']
+ nutils.start_usb_tethering(self.dut)
+ self.dut.recreate_services(serial)
+ self.iface = nutils.wait_for_new_iface(iflist_before)
+ if not self.check_upstream_ready():
+ raise asserts.fail("Upstream interface is not active.")
def teardown_class(self):
nutils.stop_usb_tethering(self.dut)
@@ -31,14 +53,112 @@
def on_fail(self, test_name, begin_time):
self.dut.take_bug_report(test_name, begin_time)
- @test_tracker_info(uuid="140a064b-1ab0-4a92-8bdb-e52dde03d5b8")
- def test_usb_tethering_over_wifi(self):
- """Tests USB tethering over wifi.
+ @test_tracker_info(uuid="d4da7695-4342-4564-b7b0-0a30895f23eb")
+ def test_icmp_connectivity(self):
+ """Tests connectivity under ICMP.
Steps:
- 1. Connects to a wifi network
- 2. Enables USB tethering
- 3. Verifies wifi is preferred upstream over data connection
+ 1. Enable USB tethering on Android devices
+ 2. Generate ICMP packet and send to target IP address
+ 3. Verify that the response contains an ICMP layer
+ """
+ icmp = IP(dst=GOOGLE_DNS_IP_ADDRESS)/ICMP()
+ resp = sr1(icmp, timeout=2, iface=self.iface)
+ asserts.assert_true(
+ resp and resp.haslayer(ICMP),
+ "Failed to send ICMP: " + resp.show(dump=True) if resp else "null")
+
+ @test_tracker_info(uuid="0dc7d049-11bf-42f9-918a-263f4470a7e8")
+ def test_icmpv6_connectivity(self):
+ """Tests connectivity under ICMPv6.
+
+ Steps:
+ 1. Enable USB tethering on Android devices
+ 2. Generate ICMPv6 echo request packet and send to target URL
+ 3. Verify that the response contains an IPv6 layer
+ """
+ icmpv6 = IPv6(dst=DEFAULT_DOMAIN_NAME_IPV6)/ICMPv6EchoRequest()
+ resp = sr1(icmpv6, timeout=2, iface=self.iface)
+ asserts.assert_true(
+ resp and resp.haslayer(IPv6),
+ "Failed to send ICMPv6: " + resp.show(dump=True) if resp else "null")
+
+ @test_tracker_info(uuid="34aaffb8-8dd4-4a1f-a158-2732b8df5e59")
+ def test_dns_query_connectivity(self):
+ """Tests connectivity of DNS query.
+
+ Steps:
+ 1. Enable USB tethering on Android devices
+ 2. Generate DNS query and send to target DNS server
+ 3. Verify that the response contains a DNS layer
+ """
+ dnsqr = IP(dst=GOOGLE_DNS_IP_ADDRESS) \
+ /UDP(sport=RandShort(), dport=53) \
+ /DNS(rd=1, qd=DNSQR(qname=DEFAULT_DOMAIN_NAME))
+ resp = sr1(dnsqr, timeout=2, iface=self.iface)
+ asserts.assert_true(
+ resp and resp.haslayer(DNS),
+ "Failed to send DNS query: " + resp.show(dump=True) if resp else "null")
+
+ @test_tracker_info(uuid="b9bed0fa-3178-4456-92e0-736b3a8cc181")
+ def test_tcp_connectivity(self):
+ """Tests connectivity under TCP.
+
+ Steps:
+ 1. Enable USB tethering on Android devices
+ 2. Generate TCP packet and send to target URL
+ 3. Verify that the response contains a TCP layer
+ """
+ tcp = IP(dst=DEFAULT_DOMAIN_NAME)/TCP(dport=[80, 443])
+ resp = sr1(tcp, timeout=2, iface=self.iface)
+ asserts.assert_true(
+ resp and resp.haslayer(TCP),
+ "Failed to send TCP packet:" + resp.show(dump=True) if resp else "null")
+
+ @test_tracker_info(uuid="5e2f31f4-0b18-44be-a1ba-d82bf9050996")
+ def test_tcp_ipv6_connectivity(self):
+ """Tests connectivity under IPv6.
+
+ Steps:
+ 1. Enable USB tethering on Android devices
+ 2. Generate IPv6 packet and send to target URL (e.g., ipv6.google.com)
+ 3. Verify that the response contains an IPv6 layer
+ """
+ tcp_ipv6 = IPv6(dst=DEFAULT_DOMAIN_NAME_IPV6)/TCP(dport=[80, 443])
+ resp = sr1(tcp_ipv6, timeout=2, iface=self.iface)
+ asserts.assert_true(
+ resp and resp.haslayer(IPv6),
+ "Failed to send TCP packet over IPv6, resp: " +
+ resp.show(dump=True) if resp else "null")
+
+ @test_tracker_info(uuid="96115afb-e0d3-40a8-8f04-b64cedc6588f")
+ def test_http_connectivity(self):
+ """Tests connectivity under HTTP.
+
+ Steps:
+ 1. Enable USB tethering on Android devices
+ 2. Implement TCP 3-way handshake to simulate HTTP GET
+ 3. Verify that the 3-way handshake works and response contains a TCP layer
+ """
+ syn_ack = sr1(IP(dst=DEFAULT_DOMAIN_NAME)
+ / TCP(dport=80, flags="S"), timeout=2, iface=self.iface)
+ get_str = "GET / HTTP/1.1\r\nHost: " + DEFAULT_DOMAIN_NAME + "\r\n\r\n"
+ req = IP(dst=DEFAULT_DOMAIN_NAME)/TCP(dport=80, sport=syn_ack[TCP].dport,
+ seq=syn_ack[TCP].ack, ack=syn_ack[TCP].seq + 1, flags="A")/get_str
+ resp = sr1(req, timeout=2, iface=self.iface)
+ asserts.assert_true(
+ resp and resp.haslayer(TCP),
+ "Failed to send HTTP request, resp: " +
+ resp.show(dump=True) if resp else "null")
+
+ @test_tracker_info(uuid="140a064b-1ab0-4a92-8bdb-e52dde03d5b8")
+ def test_usb_tethering_over_wifi(self):
+ """Tests connectivity over Wi-Fi.
+
+ Steps:
+ 1. Connects to a Wi-Fi network
+ 2. Enable USB tethering
+ 3. Verifies Wi-Fi is preferred upstream over data connection
"""
wutils.start_wifi_connection_scan_and_ensure_network_found(
@@ -47,10 +167,7 @@
wifi_network = self.dut.droid.connectivityGetActiveNetwork()
self.log.info("wifi network %s" % wifi_network)
- iflist_before = get_if_list()
- nutils.start_usb_tethering(self.dut)
self.USB_TETHERED = True
- self.iface = nutils.wait_for_new_iface(iflist_before)
self.real_hwaddr = get_if_raw_hwaddr(self.iface)
output = self.dut.adb.shell(DUMSYS_CMD)
@@ -63,3 +180,17 @@
"interface")
self.log.info("WiFi is the upstream interface")
+ def check_upstream_ready(self, retry=3):
+ """Check the upstream is activated
+
+ Check the upstream is activated with retry
+ """
+ for i in range(0, retry):
+ output = self.dut.adb.shell(DUMSYS_CMD)
+ for line in output.split("\n"):
+ if UPSTREAM_WANTED_STRING in line:
+ if "true" in line:
+ self.log.info("Upstream interface is active")
+ elif i == retry:
+ return False
+ return True
diff --git a/acts_tests/tests/google/net/scapy-2.2.0.tar.gz b/acts_tests/tests/google/net/scapy-2.2.0.tar.gz
deleted file mode 100644
index 47ac039..0000000
--- a/acts_tests/tests/google/net/scapy-2.2.0.tar.gz
+++ /dev/null
Binary files differ
diff --git a/acts_tests/tests/google/nr/cbr/CellBroadcastInitializationTest.py b/acts_tests/tests/google/nr/cbr/CellBroadcastInitializationTest.py
new file mode 100644
index 0000000..ed3ea6a
--- /dev/null
+++ b/acts_tests/tests/google/nr/cbr/CellBroadcastInitializationTest.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python3.4
+#
+# Copyright 2022 - Google
+#
+# 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.
+"""
+ Test Script for CellBroadcast initialization Test
+"""
+
+import time
+import os
+
+
+from acts.logger import epoch_to_log_line_timestamp
+from acts.keys import Config
+from acts.base_test import BaseTestClass
+from acts.test_decorators import test_tracker_info
+from acts.utils import load_config
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.tel_test_utils import reboot_device
+from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
+
+
+class CellBroadcastInitializationTest(BaseTestClass):
+ def setup_test(self):
+ super().setup_class()
+ self.number_of_devices = 1
+ self.cbr_init_iteration = self.user_params.get("cbr_init_iteration", 50)
+
+ def teardown_class(self):
+ super().teardown_class(self)
+
+ def _get_current_time_in_secs(self, ad):
+ try:
+ c_time = get_device_epoch_time(ad)
+ c_time = epoch_to_log_line_timestamp(c_time).split()[1].split('.')[0]
+ return self._convert_formatted_time_to_secs(c_time)
+ except Exception as e:
+ ad.log.error(e)
+
+ def _convert_formatted_time_to_secs(self, formatted_time):
+ try:
+ time_list = formatted_time.split(":")
+ return int(time_list[0]) * 3600 + int(time_list[1]) * 60 + int(time_list[2])
+ except Exception as e:
+ self.log.error(e)
+
+ def _verify_channel_config_4400(self, ad):
+ #TODO add all channel checks as constants in tel_defines
+ channel_4400__log = 'SmsBroadcastConfigInfo: Id \\[4400'
+ return ad.search_logcat(channel_4400__log)
+
+ @test_tracker_info(uuid="30f30fa4-f57a-40bd-a37a-141a8efb5a04")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_reboot_stress(self):
+ """ Verifies channel 4400 is set correctly after device boot up
+ only applicable to US carriers
+ after every boot up, search logcat to verify channel 4400 is set
+ default iterations is 50
+ config param : cbr_init_iteration
+
+ """
+ ad = self.android_devices[0]
+
+ current_cbr_version = ad.get_apk_version('com.google.android.cellbroadcast')
+ ad.log.info("Current cbr apk version is %s.", current_cbr_version)
+
+ failure_count = 0
+ begin_time = self._get_current_time_in_secs(ad)
+ for iteration in range(1, self.cbr_init_iteration + 1):
+ msg = "Stress CBR reboot initialization test Iteration: <%s>/<%s>" % (iteration, self.cbr_init_iteration)
+ self.log.info(msg)
+ ad.reboot()
+ ad.wait_for_boot_completion()
+ self.log.info("Rebooted")
+ #TODO make sleep time a constant in tel_defines WAIT_TIME_CBR_INIT_AFTER_REBOOT
+ time.sleep(40)
+ if not self._verify_channel_config_4400(ad):
+ failure_count += 1
+ self.log.error('Iteration failed at %d ' % iteration)
+ end_time = self._get_current_time_in_secs(ad)
+ self.log.debug('Test completed from %s to %s' % (begin_time, end_time))
+ result = True
+ if failure_count > 0:
+ result = False
+ self.log.error('CBR reboot init stress test: <%s> failures in %s iterations',
+ failure_count, self.cbr_init_iteration)
+ return result
+
diff --git a/acts_tests/tests/google/nr/cbr/CellBroadcastTest.py b/acts_tests/tests/google/nr/cbr/CellBroadcastTest.py
index d5264ca..4086f2a 100644
--- a/acts_tests/tests/google/nr/cbr/CellBroadcastTest.py
+++ b/acts_tests/tests/google/nr/cbr/CellBroadcastTest.py
@@ -19,24 +19,39 @@
import xml.etree.ElementTree as ET
import time
+import random
+import os
from acts import signals
+from acts.logger import epoch_to_log_line_timestamp
+from acts.keys import Config
from acts.test_decorators import test_tracker_info
from acts.utils import load_config
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_defines import CARRIER_TEST_CONF_XML_PATH
+from acts_contrib.test_utils.tel.tel_defines import CARRIER_TEST_CONF_XML_PATH, GERMANY_TELEKOM, QATAR_VODAFONE
+from acts_contrib.test_utils.tel.tel_defines import CLEAR_NOTIFICATION_BAR
+from acts_contrib.test_utils.tel.tel_defines import DEFAULT_ALERT_TYPE
+from acts_contrib.test_utils.tel.tel_defines import EXPAND_NOTIFICATION_BAR
+from acts_contrib.test_utils.tel.tel_defines import COLLAPSE_NOTIFICATION_BAR
from acts_contrib.test_utils.tel.tel_defines import UAE
from acts_contrib.test_utils.tel.tel_defines import JAPAN_KDDI
from acts_contrib.test_utils.tel.tel_defines import NEWZEALAND
from acts_contrib.test_utils.tel.tel_defines import HONGKONG
-from acts_contrib.test_utils.tel.tel_defines import CHILE
-from acts_contrib.test_utils.tel.tel_defines import PERU
+from acts_contrib.test_utils.tel.tel_defines import CHILE_ENTEL
+from acts_contrib.test_utils.tel.tel_defines import CHILE_TELEFONICA
+from acts_contrib.test_utils.tel.tel_defines import MEXICO_TELEFONICA
+from acts_contrib.test_utils.tel.tel_defines import ELSALVADOR_TELEFONICA
+from acts_contrib.test_utils.tel.tel_defines import PERU_TELEFONICA
+from acts_contrib.test_utils.tel.tel_defines import PERU_ENTEL
from acts_contrib.test_utils.tel.tel_defines import KOREA
from acts_contrib.test_utils.tel.tel_defines import TAIWAN
from acts_contrib.test_utils.tel.tel_defines import CANADA
+from acts_contrib.test_utils.tel.tel_defines import AUSTRALIA
from acts_contrib.test_utils.tel.tel_defines import BRAZIL
from acts_contrib.test_utils.tel.tel_defines import COLUMBIA
-from acts_contrib.test_utils.tel.tel_defines import EQUADOR
+from acts_contrib.test_utils.tel.tel_defines import ECUADOR_TELEFONICA
+from acts_contrib.test_utils.tel.tel_defines import ECUADOR_CLARO
+from acts_contrib.test_utils.tel.tel_defines import FRANCE
from acts_contrib.test_utils.tel.tel_defines import PUERTORICO
from acts_contrib.test_utils.tel.tel_defines import NETHERLANDS
from acts_contrib.test_utils.tel.tel_defines import ROMANIA
@@ -47,12 +62,16 @@
from acts_contrib.test_utils.tel.tel_defines import ITALY
from acts_contrib.test_utils.tel.tel_defines import SOUTHAFRICA
from acts_contrib.test_utils.tel.tel_defines import UK
+from acts_contrib.test_utils.tel.tel_defines import US_VZW
+from acts_contrib.test_utils.tel.tel_defines import US_ATT
+from acts_contrib.test_utils.tel.tel_defines import US_TMO
from acts_contrib.test_utils.tel.tel_defines import ISRAEL
from acts_contrib.test_utils.tel.tel_defines import OMAN
from acts_contrib.test_utils.tel.tel_defines import JAPAN_SOFTBANK
from acts_contrib.test_utils.tel.tel_defines import SAUDIARABIA
from acts_contrib.test_utils.tel.tel_defines import MAIN_ACTIVITY
from acts_contrib.test_utils.tel.tel_defines import CBR_PACKAGE
+from acts_contrib.test_utils.tel.tel_defines import SYSUI_PACKAGE
from acts_contrib.test_utils.tel.tel_defines import CBR_ACTIVITY
from acts_contrib.test_utils.tel.tel_defines import CBR_TEST_APK
from acts_contrib.test_utils.tel.tel_defines import MCC_MNC
@@ -61,19 +80,94 @@
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_ALERTS_TO_POPULATE
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_UI
from acts_contrib.test_utils.tel.tel_defines import SCROLL_DOWN
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_ALERT_TO_RECEIVE
+from acts_contrib.test_utils.tel.tel_defines import EXIT_ALERT_LIST
+from acts_contrib.test_utils.tel.tel_defines import CMD_DND_OFF
+from acts_contrib.test_utils.tel.tel_defines import DUMPSYS_VIBRATION
+from acts_contrib.test_utils.tel.tel_defines import DEFAULT_SOUND_TIME
+from acts_contrib.test_utils.tel.tel_defines import DEFAULT_VIBRATION_TIME
+from acts_contrib.test_utils.tel.tel_defines import DEFAULT_OFFSET
+from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_DATA_SUB_CHANGE
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED
+from acts_contrib.test_utils.tel.tel_defines import GEN_5G
+from acts_contrib.test_utils.tel.tel_defines import GEN_4G
+from acts_contrib.test_utils.tel.tel_defines import GEN_3G
+from acts_contrib.test_utils.tel.tel_logging_utils import log_screen_shot
+from acts_contrib.test_utils.tel.tel_logging_utils import get_screen_shot_log
from acts_contrib.test_utils.tel.tel_test_utils import reboot_device
-from acts_contrib.test_utils.tel.tel_test_utils import log_screen_shot
-from acts_contrib.test_utils.tel.tel_test_utils import get_screen_shot_log
+from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_data_connection
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id
from acts_contrib.test_utils.net import ui_utils as uutils
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_data_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
+from test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from test_utils.tel.tel_ims_utils import set_wfc_mode_for_subscription
+from test_utils.tel.tel_ims_utils import wait_for_wfc_enabled
class CellBroadcastTest(TelephonyBaseTest):
def setup_class(self):
super().setup_class()
- self.region_plmn_list_conf = self.user_params.get("region_plmn_list")
- self.emergency_alert_settings_conf = self.user_params.get("emergency_alert_settings")
- self.region_plmn_dict = load_config(self.region_plmn_list_conf)
- self.emergency_alert_settings_dict = load_config(self.emergency_alert_settings_conf)
+ req_param = ["region_plmn_list", "emergency_alert_settings", "emergency_alert_channels", "carrier_test_conf"]
+ self.unpack_userparams(req_param_names=req_param)
+ if hasattr(self, "region_plmn_list"):
+ if isinstance(self.region_plmn_list, list):
+ self.region_plmn_list = self.region_plmn_list[0]
+ if not os.path.isfile(self.region_plmn_list):
+ self.region_plmn_list = os.path.join(
+ self.user_params[Config.key_config_path.value],
+ self.region_plmn_list)
+ if hasattr(self, "emergency_alert_settings"):
+ if isinstance(self.emergency_alert_settings, list):
+ self.emergency_alert_settings = self.emergency_alert_settings[0]
+ if not os.path.isfile(self.emergency_alert_settings):
+ self.emergency_alert_settings = os.path.join(
+ self.user_params[Config.key_config_path.value],
+ self.emergency_alert_settings)
+ if hasattr(self, "emergency_alert_channels"):
+ if isinstance(self.emergency_alert_channels, list):
+ self.emergency_alert_channels = self.emergency_alert_channels[0]
+ if not os.path.isfile(self.emergency_alert_channels):
+ self.emergency_alert_channels = os.path.join(
+ self.user_params[Config.key_config_path.value],
+ self.emergency_alert_channels)
+
+ subInfo = self.android_devices[0].droid.subscriptionGetAllSubInfoList()
+ self.slot_sub_id_list = {}
+ for info in subInfo:
+ if info["simSlotIndex"] >= 0:
+ self.slot_sub_id_list[info["subscriptionId"]] = info["simSlotIndex"]
+ if len(subInfo) > 1:
+ self.android_devices[0].log.info("device is operated at DSDS!")
+ else:
+ self.android_devices[0].log.info("device is operated at single SIM!")
+ self.current_sub_id = self.android_devices[0].droid.subscriptionGetDefaultVoiceSubId()
+
+ self.android_devices[0].log.info("Active slot: %d, active voice subscription id: %d",
+ self.slot_sub_id_list[self.current_sub_id], self.current_sub_id)
+
+ if hasattr(self, "carrier_test_conf"):
+ if isinstance(self.carrier_test_conf, list):
+ self.carrier_test_conf = self.carrier_test_conf[self.slot_sub_id_list[self.current_sub_id]]
+ if not os.path.isfile(self.carrier_test_conf):
+ self.carrier_test_conf = os.path.join(
+ self.user_params[Config.key_config_path.value],
+ self.carrier_test_conf)
+ self.verify_vibration = self.user_params.get("verify_vibration", True)
+ self._disable_vibration_check_for_11()
+ self.verify_sound = self.user_params.get("verify_sound", True)
+ self.region_plmn_dict = load_config(self.region_plmn_list)
+ self.emergency_alert_settings_dict = load_config(self.emergency_alert_settings)
+ self.emergency_alert_channels_dict = load_config(self.emergency_alert_channels)
self._verify_cbr_test_apk_install(self.android_devices[0])
def setup_test(self):
@@ -94,7 +188,9 @@
def _verify_device_in_specific_region(self, ad, region=None):
mccmnc = self.region_plmn_dict[region][MCC_MNC]
- current_plmn = ad.adb.getprop(PLMN_ADB_PROPERTY)
+ plmns = ad.adb.getprop(PLMN_ADB_PROPERTY)
+ plmn_list = plmns.split(",")
+ current_plmn = plmn_list[self.slot_sub_id_list[self.current_sub_id]]
if current_plmn == mccmnc:
ad.log.info("device in %s region", region.upper())
return True
@@ -102,18 +198,35 @@
ad.log.info("device not in %s region", region.upper())
return False
+ def _disable_vibration_check_for_11(self):
+ if self.android_devices[0].adb.getprop("ro.build.version.release") in ("11", "R"):
+ self.verify_vibration = False
def _get_toggle_value(self, ad, alert_text=None):
- node = uutils.wait_and_get_xml_node(ad, timeout=30, text=alert_text)
+ if alert_text == "Alerts":
+ node = uutils.wait_and_get_xml_node(ad, timeout=30, matching_node=2, text=alert_text)
+ else:
+ node = uutils.wait_and_get_xml_node(ad, timeout=30, text=alert_text)
return node.parentNode.nextSibling.firstChild.attributes['checked'].value
+ def _wait_and_click(self, ad, alert_text=None):
+ if alert_text == "Alerts":
+ uutils.wait_and_click(ad, text=alert_text, matching_node=2)
+ else:
+ uutils.wait_and_click(ad, text=alert_text)
+
+ def _has_element(self, ad, alert_text=None):
+ if alert_text == "Alerts":
+ return uutils.has_element(ad, text=alert_text, matching_node=2)
+ else:
+ return uutils.has_element(ad, text=alert_text)
def _open_wea_settings_page(self, ad):
ad.adb.shell("am start -a %s -n %s/%s" % (MAIN_ACTIVITY, CBR_PACKAGE, CBR_ACTIVITY))
def _close_wea_settings_page(self, ad):
- pid = ad.adb.shell("pidof %s" % CBR_PACKAGE)
+ pid = ad.adb.shell("pidof %s" % CBR_PACKAGE, ignore_status=True)
ad.adb.shell("kill -9 %s" % pid, ignore_status=True)
@@ -130,15 +243,15 @@
region.upper(), mccmnc, imsi)
# update carrier xml file
- carrier_test_conf = self.user_params.get("carrier_test_conf")
- tree = ET.parse(carrier_test_conf)
+ tree = ET.parse(self.carrier_test_conf)
root = tree.getroot()
root[1].attrib['value'] = mccmnc
root[2].attrib['value'] = imsi
- tree.write(carrier_test_conf)
+ tree.write(self.carrier_test_conf)
# push carrier xml to device
- ad.adb.push("%s %s" % (carrier_test_conf, CARRIER_TEST_CONF_XML_PATH))
+ ad.log.info("push %s to %s" % (self.carrier_test_conf, CARRIER_TEST_CONF_XML_PATH))
+ ad.adb.push("%s %s" % (self.carrier_test_conf, CARRIER_TEST_CONF_XML_PATH))
# reboot device
reboot_device(ad)
@@ -157,10 +270,10 @@
alert_value = value["default_value"]
self._open_wea_settings_page(ad)
# scroll till bottom
- if not uutils.has_element(ad, text=alert_text):
+ if not self._has_element(ad, alert_text):
for _ in range(3):
ad.adb.shell(SCROLL_DOWN)
- if not uutils.has_element(ad, text=alert_text):
+ if not self._has_element(ad, alert_text):
ad.log.error("UI - %s missing", alert_text)
result = False
continue
@@ -182,26 +295,26 @@
alert_toggle = value["toggle_avail"]
if alert_toggle == "true":
self._open_wea_settings_page(ad)
- if not uutils.has_element(ad, text=alert_text):
+ if not self._has_element(ad, alert_text):
for _ in range(3):
ad.adb.shell(SCROLL_DOWN)
- if not uutils.has_element(ad, text=alert_text):
+ if not self._has_element(ad, alert_text):
ad.log.error("UI - %s missing", alert_text)
result = False
continue
before_toggle = self._get_toggle_value(ad, alert_text)
- uutils.wait_and_click(ad, text=alert_text)
+ self._wait_and_click(ad, alert_text)
after_toggle = self._get_toggle_value(ad, alert_text)
if before_toggle == after_toggle:
for _ in range(3):
ad.adb.shell(SCROLL_DOWN)
- uutils.wait_and_click(ad, text=alert_text)
+ self._wait_and_click(ad, alert_text)
after_toggle = self._get_toggle_value(ad, alert_text)
if before_toggle == after_toggle:
ad.log.error("UI - fail to toggle %s", alert_text)
result = False
else:
- uutils.wait_and_click(ad, text=alert_text)
+ self._wait_and_click(ad, alert_text)
reset_toggle = self._get_toggle_value(ad, alert_text)
if reset_toggle != before_toggle:
ad.log.error("UI - fail to reset toggle %s", alert_text)
@@ -211,6 +324,232 @@
return result
+ def _convert_formatted_time_to_secs(self, formatted_time):
+ try:
+ time_list = formatted_time.split(":")
+ return int(time_list[0]) * 3600 + int(time_list[1]) * 60 + int(time_list[2])
+ except Exception as e:
+ self.log.error(e)
+
+
+ def _get_current_time_in_secs(self, ad):
+ try:
+ c_time = get_device_epoch_time(ad)
+ c_time = epoch_to_log_line_timestamp(c_time).split()[1].split('.')[0]
+ return self._convert_formatted_time_to_secs(c_time)
+ except Exception as e:
+ ad.log.error(e)
+
+
+ def _verify_flashlight(self, ad):
+ count = 0
+ while(count < 10):
+ status = ad.adb.shell("settings get secure flashlight_available")
+ if status == "1":
+ ad.log.info("LED lights OK")
+ return True
+ ad.log.error("LED lights not OK")
+ return False
+
+
+
+ def _verify_vibration(self, ad, begintime, expectedtime, offset):
+ if not self.verify_vibration:
+ return True
+ out = ad.adb.shell(DUMPSYS_VIBRATION)
+ if out:
+ try:
+ starttime = out.split()[2].split('.')[0]
+ endtime = out.split()[5].split('.')[0]
+ starttime = self._convert_formatted_time_to_secs(starttime)
+ endtime = self._convert_formatted_time_to_secs(endtime)
+ vibration_time = endtime - starttime
+ if (starttime < begintime):
+ ad.log.error("vibration: actualtime:%s logtime:%s Not OK", begintime, starttime)
+ return False
+ if not vibration_time in range(expectedtime - offset, expectedtime + offset + 1):
+ ad.log.error("vibration: %d secs Not OK", vibration_time)
+ return False
+ ad.log.info("vibration: %d secs OK", vibration_time)
+ return True
+ except Exception as e:
+ ad.log.error("vibration parsing is broken %s", e)
+ return False
+ return False
+
+
+ def _verify_sound(self, ad, begintime, expectedtime, offset, calling_package=CBR_PACKAGE):
+ if not self.verify_sound:
+ return True
+ cbr_pid = ad.adb.shell("pidof %s" % calling_package)
+ DUMPSYS_START_AUDIO = "dumpsys audio | grep %s | grep requestAudioFocus | tail -1" % cbr_pid
+ DUMPSYS_END_AUDIO = "dumpsys audio | grep %s | grep abandonAudioFocus | tail -1" % cbr_pid
+ start_audio = ad.adb.shell(DUMPSYS_START_AUDIO)
+ end_audio = ad.adb.shell(DUMPSYS_END_AUDIO)
+ if start_audio and end_audio:
+ try:
+ starttime = start_audio.split()[1]
+ endtime = end_audio.split()[1]
+ starttime = self._convert_formatted_time_to_secs(starttime)
+ endtime = self._convert_formatted_time_to_secs(endtime)
+ sound_time = endtime - starttime
+ if (starttime < begintime):
+ ad.log.error("sound: actualtime:%s logtime:%s Not OK", begintime, starttime)
+ return False
+ if not sound_time in range(expectedtime - offset, expectedtime + offset + 1):
+ ad.log.error("sound: %d secs Not OK", sound_time)
+ return False
+ ad.log.info("sound: %d secs OK", sound_time)
+ return True
+ except Exception as e:
+ ad.log.error("sound parsing is broken %s", e)
+ return False
+ return False
+
+
+ def _exit_alert_pop_up(self, ad):
+ for text in EXIT_ALERT_LIST:
+ try:
+ uutils.wait_and_click(ad, text_contains=text, timeout=1)
+ except Exception:
+ continue
+
+
+ def _verify_text_present_on_ui(self, ad, alert_text):
+ if uutils.has_element(ad, text=alert_text, timeout=5):
+ return True
+ elif uutils.has_element(ad, text_contains=alert_text, timeout=5):
+ return True
+ else:
+ return False
+
+
+ def _log_and_screenshot_alert_fail(self, ad, state, region, channel):
+ ad.log.error("Fail for alert: %s for %s: %s", state, region, channel)
+ log_screen_shot(ad, "alert_%s_for_%s_%s" % (state, region, channel))
+
+
+ def _show_statusbar_notifications(self, ad):
+ ad.adb.shell(EXPAND_NOTIFICATION_BAR)
+
+
+ def _hide_statusbar_notifications(self, ad):
+ ad.adb.shell(COLLAPSE_NOTIFICATION_BAR)
+
+
+ def _clear_statusbar_notifications(self, ad):
+ ad.adb.shell(CLEAR_NOTIFICATION_BAR)
+
+
+ def _popup_alert_in_statusbar_notifications(self, ad, alert_text):
+ alert_in_notification = False
+ # Open status bar notifications.
+ self._show_statusbar_notifications(ad)
+ # Wait for status bar notifications showing.
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+ if self._verify_text_present_on_ui(ad, alert_text):
+ # Found alert in notifications, display it.
+ uutils.wait_and_click(ad, text=alert_text)
+ alert_in_notification = True
+ else:
+ # Close status bar notifications
+ self._hide_statusbar_notifications(ad)
+ return alert_in_notification
+
+
+ def _verify_send_receive_wea_alerts(self, ad, region=None, call=False, call_direction=DIRECTION_MOBILE_ORIGINATED):
+ result = True
+ # Always clear notifications in the status bar before testing to find alert notification easily.
+ self._clear_statusbar_notifications(ad)
+ for key, value in self.emergency_alert_channels_dict[region].items():
+
+ if call:
+ if not self._setup_voice_call(self.log,
+ self.android_devices,
+ call_direction=call_direction):
+ self.log("Fail to set up voice call!")
+ return False
+
+ # Configs
+ iteration_result = True
+ channel = int(key)
+ alert_text = value["title"]
+ alert_expected = value["default_value"]
+ wait_for_alert = value.get("alert_time", WAIT_TIME_FOR_ALERT_TO_RECEIVE)
+ vibration_time = value.get("vibration_time", DEFAULT_VIBRATION_TIME)
+ sound_time = value.get("sound_time", DEFAULT_SOUND_TIME)
+ offset = value.get("offset", DEFAULT_OFFSET)
+ alert_type = value.get("alert_type", DEFAULT_ALERT_TYPE)
+
+ # Begin Iteration
+ begintime = self._get_current_time_in_secs(ad)
+ sequence_num = random.randrange(10000, 40000)
+ ad.log.info("Iteration: %s for %s: %s", alert_text, region, channel)
+
+ # Send Alert
+ ad.droid.cbrSendTestAlert(sequence_num, channel)
+ if region == NEWZEALAND:
+ if not self._verify_flashlight(ad):
+ iteration_result = False
+
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+ if call:
+ hangup_call(self.log, ad)
+
+ time.sleep(wait_for_alert)
+
+ # Receive Alert
+ if not self._verify_text_present_on_ui(ad, alert_text):
+ alert_in_notification = False
+ # Check if alert message is expected to be in the notification drawer
+ if alert_expected == "true" and alert_type == "notification":
+ # Verify expected notification in notification drawer and open the message
+ if self._popup_alert_in_statusbar_notifications(ad, alert_text):
+ ad.log.info("Found alert channel %d in status bar notifications, pop it up.", channel)
+ # Verify alert text in message.
+ alert_in_notification = self._verify_text_present_on_ui(ad, alert_text)
+ if alert_in_notification:
+ # Verify vibration and notification sound.
+ # We check sound generated by com.android.systemui package.
+ # For the reason of offset + 1, refer to b/199565843
+ # TODO: The notification sound is initiated by system
+ # rather than CellBroadcastReceiver. In case there are
+ # any non-emergency notifications coming during testing, we
+ # should consider to validate notification id instead of
+ # com.android.systemui package. b/199565843
+ if not (self._verify_vibration(ad, begintime, vibration_time, offset) and
+ self._verify_sound(ad, begintime, sound_time, offset+1, SYSUI_PACKAGE)):
+ iteration_result = False
+ if alert_expected == "true" and not alert_in_notification:
+ iteration_result = False
+ self._log_and_screenshot_alert_fail(ad, "missing", region, channel)
+ else:
+ if alert_expected == "true":
+ ad.log.info("Alert received OK")
+ self._exit_alert_pop_up(ad)
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+
+ # Vibration and Sound
+ if not self._verify_text_present_on_ui(ad, alert_text):
+ ad.log.info("Alert exited OK")
+ if not (self._verify_vibration(ad, begintime, vibration_time, offset) and
+ self._verify_sound(ad, begintime, sound_time, offset)):
+ iteration_result = False
+ else:
+ iteration_result = False
+ self._log_and_screenshot_alert_fail(ad, "present", region, channel)
+ else:
+ iteration_result = False
+ self._log_and_screenshot_alert_fail(ad, "present", region, channel)
+ if iteration_result:
+ ad.log.info("Success alert: %s for %s: %s", alert_text, region, channel)
+ else:
+ ad.log.error("Failure alert: %s for %s: %s", alert_text, region, channel)
+ result = iteration_result
+ self._exit_alert_pop_up(ad)
+ return result
+
+
def _settings_test_flow(self, region):
ad = self.android_devices[0]
result = True
@@ -218,16 +557,89 @@
time.sleep(WAIT_TIME_FOR_UI)
if not self._verify_wea_default_settings(ad, region):
result = False
- log_screen_shot(ad, "default_settings_for_%s" % region)
+ log_screen_shot(ad, "default_settings_%s" % region)
self._close_wea_settings_page(ad)
+ # Here close wea setting UI and then immediately open the UI that sometimes causes
+ # failing to open the wea setting UI. So we just delay 1 sec after closing
+ # the wea setting UI.
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
if not self._verify_wea_toggle_settings(ad, region):
- log_screen_shot(ad, "toggle_settings_for_%s" % region)
+ log_screen_shot(ad, "toggle_settings_%s" % region)
result = False
get_screen_shot_log(ad)
self._close_wea_settings_page(ad)
return result
+ def _send_receive_test_flow(self, region):
+ ad = self.android_devices[0]
+ result = True
+ self._set_device_to_specific_region(ad, region)
+ time.sleep(WAIT_TIME_FOR_UI)
+ ad.log.info("disable DND: %s", CMD_DND_OFF)
+ ad.adb.shell(CMD_DND_OFF)
+ if not self._verify_send_receive_wea_alerts(ad, region):
+ result = False
+ get_screen_shot_log(ad)
+ return result
+
+
+ def _setup_receive_test_flow_wifi(self, region, gen, data):
+ """ Setup send/receive WEA with wifi enabled and various RAT."""
+ ad = self.android_devices[0]
+ self._set_device_to_specific_region(ad, region)
+ time.sleep(WAIT_TIME_FOR_UI)
+ ad.log.info("disable DND: %s", CMD_DND_OFF)
+ ad.adb.shell(CMD_DND_OFF)
+ if gen == GEN_5G:
+ if not provision_device_for_5g(self.log, ad):
+ return False
+ else:
+ phone_setup_data_for_subscription(ad.log,
+ ad,
+ get_default_data_sub_id(ad),
+ gen)
+ if data:
+ ad.log.info("Enable data network!")
+ else:
+ ad.log.info("Disable data network!")
+ ad.droid.telephonyToggleDataConnection(data)
+ if not wait_for_data_connection(ad.log, ad, data,
+ MAX_WAIT_TIME_DATA_SUB_CHANGE):
+ if data:
+ ad.log.error("Failed to enable data network!")
+ else:
+ ad.log.error("Failed to disable data network!")
+ return False
+
+ wifi_toggle_state(ad.log, ad, True)
+ if not ensure_wifi_connected(ad.log, ad,
+ self.wifi_network_ssid,
+ self.wifi_network_pass):
+ ad.log.error("WiFi connect fail.")
+ return False
+ return True
+
+ def _setup_voice_call(self, log, ads, call_direction=DIRECTION_MOBILE_ORIGINATED):
+ if call_direction == DIRECTION_MOBILE_ORIGINATED:
+ ad_caller = ads[0]
+ ad_callee = ads[1]
+ else:
+ ad_caller = ads[1]
+ ad_callee = ads[0]
+ return call_setup_teardown(log, ad_caller, ad_callee, wait_time_in_call=0)
+
+ def _setup_wfc_mode(self, ad):
+ if not set_wfc_mode_for_subscription(ad,
+ WFC_MODE_WIFI_ONLY,
+ get_default_data_sub_id(ad)):
+ ad.log.error("Unable to set WFC mode to %s.", WFC_MODE_WIFI_ONLY)
+ return False
+
+ if not wait_for_wfc_enabled(ad.log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED):
+ ad.log.error("WFC is not enabled")
+ return False
+ return True
""" Tests Begin """
@@ -246,6 +658,36 @@
return self._settings_test_flow(UAE)
+ @test_tracker_info(uuid="ac4639ca-b77e-4200-b3f0-9079e2783f60")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_default_alert_settings_australia(self):
+ """ Verifies Wireless Emergency Alert settings for Australia
+
+ configures the device to Australia
+ verifies alert names and its default values
+ toggles the alert twice if available
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._settings_test_flow(AUSTRALIA)
+
+
+ @test_tracker_info(uuid="d0255023-d9bb-45c5-bede-446d720e619a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_default_alert_settings_france(self):
+ """ Verifies Wireless Emergency Alert settings for France
+
+ configures the device to France
+ verifies alert names and its default values
+ toggles the alert twice if available
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._settings_test_flow(FRANCE)
+
+
@test_tracker_info(uuid="fd461335-21c0-470c-aca7-74c8ebb67711")
@TelephonyBaseTest.tel_test_wrap
def test_default_alert_settings_japan_kddi(self):
@@ -293,32 +735,92 @@
@test_tracker_info(uuid="d9e2dca2-4965-48d5-9d79-352c4ccf9e0f")
@TelephonyBaseTest.tel_test_wrap
- def test_default_alert_settings_chile(self):
- """ Verifies Wireless Emergency Alert settings for Chile
+ def test_default_alert_settings_chile_entel(self):
+ """ Verifies Wireless Emergency Alert settings for Chile_Entel
- configures the device to Chile
+ configures the device to Chile_Entel
verifies alert names and its default values
toggles the alert twice if available
Returns:
True if pass; False if fail and collects screenshot
"""
- return self._settings_test_flow(CHILE)
+ return self._settings_test_flow(CHILE_ENTEL)
+
+
+ @test_tracker_info(uuid="2a045a0e-145c-4677-b454-b0b63a69ea10")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_default_alert_settings_chile_telefonica(self):
+ """ Verifies Wireless Emergency Alert settings for Chile_Telefonica
+
+ configures the device to Chile_Telefonica
+ verifies alert names and its default values
+ toggles the alert twice if available
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._settings_test_flow(CHILE_TELEFONICA)
@test_tracker_info(uuid="77cff297-fe3b-4b4c-b502-5324b4e91506")
@TelephonyBaseTest.tel_test_wrap
- def test_default_alert_settings_peru(self):
- """ Verifies Wireless Emergency Alert settings for Peru
+ def test_default_alert_settings_peru_entel(self):
+ """ Verifies Wireless Emergency Alert settings for Peru_Entel
- configures the device to Peru
+ configures the device to Peru_Entel
verifies alert names and its default values
toggles the alert twice if available
Returns:
True if pass; False if fail and collects screenshot
"""
- return self._settings_test_flow(PERU)
+ return self._settings_test_flow(PERU_ENTEL)
+
+
+ @test_tracker_info(uuid="8b683505-288f-4587-95f2-9a8705476f09")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_default_alert_settings_peru_telefonica(self):
+ """ Verifies Wireless Emergency Alert settings for Peru_Telefonica
+
+ configures the device to Peru_Telefonica
+ verifies alert names and its default values
+ toggles the alert twice if available
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._settings_test_flow(PERU_TELEFONICA)
+
+
+ @test_tracker_info(uuid="cc0e0f64-2c77-4e20-b55e-6f555f7ecb97")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_default_alert_settings_elsalvador_telefonica(self):
+ """ Verifies Wireless Emergency Alert settings for Elsalvador_Telefonica
+
+ configures the device to Elsalvador_Telefonica
+ verifies alert names and its default values
+ toggles the alert twice if available
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._settings_test_flow(ELSALVADOR_TELEFONICA)
+
+
+ @test_tracker_info(uuid="339be9ef-7e0e-463a-ad45-12b7e74bb1c4")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_default_alert_settings_mexico_telefonica(self):
+ """ Verifies Wireless Emergency Alert settings for Mexico_Telefonica
+
+ configures the device to Mexico_Telefonica
+ verifies alert names and its default values
+ toggles the alert twice if available
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._settings_test_flow(MEXICO_TELEFONICA)
@test_tracker_info(uuid="4c3c4e65-c624-4eba-9a81-263f4ee01e12")
@@ -398,17 +900,32 @@
@test_tracker_info(uuid="2ebfc05b-3512-4eff-9c09-5d8f49fe0b5e")
@TelephonyBaseTest.tel_test_wrap
- def test_default_alert_settings_equador(self):
- """ Verifies Wireless Emergency Alert settings for Equador
+ def test_default_alert_settings_ecuador_telefonica(self):
+ """ Verifies Wireless Emergency Alert settings for Ecuador Telefonica
- configures the device to Equador
+ configures the device to Ecuador Telefonica
verifies alert names and its default values
toggles the alert twice if available
Returns:
True if pass; False if fail and collects screenshot
"""
- return self._settings_test_flow(EQUADOR)
+ return self._settings_test_flow(ECUADOR_TELEFONICA)
+
+
+ @test_tracker_info(uuid="694bf8f6-9e6e-46b4-98df-c7ab1a9a3ec8")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_default_alert_settings_ecuador_claro(self):
+ """ Verifies Wireless Emergency Alert settings for Ecuador Claro
+
+ configures the device to Ecuador Claro
+ verifies alert names and its default values
+ toggles the alert twice if available
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._settings_test_flow(ECUADOR_CLARO)
@test_tracker_info(uuid="96628975-a23f-47f7-ab18-1aa7a7dc08b5")
@@ -619,3 +1136,1055 @@
True if pass; False if fail and collects screenshot
"""
return self._settings_test_flow(SAUDIARABIA)
+
+
+ @test_tracker_info(uuid="a5f232c4-e0fa-4ce6-aa00-c838f0d86272")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_default_alert_settings_us_att(self):
+ """ Verifies Wireless Emergency Alert settings for US ATT
+
+ configures the device to US ATT
+ verifies alert names and its default values
+ toggles the alert twice if available
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._settings_test_flow(US_ATT)
+
+
+ @test_tracker_info(uuid="a712c136-8ce9-4bc2-9dda-05ecdd11e8ad")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_default_alert_settings_us_tmo(self):
+ """ Verifies Wireless Emergency Alert settings for US TMO
+
+ configures the device to US TMO
+ verifies alert names and its default values
+ toggles the alert twice if available
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._settings_test_flow(US_TMO)
+
+
+ @test_tracker_info(uuid="20403705-f627-42d7-9dc2-4e820273a622")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_default_alert_settings_us_vzw(self):
+ """ Verifies Wireless Emergency Alert settings for US VZW
+
+ configures the device to US VZW
+ verifies alert names and its default values
+ toggles the alert twice if available
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._settings_test_flow(US_VZW)
+
+
+ @test_tracker_info(uuid="fb4cda9e-7b4c-469e-a480-670bfb9dc6d7")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_default_alert_settings_germany_telekom(self):
+ """ Verifies Wireless Emergency Alert settings for Germany telecom
+
+ configures the device to Germany telecom
+ verifies alert names and its default values
+ toggles the alert twice if available
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._settings_test_flow(GERMANY_TELEKOM)
+
+
+ @test_tracker_info(uuid="f4afbef9-c1d7-4fab-ad0f-e03bc961a689")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_default_alert_settings_qatar_vodafone(self):
+ """ Verifies Wireless Emergency Alert settings for Qatar vodafone
+
+ configures the device to Qatar vodafone
+ verifies alert names and its default values
+ toggles the alert twice if available
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._settings_test_flow(QATAR_VODAFONE)
+
+
+ @test_tracker_info(uuid="f3a99475-a23f-427c-a371-d2a46d357d75")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_australia(self):
+ """ Verifies Wireless Emergency Alerts for AUSTRALIA
+
+ configures the device to AUSTRALIA
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(AUSTRALIA)
+
+
+ @test_tracker_info(uuid="73c98624-2935-46ea-bf7c-43c431177ebd")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_brazil(self):
+ """ Verifies Wireless Emergency Alerts for BRAZIL
+
+ configures the device to BRAZIL
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(BRAZIL)
+
+
+ @test_tracker_info(uuid="8c2e16f8-9b7f-4733-a65e-f087d2480e92")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_canada(self):
+ """ Verifies Wireless Emergency Alerts for CANADA
+
+ configures the device to CANADA
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(CANADA)
+
+
+ @test_tracker_info(uuid="feea4e42-99cc-4075-bd78-15b149cb2e4c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_chile_entel(self):
+ """ Verifies Wireless Emergency Alerts for CHILE_ENTEL
+
+ configures the device to CHILE_ENTEL
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(CHILE_ENTEL)
+
+
+ @test_tracker_info(uuid="d2ec84ad-7f9a-4aa2-97e8-ca9ffa6c58a7")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_chile_telefonica(self):
+ """ Verifies Wireless Emergency Alerts for CHILE_TELEFONICA
+
+ configures the device to CHILE_TELEFONICA
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(CHILE_TELEFONICA)
+
+
+ @test_tracker_info(uuid="4af30b94-50ea-4e19-8866-31fd3573a059")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_columbia(self):
+ """ Verifies Wireless Emergency Alerts for COLUMBIA
+
+ configures the device to COLUMBIA
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(COLUMBIA)
+
+
+ @test_tracker_info(uuid="2378b651-2097-48e6-b409-885bde9f4586")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_ecuador_telefonica(self):
+ """ Verifies Wireless Emergency Alerts for ECUADOR Telefonica
+
+ configures the device to ECUADOR Telefonica
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(ECUADOR_TELEFONICA)
+
+
+ @test_tracker_info(uuid="cd064259-6cb2-460b-8225-de613f6cf967")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_ecuador_claro(self):
+ """ Verifies Wireless Emergency Alerts for ECUADOR Claro
+
+ configures the device to ECUADOR Claro
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(ECUADOR_CLARO)
+
+
+ @test_tracker_info(uuid="b11d1dd7-2090-463a-ba3a-39703db7f376")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_elsalvador_telefonica(self):
+ """ Verifies Wireless Emergency Alerts for ELSALVADOR telefonica
+
+ configures the device to ELSALVADOR telefonica
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(ELSALVADOR_TELEFONICA)
+
+
+ @test_tracker_info(uuid="46d6c612-21df-476e-a41b-3baa621b52f0")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_estonia(self):
+ """ Verifies Wireless Emergency Alerts for ESTONIA
+
+ configures the device to ESTONIA
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(ESTONIA)
+
+
+ @test_tracker_info(uuid="6de32af0-9545-4143-b327-146e4d0af28c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_france(self):
+ """ Verifies Wireless Emergency Alerts for FRANCE
+
+ configures the device to FRANCE
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(FRANCE)
+
+
+ @test_tracker_info(uuid="9c5826db-0457-4c6f-9d06-6973b5f77e3f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_greece(self):
+ """ Verifies Wireless Emergency Alerts for GREECE
+
+ configures the device to GREECE
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(GREECE)
+
+
+ @test_tracker_info(uuid="57dd9a79-6ac2-41c7-b7eb-3afb01f35bd2")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_hongkong(self):
+ """ Verifies Wireless Emergency Alerts for Japan HONGKONG
+
+ configures the device to HONGKONG
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(HONGKONG)
+
+
+ @test_tracker_info(uuid="8ffdfaf8-5925-4e66-be22-e1ac25165784")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_israel(self):
+ """ Verifies Wireless Emergency Alerts for ISRAEL
+
+ configures the device to ISRAEL
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(ISRAEL)
+
+
+ @test_tracker_info(uuid="f38e289c-4c7d-48a7-9b21-f7d872e3eb98")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_italy(self):
+ """ Verifies Wireless Emergency Alerts for ITALY
+
+ configures the device to ITALY
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(ITALY)
+
+
+ @test_tracker_info(uuid="d434dbf8-72e8-44a7-ab15-d418133088c6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_japan_kddi(self):
+ """ Verifies Wireless Emergency Alerts for JAPAN_KDDI
+
+ configures the device to JAPAN_KDDI
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(JAPAN_KDDI)
+
+
+ @test_tracker_info(uuid="c597995f-8937-4987-91db-7f83a0f5f4ec")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_japan_softbank(self):
+ """ Verifies Wireless Emergency Alerts for JAPAN_SOFTBANK
+
+ configures the device to JAPAN_SOFTBANK
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(JAPAN_SOFTBANK)
+
+
+ @test_tracker_info(uuid="b159d6b2-b900-4329-9b77-c9ba9e83dddc")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_korea(self):
+ """ Verifies Wireless Emergency Alerts for KOREA
+
+ configures the device to KOREA
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(KOREA)
+
+
+ @test_tracker_info(uuid="9b59c594-179a-44d6-9dbf-68adc43aa820")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_latvia(self):
+ """ Verifies Wireless Emergency Alerts for LATVIA
+
+ configures the device to LATVIA
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(LATVIA)
+
+
+ @test_tracker_info(uuid="af7d916b-42f0-4420-8a1c-b39d3f184953")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_lithuania(self):
+ """ Verifies Wireless Emergency Alerts for LITHUANIA
+
+ configures the device to LITHUANIA
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(LITHUANIA)
+
+
+ @test_tracker_info(uuid="061cd0f3-cefa-4e5d-a1aa-f6125ccf9347")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_mexico_telefonica(self):
+ """ Verifies Wireless Emergency Alerts for MEXICO telefonica
+
+ configures the device to MEXICO telefonica
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(MEXICO_TELEFONICA)
+
+
+ @test_tracker_info(uuid="a9c7cdbe-5a9e-49fb-af60-953e8c1547c0")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_netherlands(self):
+ """ Verifies Wireless Emergency Alerts for NETHERLANDS
+
+ configures the device to NETHERLANDS
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(NETHERLANDS)
+
+
+ @test_tracker_info(uuid="23db0b77-1a1c-494c-bcc6-1355fb037a6f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_newzealand(self):
+ """ Verifies Wireless Emergency Alerts for NEWZEALAND
+
+ configures the device to NEWZEALAND
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(NEWZEALAND)
+
+
+ @test_tracker_info(uuid="a4216cbb-4ed7-4e72-98e7-2ebebe904956")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_oman(self):
+ """ Verifies Wireless Emergency Alerts for OMAN
+
+ configures the device to OMAN
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(OMAN)
+
+
+ @test_tracker_info(uuid="35f0f156-1555-4bf1-98b1-b5848d8e2d39")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_peru_entel(self):
+ """ Verifies Wireless Emergency Alerts for PERU_ENTEL
+
+ configures the device to PERU_ENTEL
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(PERU_ENTEL)
+
+
+ @test_tracker_info(uuid="4708c783-ca89-498d-b74c-a6bc9df3fb32")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_peru_telefonica(self):
+ """ Verifies Wireless Emergency Alerts for PERU_TELEFONICA
+
+ configures the device to PERU_TELEFONICA
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(PERU_TELEFONICA)
+
+
+ @test_tracker_info(uuid="fefb293a-5c22-45b2-9323-ccb355245c9a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_puertorico(self):
+ """ Verifies Wireless Emergency Alerts for PUERTORICO
+
+ configures the device to PUERTORICO
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(PUERTORICO)
+
+
+ @test_tracker_info(uuid="7df5a2fd-fc20-46a1-8a57-c7690daf97ff")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_romania(self):
+ """ Verifies Wireless Emergency Alerts for ROMANIA
+
+ configures the device to ROMANIA
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(ROMANIA)
+
+
+ @test_tracker_info(uuid="cb1a2e92-eddb-4d8a-8b8d-96a0b8c558dd")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_saudiarabia(self):
+ """ Verifies Wireless Emergency Alerts for SAUDIARABIA
+
+ configures the device to SAUDIARABIA
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(SAUDIARABIA)
+
+
+ @test_tracker_info(uuid="0bf0196a-e456-4fa8-a735-b8d6d014ce7f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_southafrica(self):
+ """ Verifies Wireless Emergency Alerts for SOUTHAFRICA
+
+ configures the device to SOUTHAFRICA
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(SOUTHAFRICA)
+
+
+ @test_tracker_info(uuid="513c7d24-4957-49a4-98a2-f8a9444124ae")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_taiwan(self):
+ """ Verifies Wireless Emergency Alerts for TAIWAN
+
+ configures the device to TAIWAN
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(TAIWAN)
+
+
+ @test_tracker_info(uuid="43d54588-95e2-4e8a-b322-f6c99b9d3fbb")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_uae(self):
+ """ Verifies Wireless Emergency Alerts for UAE
+
+ configures the device to UAE
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(UAE)
+
+
+ @test_tracker_info(uuid="b44425c3-0d5b-498a-8322-86cc03eefd7d")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_uk(self):
+ """ Verifies Wireless Emergency Alerts for UK
+
+ configures the device to UK
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(UK)
+
+
+ @test_tracker_info(uuid="b3e73b61-6232-44f0-9507-9954387ab25b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_us_att(self):
+ """ Verifies Wireless Emergency Alerts for US ATT
+
+ configures the device to US ATT
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(US_ATT)
+
+
+ @test_tracker_info(uuid="f993d21d-c240-4196-8015-ea8f5967fdb3")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_us_tmo(self):
+ """ Verifies Wireless Emergency Alerts for US TMO
+
+ configures the device to US TMO
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(US_TMO)
+
+
+ @test_tracker_info(uuid="173293f2-4876-4891-ad2c-2b0d5269b2e0")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_us_vzw(self):
+ """ Verifies Wireless Emergency Alerts for US Verizon
+
+ configures the device to US Verizon
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(US_VZW)
+
+
+ @test_tracker_info(uuid="b94cc715-d2e2-47a4-91cd-acb47d64e6b2")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_germany_telekom(self):
+ """ Verifies Wireless Emergency Alerts for Germany telekom
+
+ configures the device to Germany telekom
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(GERMANY_TELEKOM)
+
+
+ @test_tracker_info(uuid="f0b0cdbf-32c4-4dfd-b8fb-03d8b6169fd1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_qatar_vodafone(self):
+ """ Verifies Wireless Emergency Alerts for Qatar vodafone.
+
+ configures the device to Qatar vodafone
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ return self._send_receive_test_flow(QATAR_VODAFONE)
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_5g_wifi_us_vzw(self):
+ """ Verifies WEA with WiFi and 5G NSA data network enabled for US Verizon.
+
+ configures the device to US Verizon
+ enables WiFi and 5G NSA data network.
+ connects to internet via WiFi.
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ result = True
+ if not self._setup_receive_test_flow_wifi(US_VZW, GEN_5G, True):
+ result = False
+ if result:
+ if not self._verify_send_receive_wea_alerts(self.android_devices[0], US_VZW):
+ result = False
+
+ get_screen_shot_log(self.android_devices[0])
+ return result
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_4g_wifi_us_vzw(self):
+ """ Verifies WEA with WiFi and 4G data network enabled for US Verizon.
+
+ configures the device to US Verizon
+ enables WiFi and 4G data network.
+ connects to internet via WiFi.
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ result = True
+ if not self._setup_receive_test_flow_wifi(US_VZW, GEN_4G, True):
+ result = False
+ if result:
+ if not self._verify_send_receive_wea_alerts(self.android_devices[0], US_VZW):
+ result = False
+
+ get_screen_shot_log(self.android_devices[0])
+ return result
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_3g_wifi_us_vzw(self):
+ """ Verifies WEA with WiFi and 3G data network enabled for US Verizon.
+
+ configures the device to US Verizon
+ enables WiFi and 3G data network.
+ connects to internet via WiFi.
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ result = True
+ if not self._setup_receive_test_flow_wifi(US_VZW, GEN_3G, True):
+ result = False
+ if result:
+ if not self._verify_send_receive_wea_alerts(self.android_devices[0], US_VZW):
+ result = False
+
+ get_screen_shot_log(self.android_devices[0])
+ return result
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_5g_wifi_only_us_vzw(self):
+ """ Verifies WEA with WiFi enabled and 5G NSA data network disabled for US Verizon.
+
+ configures the device to US Verizon
+ enables WiFi and disable 5G NSA data network.
+ connects to internet via WiFi.
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ result = True
+ if not self._setup_receive_test_flow_wifi(US_VZW, GEN_5G, False):
+ result = False
+ if result:
+ if not self._verify_send_receive_wea_alerts(self.android_devices[0], US_VZW):
+ result = False
+
+ get_screen_shot_log(self.android_devices[0])
+ return result
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_4g_wifi_only_us_vzw(self):
+ """ Verifies WEA with WiFi enabled and 4G data network disabled for US Verizon.
+
+ configures the device to US Verizon
+ enables WiFi and disable 4G data network.
+ connects to internet via WiFi.
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ result = True
+ if not self._setup_receive_test_flow_wifi(US_VZW, GEN_4G, False):
+ result = False
+ if result:
+ if not self._verify_send_receive_wea_alerts(self.android_devices[0], US_VZW):
+ result = False
+
+ get_screen_shot_log(self.android_devices[0])
+ return result
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_3g_wifi_only_us_vzw(self):
+ """ Verifies WEA with WiFi enabled and 3G data network disabled for US Verizon.
+
+ configures the device to US Verizon
+ enables WiFi and disable 3G data network.
+ connects to internet via WiFi.
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ result = True
+ if not self._setup_receive_test_flow_wifi(US_VZW, GEN_3G, False):
+ result = False
+ if result:
+ if not self._verify_send_receive_wea_alerts(self.android_devices[0], US_VZW):
+ result = False
+
+ get_screen_shot_log(self.android_devices[0])
+ return result
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_5g_wfc_wifi_only_us_vzw(self):
+ """ Verifies WEA with WFC mode and 5G NSA data network disabled for US Verizon.
+
+ configures the device to US Verizon
+ enables WFC mode and disable 5G NSA data network.
+ connects to internet via WiFi.
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ result = True
+ if not self._setup_receive_test_flow_wifi(US_VZW, GEN_5G, False)\
+ or not self._setup_wfc_mode(self.android_devices[0]):
+ result = False
+
+ if result:
+ if not self._verify_send_receive_wea_alerts(self.android_devices[0], US_VZW):
+ result = False
+
+ get_screen_shot_log(self.android_devices[0])
+ return result
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_4g_wfc_wifi_only_us_vzw(self):
+ """ Verifies WEA with WFC mode and 4G data network disabled for US Verizon.
+
+ configures the device to US Verizon
+ enables WFC mode and disable 4G data network.
+ connects to internet via WiFi.
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ result = True
+ if not self._setup_receive_test_flow_wifi(US_VZW, GEN_4G, False)\
+ or not self._setup_wfc_mode(self.android_devices[0]):
+ result = False
+
+ if result:
+ if not self._verify_send_receive_wea_alerts(self.android_devices[0], US_VZW):
+ result = False
+
+ get_screen_shot_log(self.android_devices[0])
+ return True
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_3g_wfc_wifi_only_us_vzw(self):
+ """ Verifies WEA with WFC mode and 3G data network disabled for US Verizon.
+
+ configures the device to US Verizon
+ enables WFC mode and disable 3G data network.
+ connects to internet via WiFi.
+ send alerts across all channels,
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ result = True
+ if not self._setup_receive_test_flow_wifi(US_VZW, GEN_3G, False)\
+ or not self._setup_wfc_mode(self.android_devices[0]):
+ result = False
+
+ if result:
+ if not self._verify_send_receive_wea_alerts(self.android_devices[0], US_VZW):
+ result = False
+
+ get_screen_shot_log(self.android_devices[0])
+ return True
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_5g_epdg_mo_wfc_wifi_only_us_vzw(self):
+ """ Verifies WEA during VoWiFi call for US Verizon.
+
+ configures the device to US Verizon
+ enables WFC mode and disable 5G NSA data network.
+ connects to internet via WiFi.
+ sends alerts across all channels and initiates mo VoWiFi call respectively.
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ result = True
+ if not self._setup_receive_test_flow_wifi(US_VZW, GEN_5G, False)\
+ or not self._setup_wfc_mode(self.android_devices[0]):
+ result = False
+
+ phone_setup_voice_general(self.log, self.android_devices[1] )
+
+ if result:
+ if not self._verify_send_receive_wea_alerts(self.android_devices[0], US_VZW, call=True):
+ result = False
+
+ get_screen_shot_log(self.android_devices[0])
+ return result
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_4g_epdg_mo_wfc_wifi_only_us_vzw(self):
+ """ Verifies WEA during VoWiFi call for US Verizon.
+
+ configures the device to US Verizon
+ enables WFC mode and disable 5G NSA data network.
+ connects to internet via WiFi.
+ sends alerts across all channels and initiates mo VoWiFi call respectively.
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ result = True
+ if not self._setup_receive_test_flow_wifi(US_VZW, GEN_4G, False)\
+ or not self._setup_wfc_mode(self.android_devices[0]):
+ result = False
+
+ phone_setup_voice_general(self.log, self.android_devices[1] )
+
+ if result:
+ if not self._verify_send_receive_wea_alerts(self.android_devices[0], US_VZW, call=True):
+ result = False
+
+ get_screen_shot_log(self.android_devices[0])
+ return result
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ def test_send_receive_alerts_3g_epdg_mo_wfc_wifi_only_us_vzw(self):
+ """ Verifies WEA during VoWiFi call for US Verizon.
+
+ configures the device to US Verizon
+ enables WFC mode and disable 5G NSA data network.
+ connects to internet via WiFi.
+ sends alerts across all channels and initiates mo VoWiFi call respectively.
+ verify if alert is received correctly
+ verify sound and vibration timing
+ click on OK/exit alert and verify text
+
+ Returns:
+ True if pass; False if fail and collects screenshot
+ """
+ result = True
+ if not self._setup_receive_test_flow_wifi(US_VZW, GEN_3G, False)\
+ or not self._setup_wfc_mode(self.android_devices[0]):
+ result = False
+
+ phone_setup_voice_general(self.log, self.android_devices[1] )
+
+ if result:
+ if not self._verify_send_receive_wea_alerts(self.android_devices[0], US_VZW, call=True):
+ result = False
+
+ get_screen_shot_log(self.android_devices[0])
+ return result
+
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gActivationTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gActivationTest.py
index 87e7856..eab184d 100755
--- a/acts_tests/tests/google/nr/nsa5g/Nsa5gActivationTest.py
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gActivationTest.py
@@ -21,18 +21,9 @@
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_defines import GEN_4G
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_WCDMA_ONLY
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
from acts_contrib.test_utils.tel.tel_test_utils import reboot_device
-from acts_contrib.test_utils.tel.tel_test_utils import get_current_override_network_type
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_generation
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_toggle_state
-from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_network_mode_pref
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_nsa
-from acts_contrib.test_utils.tel.tel_5g_test_utils import set_preferred_mode_for_5g
+from acts_contrib.test_utils.tel.tel_test_utils import cycle_airplane_mode
+from acts_contrib.test_utils.tel.tel_5g_test_utils import test_activation_by_condition
class Nsa5gActivationTest(TelephonyBaseTest):
@@ -63,29 +54,10 @@
Returns:
True if pass; False if fail.
"""
- ad = self.android_devices[0]
- wifi_toggle_state(ad.log, ad, False)
- set_preferred_mode_for_5g(ad)
- for iteration in range(3):
- ad.log.info("Attempt %d", iteration + 1)
- # APM toggle
- toggle_airplane_mode(ad.log, ad, True)
- toggle_airplane_mode(ad.log, ad, False)
- # LTE attach
- if not wait_for_network_generation(
- ad.log, ad, GEN_4G, voice_or_data=NETWORK_SERVICE_DATA):
- ad.log.error("Fail to ensure initial data in 4G")
- # 5G attach
- ad.log.info("Waiting for 5g NSA attach for 60 secs")
- if is_current_network_5g_nsa(ad, timeout=60):
- ad.log.info("Success! attached on 5g NSA")
- return True
- else:
- ad.log.error("Failure - expected NR_NSA, current %s",
- get_current_override_network_type(ad))
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ad.log.info("nsa5g attach test FAIL for all 3 iterations")
- return False
+
+ return test_activation_by_condition(self.android_devices[0],
+ nr_type='nsa',
+ precond_func=lambda: cycle_airplane_mode(self.android_devices[0]))
@test_tracker_info(uuid="d4f5f0c5-cc58-4531-96dd-32eed9121b95")
@@ -101,29 +73,10 @@
Returns:
True if pass; False if fail.
"""
- ad = self.android_devices[0]
- wifi_toggle_state(ad.log, ad, False)
- toggle_airplane_mode(ad.log, ad, False)
- set_preferred_mode_for_5g(ad)
- for iteration in range(3):
- ad.log.info("Attempt %d", iteration + 1)
- # Reboot phone
- reboot_device(ad)
- # LTE attach
- if not wait_for_network_generation(
- ad.log, ad, GEN_4G, voice_or_data=NETWORK_SERVICE_DATA):
- ad.log.error("Fail to ensure initial data in 4G")
- # 5G attach
- ad.log.info("Waiting for 5g NSA attach for 60 secs")
- if is_current_network_5g_nsa(ad, timeout=60):
- ad.log.info("Success! attached on 5g NSA")
- return True
- else:
- ad.log.error("Failure - expected NR_NSA, current %s",
- get_current_override_network_type(ad))
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ad.log.info("nsa5g reboot test FAIL for all 3 iterations")
- return False
+
+ return test_activation_by_condition(self.android_devices[0],
+ nr_type='nsa',
+ precond_func=lambda: reboot_device(self.android_devices[0]))
@test_tracker_info(uuid="1ceda4b5-4a6a-43fa-8976-67cbfb7eab5b")
@@ -140,32 +93,9 @@
Returns:
True if pass; False if fail.
"""
- ad = self.android_devices[0]
- sub_id = ad.droid.subscriptionGetDefaultSubId()
- wifi_toggle_state(ad.log, ad, False)
- toggle_airplane_mode(ad.log, ad, False)
- for iteration in range(3):
- ad.log.info("Attempt %d", iteration + 1)
- # Set mode pref to 3G
- set_preferred_network_mode_pref(ad.log, ad, sub_id,
- NETWORK_MODE_WCDMA_ONLY)
- time.sleep(15)
- # Set mode pref to 5G
- set_preferred_mode_for_5g(ad)
- # LTE attach
- if not wait_for_network_generation(
- ad.log, ad, GEN_4G, voice_or_data=NETWORK_SERVICE_DATA):
- ad.log.error("Fail to ensure initial data in 4G")
- # 5G attach
- ad.log.info("Waiting for 5g NSA attach for 60 secs")
- if is_current_network_5g_nsa(ad, timeout=60):
- ad.log.info("Success! attached on 5g NSA")
- return True
- else:
- ad.log.error("Failure - expected NR_NSA, current %s",
- get_current_override_network_type(ad))
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ad.log.info("nsa5g mode pref from 3G test FAIL for all 3 iterations")
- return False
+
+ return test_activation_by_condition(self.android_devices[0],
+ from_3g=True,
+ nr_type='nsa')
""" Tests End """
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSDDSSwitchTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSDDSSwitchTest.py
new file mode 100644
index 0000000..9c2ddce
--- /dev/null
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSDDSSwitchTest.py
@@ -0,0 +1,427 @@
+#!/usr/bin/env python3
+#
+# Copyright 2020 - Google
+#
+# 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.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
+from acts_contrib.test_utils.tel.tel_dsds_utils import dds_switch_during_data_transfer_test
+from acts_contrib.test_utils.tel.tel_dsds_utils import dsds_dds_swap_call_streaming_test
+from acts_contrib.test_utils.tel.tel_dsds_utils import dsds_dds_swap_message_streaming_test
+from acts_contrib.test_utils.tel.tel_defines import YOUTUBE_PACKAGE_NAME
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+
+class Nsa5gDSDSDDSSwitchTest(TelephonyBaseTest):
+ def setup_class(self):
+ TelephonyBaseTest.setup_class(self)
+ self.message_lengths = (50, 160, 180)
+ self.tel_logger = TelephonyMetricLogger.for_test_case()
+
+ def teardown_test(self):
+ self.android_devices[0].force_stop_apk(YOUTUBE_PACKAGE_NAME)
+ ensure_phones_idle(self.log, self.android_devices)
+
+ @test_tracker_info(uuid="0514be56-48b1-4ae9-967f-2326939ef386")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_sms_dds_psim_5g_nsa_volte_esim_5g_nsa_volte(self):
+ """ 5G NSA DDS swap SMS test(Initial DDS is on SIM1).
+
+ 1. Make MO/MT SMS via SIM1 when DDS is on SIM1 and idle.
+ 2. Switch DDS to SIM2.
+ 3. Make MO/MT SMS via SIM2 when DDS is on SIM2 and idle.
+ 4. Switch DDS to SIM1, make sure data works fine.
+
+ After Make/Receive SMS will check the dds slot if is attach to the
+ network with assigned RAT successfully and data works fine.
+ """
+ return dsds_dds_swap_message_streaming_test(
+ self.log,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=[0, 1],
+ init_dds=0,
+ msg_type="SMS",
+ direction="mt",
+ streaming=False)
+
+ @test_tracker_info(uuid="d04fca02-881c-4089-bfdf-b1d84c301ff1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_sms_non_dds_psim_5g_nsa_volte_esim_5g_nsa_volte(self):
+ """ 5G NSA DDS swap SMS test(Initial DDS is on SIM1).
+
+ 1. Make MO/MT SMS via SIM2 when DDS is on SIM1 and idle.
+ 2. Switch DDS to SIM2.
+ 3. Make MO/MT SMS via SIM1 when DDS is on SIM2 and idle.
+ 4. Switch DDS to SIM1, make sure data works fine.
+
+ After Make/Receive SMS will check the dds slot if is attach to the
+ network with assigned RAT successfully and data works fine.
+ """
+ return dsds_dds_swap_message_streaming_test(
+ self.log,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=[1, 0],
+ init_dds=0,
+ msg_type="SMS",
+ direction="mt",
+ streaming=False)
+
+ @test_tracker_info(uuid="e5562a55-788a-4c33-9b97-8eeb8e412052")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_youtube_sms_dds_psim_5g_nsa_volte_esim_5g_nsa_volte(self):
+ """ 5G NSA DDS swap SMS test(Initial DDS is on SIM1).
+
+ 1. Start Youtube streaming.
+ 2. Make MO/MT SMS via SIM1 when DDS is on SIM1 and idle.
+ 3. Stop Youtube streaming.
+ 4. Switch DDS to SIM2.
+ 5. Start Youtube streaming.
+ 6. Make MO/MT SMS via SIM2 when DDS is on SIM2 and idle.
+ 7. Stop Youtube streaming.
+ 8. Switch DDS to SIM1, make sure data works fine.
+
+ After Make/Receive SMS will check the dds slot if is attach to the
+ network with assigned RAT successfully and data works fine.
+ """
+ return dsds_dds_swap_message_streaming_test(
+ self.log,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=[0, 1],
+ init_dds=0,
+ msg_type="SMS",
+ direction="mt",
+ streaming=True)
+
+ @test_tracker_info(uuid="71fb524f-4777-4aa5-aa94-28d6d46dc253")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_youtube_sms_non_dds_psim_5g_nsa_volte_esim_5g_nsa_volte(self):
+ """ 5G NSA DDS swap SMS test(Initial DDS is on SIM1).
+
+ 1. Start Youtube streaming.
+ 2. Make MO/MT SMS via SIM2 when DDS is on SIM1 and idle.
+ 3. Stop Youtube streaming.
+ 4. Switch DDS to SIM2.
+ 5. Start Youtube streaming.
+ 6. Make MO/MT SMS via SIM1 when DDS is on SIM2 and idle.
+ 7. Stop Youtube streaming.
+ 8. Switch DDS to SIM1, make sure data works fine.
+
+ After Make/Receive SMS will check the dds slot if is attach to the
+ network with assigned RAT successfully and data works fine.
+ """
+ return dsds_dds_swap_message_streaming_test(
+ self.log,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=[1, 0],
+ init_dds=0,
+ msg_type="SMS",
+ direction="mt",
+ streaming=True)
+
+ @test_tracker_info(uuid="3f7cf6ff-a3ec-471b-8a13-e3035dd791c6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_mms_dds_psim_5g_nsa_volte_esim_5g_nsa_volte(self):
+ """ 5G NSA DDS swap MMS test(Initial DDS is on SIM1).
+
+ 1. Make MO/MT MMS via SIM1 when DDS is on SIM1 and idle.
+ 2. Switch DDS to SIM2.
+ 3. Make MO/MT MMS via SIM2 when DDS is on SIM2 and idle.
+ 4. Switch DDS to SIM1, make sure data works fine.
+
+ After Make/Receive MMS will check the dds slot if is attach to the
+ network with assigned RAT successfully and data works fine.
+ """
+ return dsds_dds_swap_message_streaming_test(
+ self.log,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=[0, 1],
+ init_dds=0,
+ msg_type="MMS",
+ direction="mt",
+ streaming=False)
+
+ @test_tracker_info(uuid="311205dd-f484-407c-bd4a-93c25a78b02a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_mms_non_dds_psim_5g_nsa_volte_esim_5g_nsa_volte(self):
+ """ 5G NSA DDS swap MMS test(Initial DDS is on SIM1).
+
+ 1. Make MO/MT MMS via SIM2 when DDS is on SIM1 and idle.
+ 2. Switch DDS to SIM2.
+ 3. Make MO/MT MMS via SIM1 when DDS is on SIM2 and idle.
+ 4. Switch DDS to SIM1, make sure data works fine.
+
+ After Make/Receive MMS will check the dds slot if is attach to the
+ network with assigned RAT successfully and data works fine.
+ """
+ return dsds_dds_swap_message_streaming_test(
+ self.log,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=[1, 0],
+ init_dds=0,
+ msg_type="MMS",
+ direction="mt",
+ streaming=False)
+
+ @test_tracker_info(uuid="d817ee1d-8825-4614-abb1-f813c5f4c7de")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_youtube_mms_dds_psim_5g_nsa_volte_esim_5g_nsa_volte(self):
+ """ 5G NSA DDS swap MMS test(Initial DDS is on SIM1).
+
+ 1. Start Youtube streaming.
+ 2. Make MO/MT MMS via SIM1 when DDS is on SIM1 and idle.
+ 3. Stop Youtube streaming.
+ 4. Switch DDS to SIM2.
+ 5. Start Youtube streaming.
+ 6. Make MO/MT MMS via SIM2 when DDS is on SIM2 and idle.
+ 7. Stop Youtube streaming.
+ 8. Switch DDS to SIM1, make sure data works fine.
+
+ After Make/Receive MMS will check the dds slot if is attach to the
+ network with assigned RAT successfully and data works fine.
+ """
+ return dsds_dds_swap_message_streaming_test(
+ self.log,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=[0, 1],
+ init_dds=0,
+ msg_type="MMS",
+ direction="mt",
+ streaming=True)
+
+ @test_tracker_info(uuid="131f68c6-e0b6-41cb-85c5-a2df125e01b3")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_youtube_mms_non_dds_psim_5g_nsa_volte_esim_5g_nsa_volte(self):
+ """ 5G NSA DDS swap MMS test(Initial DDS is on SIM1).
+
+ 1. Start Youtube streaming.
+ 2. Make MO/MT MMS via SIM2 when DDS is on SIM1 and idle.
+ 3. Stop Youtube streaming.
+ 4. Switch DDS to SIM2.
+ 5. Start Youtube streaming.
+ 6. Make MO/MT MMS via SIM1 when DDS is on SIM2 and idle.
+ 7. Stop Youtube streaming.
+ 8. Switch DDS to SIM1, make sure data works fine.
+
+ After Make/Receive MMS will check the dds slot if is attach to the
+ network with assigned RAT successfully and data works fine.
+ """
+ return dsds_dds_swap_message_streaming_test(
+ self.log,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=[1, 0],
+ init_dds=0,
+ msg_type="MMS",
+ direction="mt",
+ streaming=True)
+
+ @test_tracker_info(uuid="1c3ba14c-d7f6-4737-8ac2-f55fa3b6cc46")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_voice_psim_mo_5g_nsa_volte_esim_5g_nsa_volte(self):
+ """ 5G NSA DDS swap call test(Initial DDS is on SIM1).
+
+ 1. Make MO call via SIM1 when DDS is on SIM1 and idle.
+ 2. Switch DDS to SIM2.
+ 3. Make MO call via SIM1 when DDS is on SIM2 and idle.
+ 4. Switch DDS to SIM1, make sure data works fine.
+
+ After call end will check the dds slot if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_dds_swap_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=[0, 0],
+ init_dds=0,
+ direction="mo",
+ duration=30,
+ streaming=False)
+
+ @test_tracker_info(uuid="55c3fbd0-0b8b-4275-81a0-1e1715b66ec1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_voice_psim_mt_5g_nsa_volte_esim_5g_nsa_volte(self):
+ """ 5G NSA DDS swap call test(Initial DDS is on SIM1).
+
+ 1. Receive MT call via SIM1 when DDS is on SIM1 and idle.
+ 2. Switch DDS to SIM2.
+ 3. Receive MT call via SIM1 when DDS is on SIM2 and idle.
+ 4. Switch DDS to SIM1, make sure data works fine.
+
+ After call end will check the dds slot if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_dds_swap_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=[0, 0],
+ init_dds=0,
+ direction="mt",
+ duration=30,
+ streaming=False)
+
+ @test_tracker_info(uuid="1359b4a9-7e3e-4b34-b512-4638ab4ab4a7")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_voice_esim_mo_5g_nsa_volte_psim_5g_nsa_volte(self):
+ """ 5G NSA DDS swap call test(Initial DDS is on SIM1).
+
+ 1. Make MO call via SIM2 when DDS is on SIM1 and idle.
+ 2. Switch DDS to SIM2.
+ 3. Make MO call via SIM2 when DDS is on SIM2 and idle.
+ 4. Switch DDS to SIM1, make sure data works fine.
+
+ After call end will check the dds slot if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_dds_swap_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=[1, 1],
+ init_dds=0,
+ direction="mo",
+ duration=30,
+ streaming=False)
+
+ @test_tracker_info(uuid="f4a290dc-3a8b-4364-8b6e-35275a6b8f92")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_voice_esim_mt_5g_nsa_volte_psim_5g_nsa_volte(self):
+ """ 5G NSA DDS swap call test(Initial DDS is on SIM1).
+
+ 1. Receive MT call via SIM2 when DDS is on SIM1 and idle.
+ 2. Switch DDS to SIM2.
+ 3. Receive MT call via SIM2 when DDS is on SIM2 and idle.
+ 4. Switch DDS to SIM1, make sure data works fine.
+
+ After call end will check the dds slot if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_dds_swap_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=[1, 1],
+ init_dds=0,
+ direction="mt",
+ duration=30,
+ streaming=False)
+
+ @test_tracker_info(uuid="727a75ef-7277-42fe-8a4b-7b2debe666d9")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_youtube_psim_5g_nsa_volte_esim_5g_nsa_volte(self):
+ return dds_switch_during_data_transfer_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ nw_rat=["5g_volte", "5g_volte"])
+
+ @test_tracker_info(uuid="4ef4626a-11b3-4a09-ac98-2e3d94e54bf7")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_youtube_and_voice_mo_psim_5g_nsa_volte_esim_5g_nsa_volte(self):
+ return dds_switch_during_data_transfer_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ nw_rat=["5g_volte", "5g_volte"],
+ call_slot=0,
+ call_direction="mo")
+
+ @test_tracker_info(uuid="ef3bc49f-e94f-432b-bb51-4b6008359313")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_youtube_and_voice_mt_psim_5g_nsa_volte_esim_5g_nsa_volte(self):
+ return dds_switch_during_data_transfer_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ nw_rat=["5g_volte", "5g_volte"],
+ call_slot=0,
+ call_direction="mt")
+
+ @test_tracker_info(uuid="6d913c58-dde5-453d-b9a9-30e76cdac554")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_youtube_and_voice_mo_esim_5g_nsa_volte_psim_5g_nsa_volte(self):
+ return dds_switch_during_data_transfer_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ nw_rat=["5g_volte", "5g_volte"],
+ call_slot=1,
+ call_direction="mo")
+
+ @test_tracker_info(uuid="df91d2ce-ef5e-4d38-a642-6470ade625c6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_youtube_and_voice_mt_esim_5g_nsa_volte_psim_5g_nsa_volte(self):
+ return dds_switch_during_data_transfer_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ nw_rat=["5g_volte", "5g_volte"],
+ call_slot=1,
+ call_direction="mt")
+
+ @test_tracker_info(uuid="4ba86f3c-1de6-4888-a2e5-a5e6079c3886")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_youtube_and_voice_mo_psim_5g_nsa_csfb_esim_5g_nsa_csfb(self):
+ return dds_switch_during_data_transfer_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ nw_rat=["5g_csfb", "5g_csfb"],
+ call_slot=0,
+ call_direction="mo")
+
+ @test_tracker_info(uuid="aa426eb2-dc7b-4ffe-aaa2-a3204251c131")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_youtube_and_voice_mt_psim_5g_nsa_csfb_esim_5g_nsa_csfb(self):
+ return dds_switch_during_data_transfer_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ nw_rat=["5g_csfb", "5g_csfb"],
+ call_slot=0,
+ call_direction="mt")
+
+ @test_tracker_info(uuid="854634e8-7a2a-4d14-8269-8f4f463f8f56")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_youtube_and_voice_mo_esim_5g_nsa_csfb_psim_5g_nsa_csfb(self):
+ return dds_switch_during_data_transfer_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ nw_rat=["5g_csfb", "5g_csfb"],
+ call_slot=1,
+ call_direction="mo")
+
+ @test_tracker_info(uuid="02478b9e-6bf6-4148-bbc4-0cbdf59f1625")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch_youtube_and_voice_mt_esim_5g_nsa_csfb_psim_5g_nsa_csfb(self):
+ return dds_switch_during_data_transfer_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ nw_rat=["5g_csfb", "5g_csfb"],
+ call_slot=1,
+ call_direction="mt")
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSMessageTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSMessageTest.py
new file mode 100644
index 0000000..a21cde3
--- /dev/null
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSMessageTest.py
@@ -0,0 +1,801 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - Google
+#
+# 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.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
+from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
+from acts_contrib.test_utils.tel.tel_defines import YOUTUBE_PACKAGE_NAME
+from acts_contrib.test_utils.tel.tel_dsds_utils import dsds_message_test
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+
+CallResult = TelephonyVoiceTestResult.CallResult.Value
+
+class Nsa5gDSDSMessageTest(TelephonyBaseTest):
+ def setup_class(self):
+ TelephonyBaseTest.setup_class(self)
+ self.tel_logger = TelephonyMetricLogger.for_test_case()
+
+ def teardown_test(self):
+ ensure_phones_idle(self.log, self.android_devices)
+
+ @test_tracker_info(uuid="123a50bc-f0a0-4129-9377-cc63c76d5727")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mo_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 0, mo_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="5dcf76bc-369f-4d47-b3ec-318559a95843")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mt_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 0, mt_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="245a6148-cd45-4b82-bf4c-5679ebe15e29")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mo_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 1, mo_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="5a93d377-d9bc-477c-bfab-2496064e3522")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mt_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 1, mt_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="dd4a9fb5-b0fe-492b-ad24-61e022d13a22")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mo_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 0, mo_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="09100a8f-b7ed-41a0-9f04-e716115cabb8")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mt_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 0, mt_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="b5971c57-bbe9-4e87-a6f2-9953fa770a15")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mo_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 1, mo_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="142b11d4-b593-4a09-8fc6-35e310739244")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mt_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 1, mt_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="87759475-0208-4d9b-b5b9-814fdb97f09c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mo_psim_5g_nsa_volte_esim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 0, mo_rat=["5g_volte", "volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="2f14e81d-330f-4cdd-837c-1168185ffec4")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mt_psim_5g_nsa_volte_esim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 0, mt_rat=["5g_volte", "volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="38f01127-54bf-4c55-b7d8-d8f41352b399")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mo_psim_5g_nsa_volte_esim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 1, mo_rat=["5g_volte", "volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="4e0c9692-a758-4169-85fe-c33bd2651525")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mt_psim_5g_nsa_volte_esim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 1, mt_rat=["5g_volte", "volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="9cc45474-1fca-4008-8499-87829d6516ea")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mo_esim_4g_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 0, mo_rat=["5g_volte", "volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="341786de-5b23-438a-a91b-97cf420ef5fd")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mt_esim_4g_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 0, mt_rat=["5g_volte", "volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="527e8629-6e0d-4742-98c0-5cbc868c430e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mo_esim_4g_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 1, mo_rat=["5g_volte", "volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="66277aa0-0a9a-4a25-828f-b0315ae7fd0e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mt_esim_4g_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 1, mt_rat=["5g_volte", "volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="a4d797b6-2699-48de-b36b-b10a1901305b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mo_psim_4g_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 0, mo_rat=["volte", "5g_volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="371286ba-f1da-4459-a7e8-0368d0fae147")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mt_psim_4g_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 0, mt_rat=["volte", "5g_volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="183cda35-45aa-485d-b3d4-975d78f7d361")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mo_psim_4g_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 1, mo_rat=["volte", "5g_volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="d9cb69ce-c462-4fd4-b716-bfb1fd2ed86a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mt_psim_4g_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 1, mt_rat=["volte", "5g_volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="dfe54cea-8396-4af4-8aee-9dadad602e5b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mo_esim_5g_nsa_volte_psim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 0, mo_rat=["volte", "5g_volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="fd4ae44c-3527-4b90-8d33-face10e160a6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mt_esim_5g_nsa_volte_psim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 0, mt_rat=["volte", "5g_volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="51d5e05d-66e7-4369-91e0-6cdc573d9a59")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mo_esim_5g_nsa_volte_psim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 1, mo_rat=["volte", "5g_volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="38271a0f-2efb-4991-9f24-6da9f003ddd4")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_sms_mt_esim_5g_nsa_volte_psim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 1, mt_rat=["volte", "5g_volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="dde1e900-abcd-4a5f-8872-02456ea248ee")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mo_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 0, mo_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="5a8ad6dc-687a-498e-8b99-119f3cbb781c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mt_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 0, mt_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="765443f4-d4a0-45fe-8c97-763feb4b588b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mo_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 1, mo_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="026b9e8f-400e-4b59-b40d-d4e741838be0")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mt_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 1, mt_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="468536c1-de6e-48e7-b59e-11f17389ac12")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mo_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 0, mo_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="c4ae7f6b-bc20-4cb2-8e41-8a02171aec6f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mt_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 0, mt_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="2d70443e-b442-48e0-9c1f-ce1409184ff8")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mo_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 1, mo_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="47fbc6c0-ca76-44c0-a166-d8c99d16b6ac")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mt_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 1, mt_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="39684fbc-73d1-48cb-af3f-07a366a6b190")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mo_psim_5g_nsa_volte_esim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 0, mo_rat=["5g_volte", "volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="6adf4163-4969-4129-bbac-4ebdac4c4cf5")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mt_psim_5g_nsa_volte_esim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 0, mt_rat=["5g_volte", "volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="7b636038-5b0c-4844-ba2a-2e76ed787f72")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mo_psim_5g_nsa_volte_esim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 1, mo_rat=["5g_volte", "volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="b5008ad4-372d-4849-b47b-583be6aa080a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mt_psim_5g_nsa_volte_esim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 1, mt_rat=["5g_volte", "volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="fd6b33b6-c654-4ec0-becc-2fd7ec10c291")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mo_esim_4g_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 0, mo_rat=["5g_volte", "volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="0267c4e8-e5b8-4001-912f-76c387a15f79")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mt_esim_4g_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 0, mt_rat=["5g_volte", "volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="a54caa16-dfc6-46e1-a376-b4b585e2e840")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mo_esim_4g_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 1, mo_rat=["5g_volte", "volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="f6af184a-933b-467e-81a7-44ef48b56540")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mt_esim_4g_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 1, mt_rat=["5g_volte", "volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="2e89f125-aacc-4c36-a1c2-308cd83b0e22")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mo_psim_4g_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 0, mo_rat=["volte", "5g_volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="03c23c94-3cc5-4ecf-9b87-273c815b9f53")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mt_psim_4g_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 0, mt_rat=["volte", "5g_volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="d2af382a-0f87-46c0-b2de-84f5a549e32c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mo_psim_4g_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 1, mo_rat=["volte", "5g_volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="bf788d99-954b-47e2-b465-8565bb30e907")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mt_psim_4g_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 1, mt_rat=["volte", "5g_volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="f0b1d46b-6ddc-4625-b653-38e323e542ad")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mo_esim_5g_nsa_volte_psim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 0, mo_rat=["volte", "5g_volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="b17a4943-1f69-428a-bd63-13144b2bc592")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mt_esim_5g_nsa_volte_psim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 0, mt_rat=["volte", "5g_volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="98d7b7b8-0bd3-4362-957b-56c8b19ac3d4")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mo_esim_5g_nsa_volte_psim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 1, mo_rat=["volte", "5g_volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="5f0f4174-548d-43ab-b520-5e2211fdaacc")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_mms_mt_esim_5g_nsa_volte_psim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 1, mt_rat=["volte", "5g_volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="09cd2c80-5c94-4b97-badd-b9d23712cbad")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mo_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 0, mo_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mo", streaming=True)
+
+ @test_tracker_info(uuid="deed7037-932e-4c08-bbf0-989144a51193")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mt_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 0, mt_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mt", streaming=True)
+
+ @test_tracker_info(uuid="14fe5ef1-e6aa-4615-887a-ac26043c2dfc")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mo_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 1, mo_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mo", streaming=True)
+
+ @test_tracker_info(uuid="1f07d373-dc81-42f4-a5c5-461304f1e7bf")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mt_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 1, mt_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mt", streaming=True)
+
+ @test_tracker_info(uuid="a9f066d3-a5db-4319-a5c9-f7a20f84cd6e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mo_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 0, mo_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mo", streaming=True)
+
+ @test_tracker_info(uuid="688485af-cdc7-43b7-af01-baf6bc695b70")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mt_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 0, mt_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mt", streaming=True)
+
+ @test_tracker_info(uuid="7fef6173-1f37-45d3-be94-60fea340444c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mo_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 1, mo_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mo", streaming=True)
+
+ @test_tracker_info(uuid="71b15942-6c8f-41b3-8dc9-5a1dea64aad4")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mt_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 1, mt_rat=["5g_volte", "5g_volte"], msg="SMS", direction="mt", streaming=True)
+
+ @test_tracker_info(uuid="6cbc50e7-e135-405d-bf69-ab074d345d80")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mo_psim_5g_nsa_volte_esim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 0, mo_rat=["5g_volte", "volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="d976560a-1ea1-421a-9c2d-906cbfb7654e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mt_psim_5g_nsa_volte_esim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 0, mt_rat=["5g_volte", "volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="0e3a10b2-2351-49a2-9282-99aae1372bf0")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mo_psim_5g_nsa_volte_esim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 1, mo_rat=["5g_volte", "volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="e713c430-0bfa-4d25-91f3-1b6fec84b3a5")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mt_psim_5g_nsa_volte_esim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 1, mt_rat=["5g_volte", "volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="770bec4d-c1c9-4936-8683-3fb796827eba")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mo_esim_4g_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 0, mo_rat=["5g_volte", "volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="3f34328b-9295-4740-a48b-3ffadbab3fb5")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mt_esim_4g_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 0, mt_rat=["5g_volte", "volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="eeaeb58a-7566-498e-a4d1-ce1cbd82f362")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mo_esim_4g_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 1, mo_rat=["5g_volte", "volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="7550ef0b-b0d3-4932-95d3-119abdad53ad")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mt_esim_4g_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 1, mt_rat=["5g_volte", "volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="6dd693f4-6c61-4048-9027-02c17874dbd0")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mo_psim_4g_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 0, mo_rat=["volte", "5g_volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="976d5c30-63af-4e49-952e-2cd4147b7c8d")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mt_psim_4g_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 0, mt_rat=["volte", "5g_volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="b2c94d26-c806-417d-a751-618491dce246")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mo_psim_4g_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 1, mo_rat=["volte", "5g_volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="02739364-2848-4242-bb6e-41a03ec358ed")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mt_psim_4g_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 1, mt_rat=["volte", "5g_volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="811880fd-c422-4548-8dfb-cddbfb1dc6c0")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mo_esim_5g_nsa_volte_psim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 0, mo_rat=["volte", "5g_volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="9e02ade7-c2b6-4b7e-ab15-b42c119f4141")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mt_esim_5g_nsa_volte_psim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 0, mt_rat=["volte", "5g_volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="ba2ce2de-a0a6-4abe-adb8-110541e60cb1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mo_esim_5g_nsa_volte_psim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 1, mo_rat=["volte", "5g_volte"], msg="SMS", direction="mo")
+
+ @test_tracker_info(uuid="46e1397c-7296-4aac-8e0f-7049d04427bc")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_sms_mt_esim_5g_nsa_volte_psim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 1, mt_rat=["volte", "5g_volte"], msg="SMS", direction="mt")
+
+ @test_tracker_info(uuid="181c1ac9-625e-450d-b566-834e20ecd59d")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mo_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 0, mo_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mo", streaming=True)
+
+ @test_tracker_info(uuid="b37aceed-7f67-4ae3-aba8-0f94d24d81e2")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mt_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 0, mt_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mt", streaming=True)
+
+ @test_tracker_info(uuid="0fb13f48-bfd7-4019-8a33-e229677b3357")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mo_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 1, mo_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mo", streaming=True)
+
+ @test_tracker_info(uuid="016369fa-3420-45f5-9ed2-3776816f4e4b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mt_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 1, mt_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mt", streaming=True)
+
+ @test_tracker_info(uuid="65fdbecf-9ea5-4881-9e99-4a1ed90b76cc")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mo_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 0, mo_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mo", streaming=True)
+
+ @test_tracker_info(uuid="3e6b4bcf-30cd-4502-8811-2a5a7a9142a5")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mt_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 0, mt_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mt", streaming=True)
+
+ @test_tracker_info(uuid="a49b7a91-8811-403b-b8ed-ac0edad69c2c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mo_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 1, mo_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mo", streaming=True)
+
+ @test_tracker_info(uuid="961db859-ad50-4b13-8555-e523843d3e0c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mt_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 1, mt_rat=["5g_volte", "5g_volte"], msg="MMS", direction="mt", streaming=True)
+
+ @test_tracker_info(uuid="398fea0a-4ef4-4a6d-bea0-76ab0b2e2c34")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mo_psim_5g_nsa_volte_esim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 0, mo_rat=["5g_volte", "volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="06503954-caff-47ba-8ed3-7793fca4e94a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mt_psim_5g_nsa_volte_esim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 0, mt_rat=["5g_volte", "volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="bc43d539-7bbd-4b12-b88a-ecf0229f1ed5")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mo_psim_5g_nsa_volte_esim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 1, mo_rat=["5g_volte", "volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="d558a53b-396e-4a9e-aec1-929f41f8ad2a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mt_psim_5g_nsa_volte_esim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 1, mt_rat=["5g_volte", "volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="74afcd0a-e121-4028-99c6-48cad25b18b8")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mo_esim_4g_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 0, mo_rat=["5g_volte", "volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="5042ec42-f1b3-466a-8e06-6e1c3de2dffb")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mt_esim_4g_volte_psim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 0, mt_rat=["5g_volte", "volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="6f286c93-004b-4360-9afa-78f15a0a5549")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mo_esim_4g_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 1, mo_rat=["5g_volte", "volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="0313548b-653b-44ea-bb63-76b69b67e456")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mt_esim_4g_volte_psim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 1, mt_rat=["5g_volte", "volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="4c1e4667-2b0d-4f4d-a419-c349ef767dbc")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mo_psim_4g_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 0, mo_rat=["volte", "5g_volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="f82650db-d0d9-4990-a3c6-b918eabeddc6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mt_psim_4g_volte_esim_5g_nsa_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 0, mt_rat=["volte", "5g_volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="76dca39c-8ead-435b-8b5f-8b167946a18e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mo_psim_4g_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 0, None, 1, mo_rat=["volte", "5g_volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="29d8ffec-be68-4d12-b2ad-b2e8f95347c1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mt_psim_4g_volte_esim_5g_nsa_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 0, 1, mt_rat=["volte", "5g_volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="625bc42e-c9c7-442e-8464-72aab6055ef8")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mo_esim_5g_nsa_volte_psim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 0, mo_rat=["volte", "5g_volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="18f852da-0877-4624-bbcd-d59a168780dc")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mt_esim_5g_nsa_volte_psim_4g_volte_dds_0(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 0, mt_rat=["volte", "5g_volte"], msg="MMS", direction="mt")
+
+ @test_tracker_info(uuid="cac044ec-176d-4eef-885d-ba419ab634eb")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mo_esim_5g_nsa_volte_psim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ 1, None, 1, mo_rat=["volte", "5g_volte"], msg="MMS", direction="mo")
+
+ @test_tracker_info(uuid="245ee61e-f768-403c-9005-7eed90deedd7")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_youtube_and_mms_mt_esim_5g_nsa_volte_psim_4g_volte_dds_1(self):
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
+ None, 1, 1, mt_rat=["volte", "5g_volte"], msg="MMS", direction="mt")
\ No newline at end of file
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSSupplementaryServiceTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSSupplementaryServiceTest.py
new file mode 100644
index 0000000..2b06b2c
--- /dev/null
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSSupplementaryServiceTest.py
@@ -0,0 +1,1257 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - Google
+#
+# 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 signals
+from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_CONFERENCE
+from acts_contrib.test_utils.tel.tel_dsds_utils import erase_call_forwarding
+from acts_contrib.test_utils.tel.tel_dsds_utils import msim_call_forwarding
+from acts_contrib.test_utils.tel.tel_dsds_utils import msim_call_voice_conf
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_ss_utils import set_call_waiting
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
+from acts_contrib.test_utils.tel.tel_test_utils import get_capability_for_subscription
+
+
+class Nsa5gDSDSSupplementaryServiceTest(TelephonyBaseTest):
+ def setup_class(self):
+ TelephonyBaseTest.setup_class(self)
+ self.message_lengths = (50, 160, 180)
+ self.tel_logger = TelephonyMetricLogger.for_test_case()
+ erase_call_forwarding(self.log, self.android_devices[0])
+ if not get_capability_for_subscription(
+ self.android_devices[0],
+ CAPABILITY_CONFERENCE,
+ get_outgoing_voice_sub_id(self.android_devices[0])):
+ self.android_devices[0].log.error(
+ "Conference call is not supported, abort test.")
+ raise signals.TestAbortClass(
+ "Conference call is not supported, abort test.")
+
+ def teardown_test(self):
+ ensure_phones_idle(self.log, self.android_devices)
+ erase_call_forwarding(self.log, self.android_devices[0])
+ set_call_waiting(self.log, self.android_devices[0], enable=1)
+
+ # psim 5g nsa volte & esim 5g nsa volte & dds slot 0
+ @test_tracker_info(uuid="d1a50121-a245-4e51-a6aa-7836878339aa")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_callee_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_0(self):
+ """Call forwarding unconditional test on pSIM of the primary device.
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CFU on pSIM of the primary device.
+ 2. Let the 2nd device call the pSIM of the primary device. The
+ call should be forwarded to the 3rd device. Answer and then
+ hang up the call.
+ 3. Disable CFU on pSIM of the primary device.
+ 4. Let the 2nd device call the pSIM of the primary device. The
+ call should NOT be forwarded to the primary device. Answer
+ and then hang up the call.
+ 5. Disable and erase CFU on the primary device.
+ """
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ None,
+ 0,
+ callee_rat=["5g_volte", "5g_volte"],
+ call_forwarding_type="unconditional")
+
+ @test_tracker_info(uuid="c268fee2-6f09-48c2-98d8-97cc06de0e61")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_callee_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ """Call forwarding unconditional test on eSIM of the primary device.
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CFU on eSIM of the primary device.
+ 2. Let the 2nd device call the eSIM of the primary device. The
+ call should be forwarded to the 3rd device. Answer and then
+ hang up the call.
+ 3. Disable CFU on eSIM of the primary device.
+ 4. Let the 2nd device call the eSIM of the primary device. The
+ call should NOT be forwarded to the primary device. Answer
+ and then hang up the call.
+ 5. Disable and erase CFU on the primary device.
+ """
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ None,
+ 0,
+ callee_rat=["5g_volte", "5g_volte"],
+ call_forwarding_type="unconditional")
+
+ # psim 5g nsa volte & esim 5g nsa volte & dds slot 1
+ @test_tracker_info(uuid="df98b0d6-3643-4e01-b9c5-d41b40d95146")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_callee_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ """Call forwarding unconditional test on pSIM of the primary device.
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CFU on pSIM of the primary device.
+ 2. Let the 2nd device call the pSIM of the primary device. The
+ call should be forwarded to the 3rd device. Answer and then
+ hang up the call.
+ 3. Disable CFU on pSIM of the primary device.
+ 4. Let the 2nd device call the pSIM of the primary device. The
+ call should NOT be forwarded to the primary device. Answer
+ and then hang up the call.
+ 5. Disable and erase CFU on the primary device.
+ """
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ None,
+ 1,
+ callee_rat=["5g_volte", "5g_volte"],
+ call_forwarding_type="unconditional")
+
+ @test_tracker_info(uuid="99a61d4e-f0fa-4f65-b3bd-67d2a90cdfe2")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_callee_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_1(self):
+ """Call forwarding unconditional test on eSIM of the primary device.
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CFU on eSIM of the primary device.
+ 2. Let the 2nd device call the eSIM of the primary device. The
+ call should be forwarded to the 3rd device. Answer and then
+ hang up the call.
+ 3. Disable CFU on eSIM of the primary device.
+ 4. Let the 2nd device call the eSIM of the primary device. The
+ call should NOT be forwarded to the primary device. Answer
+ and then hang up the call.
+ 5. Disable and erase CFU on the primary device.
+ """
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ None,
+ 1,
+ callee_rat=["5g_volte", "5g_volte"],
+ call_forwarding_type="unconditional")
+
+ # psim 5g nsa volte & esim 4g volte & dds slot 0
+ @test_tracker_info(uuid="9fb2da2e-00f6-4d0f-a921-49786ffbb758")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_callee_psim_5g_nsa_volte_esim_4g_volte_dds_0(self):
+ """Call forwarding unconditional test on pSIM of the primary device.
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CFU on pSIM of the primary device.
+ 2. Let the 2nd device call the pSIM of the primary device. The
+ call should be forwarded to the 3rd device. Answer and then
+ hang up the call.
+ 3. Disable CFU on pSIM of the primary device.
+ 4. Let the 2nd device call the pSIM of the primary device. The
+ call should NOT be forwarded to the primary device. Answer
+ and then hang up the call.
+ 5. Disable and erase CFU on the primary device.
+ """
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ None,
+ 0,
+ callee_rat=["5g_volte", "volte"],
+ call_forwarding_type="unconditional")
+
+ @test_tracker_info(uuid="da42b577-30a6-417d-a545-629ccbfaebb2")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_callee_esim_4g_volte_psim_5g_nsa_volte_dds_0(self):
+ """Call forwarding unconditional test on eSIM of the primary device.
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CFU on eSIM of the primary device.
+ 2. Let the 2nd device call the eSIM of the primary device. The
+ call should be forwarded to the 3rd device. Answer and then
+ hang up the call.
+ 3. Disable CFU on eSIM of the primary device.
+ 4. Let the 2nd device call the eSIM of the primary device. The
+ call should NOT be forwarded to the primary device. Answer
+ and then hang up the call.
+ 5. Disable and erase CFU on the primary device.
+ """
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ None,
+ 0,
+ callee_rat=["5g_volte", "volte"],
+ call_forwarding_type="unconditional")
+
+ # psim 5g nsa volte & esim 4g volte & dds slot 1
+ @test_tracker_info(uuid="e9ab2c2f-8b2c-4f26-879d-b872947ee3a1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_callee_psim_5g_nsa_volte_esim_4g_volte_dds_1(self):
+ """Call forwarding unconditional test on pSIM of the primary device.
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CFU on pSIM of the primary device.
+ 2. Let the 2nd device call the pSIM of the primary device. The
+ call should be forwarded to the 3rd device. Answer and then
+ hang up the call.
+ 3. Disable CFU on pSIM of the primary device.
+ 4. Let the 2nd device call the pSIM of the primary device. The
+ call should NOT be forwarded to the primary device. Answer
+ and then hang up the call.
+ 5. Disable and erase CFU on the primary device.
+ """
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ None,
+ 1,
+ callee_rat=["5g_volte", "volte"],
+ call_forwarding_type="unconditional")
+
+ @test_tracker_info(uuid="080e6cf2-7bb1-4ce8-9f15-c082cbb0fd8c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_callee_esim_4g_volte_psim_5g_nsa_volte_dds_1(self):
+ """Call forwarding unconditional test on eSIM of the primary device.
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CFU on eSIM of the primary device.
+ 2. Let the 2nd device call the eSIM of the primary device. The
+ call should be forwarded to the 3rd device. Answer and then
+ hang up the call.
+ 3. Disable CFU on eSIM of the primary device.
+ 4. Let the 2nd device call the eSIM of the primary device. The
+ call should NOT be forwarded to the primary device. Answer
+ and then hang up the call.
+ 5. Disable and erase CFU on the primary device.
+ """
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ None,
+ 1,
+ callee_rat=["5g_volte", "volte"],
+ call_forwarding_type="unconditional")
+
+ # psim 4g volte & esim 5g nsa volte & dds slot 0
+ @test_tracker_info(uuid="0da6f8e9-dfea-408b-91d9-e10fb6dad086")
+ def test_msim_cfu_callee_psim_4g_volte_esim_5g_nsa_volte_dds_0(self):
+ """Call forwarding unconditional test on pSIM of the primary device.
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CFU on pSIM of the primary device.
+ 2. Let the 2nd device call the pSIM of the primary device. The
+ call should be forwarded to the 3rd device. Answer and then
+ hang up the call.
+ 3. Disable CFU on pSIM of the primary device.
+ 4. Let the 2nd device call the pSIM of the primary device. The
+ call should NOT be forwarded to the primary device. Answer
+ and then hang up the call.
+ 5. Disable and erase CFU on the primary device.
+ """
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ None,
+ 0,
+ callee_rat=["volte", "5g_volte"],
+ call_forwarding_type="unconditional")
+
+ @test_tracker_info(uuid="dadde63d-4a4d-4fe7-82bd-25ecff856900")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_callee_esim_5g_nsa_volte_psim_4g_volte_dds_0(self):
+ """Call forwarding unconditional test on eSIM of the primary device.
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CFU on eSIM of the primary device.
+ 2. Let the 2nd device call the eSIM of the primary device. The
+ call should be forwarded to the 3rd device. Answer and then
+ hang up the call.
+ 3. Disable CFU on eSIM of the primary device.
+ 4. Let the 2nd device call the eSIM of the primary device. The
+ call should NOT be forwarded to the primary device. Answer
+ and then hang up the call.
+ 5. Disable and erase CFU on the primary device.
+ """
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ None,
+ 0,
+ callee_rat=["volte", "5g_volte"],
+ call_forwarding_type="unconditional")
+
+ # psim 4g volte & esim 5g nsa volte & dds slot 1
+ @test_tracker_info(uuid="0e951ee2-4a38-4b97-8a79-f6b3c66bf4d5")
+ def test_msim_cfu_callee_psim_4g_volte_esim_5g_nsa_volte_dds_1(self):
+ """Call forwarding unconditional test on pSIM of the primary device.
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CFU on pSIM of the primary device.
+ 2. Let the 2nd device call the pSIM of the primary device. The
+ call should be forwarded to the 3rd device. Answer and then
+ hang up the call.
+ 3. Disable CFU on pSIM of the primary device.
+ 4. Let the 2nd device call the pSIM of the primary device. The
+ call should NOT be forwarded to the primary device. Answer
+ and then hang up the call.
+ 5. Disable and erase CFU on the primary device.
+ """
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ None,
+ 1,
+ callee_rat=["volte", "5g_volte"],
+ call_forwarding_type="unconditional")
+
+ @test_tracker_info(uuid="0f15a135-aa30-46fb-956a-99b5b1109783")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_callee_esim_5g_nsa_volte_psim_4g_volte_dds_1(self):
+ """Call forwarding unconditional test on eSIM of the primary device.
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CFU on eSIM of the primary device.
+ 2. Let the 2nd device call the eSIM of the primary device. The
+ call should be forwarded to the 3rd device. Answer and then
+ hang up the call.
+ 3. Disable CFU on eSIM of the primary device.
+ 4. Let the 2nd device call the eSIM of the primary device. The
+ call should NOT be forwarded to the primary device. Answer
+ and then hang up the call.
+ 5. Disable and erase CFU on the primary device.
+ """
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ None,
+ 1,
+ callee_rat=["volte", "5g_volte"],
+ call_forwarding_type="unconditional")
+
+ # psim 5g nsa volte & esim 5g nsa volte & dds slot 0
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="edfbc065-7a1d-4ac8-94fe-58106bd5f0a0")
+ def test_msim_conf_call_host_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_0(self):
+ """Conference call test on pSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CW on pSIM of the primary device.
+ 2. Let the pSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the pSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Merge 2 active calls.
+ """
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0, None, None, 0, host_rat=["5g_volte", "5g_volte"])
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="fbae3ef2-6ecc-48fb-b21c-155b2b4fd5d6")
+ def test_msim_conf_call_host_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ """Conference call test on eSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CW on eSIM of the primary device.
+ 2. Let the eSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the eSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Merge 2 active calls.
+ """
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1, None, None, 0, host_rat=["5g_volte", "5g_volte"])
+
+ # psim 5g nsa volte & esim 5g nsa volte & dds slot 1
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="404b7bf8-0706-4d27-a1ff-231ea6d5c34b")
+ def test_msim_conf_call_host_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ """Conference call test on pSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CW on pSIM of the primary device.
+ 2. Let the pSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the pSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Merge 2 active calls.
+ """
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0, None, None, 1, host_rat=["5g_volte", "5g_volte"])
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="cd74af3e-ced5-4275-990c-0561bfeee81d")
+ def test_msim_conf_call_host_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_1(self):
+ """Conference call test on eSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CW on eSIM of the primary device.
+ 2. Let the eSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the eSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Merge 2 active calls.
+ """
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1, None, None, 1, host_rat=["5g_volte", "5g_volte"])
+
+ # psim 5g nsa volte & esim 4g volte & dds slot 0
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="ff107828-0b09-47fb-ba85-b0e13b89970f")
+ def test_msim_conf_call_host_psim_5g_nsa_volte_esim_4g_volte_dds_0(self):
+ """Conference call test on pSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CW on pSIM of the primary device.
+ 2. Let the pSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the pSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Merge 2 active calls.
+ """
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0, None, None, 0, host_rat=["5g_volte", "volte"])
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="4a3152e2-8cc6-477d-9dd6-55f3ac35681e")
+ def test_msim_conf_call_host_esim_4g_volte_psim_5g_nsa_volte_dds_0(self):
+ """Conference call test on eSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CW on eSIM of the primary device.
+ 2. Let the eSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the eSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Merge 2 active calls.
+ """
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1, None, None, 0, host_rat=["5g_volte", "volte"])
+
+ # psim 5g nsa volte & esim 4g volte & dds slot 1
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="4aa8e15a-16b5-4173-b0d7-1a6cf00cf240")
+ def test_msim_conf_call_host_psim_5g_nsa_volte_esim_4g_volte_dds_1(self):
+ """Conference call test on pSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CW on pSIM of the primary device.
+ 2. Let the pSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the pSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Merge 2 active calls.
+ """
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0, None, None, 1, host_rat=["5g_volte", "volte"])
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="82d9ca6c-8c3d-4a54-ae85-c3d52aab8bc4")
+ def test_msim_conf_call_host_esim_4g_volte_psim_5g_nsa_volte_dds_1(self):
+ """Conference call test on eSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CW on eSIM of the primary device.
+ 2. Let the eSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the eSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Merge 2 active calls.
+ """
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1, None, None, 1, host_rat=["5g_volte", "volte"])
+
+ # psim 4g volte & esim 5g nsa volte & dds slot 0
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="d8dc0e1b-bfad-4040-ab44-91b15160dd86")
+ def test_msim_conf_call_host_psim_4g_volte_esim_5g_nsa_volte_dds_0(self):
+ """Conference call test on pSIM of the primary device
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CW on pSIM of the primary device.
+ 2. Let the pSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the pSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Merge 2 active calls.
+ """
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0, None, None, 0, host_rat=["volte", "5g_volte"])
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="8d8d1050-9e73-4ec9-a9dd-7f68ccd11483")
+ def test_msim_conf_call_host_esim_5g_nsa_volte_psim_4g_volte_dds_0(self):
+ """Conference call test on eSIM of the primary device
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CW on eSIM of the primary device.
+ 2. Let the eSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the eSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Merge 2 active calls.
+ """
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1, None, None, 0, host_rat=["volte", "5g_volte"])
+
+ # psim 4g volte & esim 5g nsa volte & dds slot 1
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="8f46e57c-c7a2-49e9-9e4c-1f83ab67cd5e")
+ def test_msim_conf_call_host_psim_4g_volte_esim_5g_nsa_volte_dds_1(self):
+ """Conference call test on pSIM of the primary device
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+
+ Test steps:
+ 1. Enable CW on pSIM of the primary device.
+ 2. Let the pSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the pSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Merge 2 active calls.
+ """
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0, None, None, 1, host_rat=["volte", "5g_volte"])
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="7975fc5b-4146-4370-9f1b-1ad1987a14f3")
+ def test_msim_conf_call_host_esim_5g_nsa_volte_psim_4g_volte_dds_1(self):
+ """Conference call test on eSIM of the primary device
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+
+ Test steps:
+ 1. Enable CW on eSIM of the primary device.
+ 2. Let the eSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the eSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Merge 2 active calls.
+ """
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1, None, None, 1, host_rat=["volte", "5g_volte"])
+
+ # psim 5g nsa volte & esim 5g nsa volte & dds slot 0
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="1050ee12-d1aa-47c9-ad3a-589ad6c6b695")
+ def test_msim_cw_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_0(self):
+ """Call waiting test on pSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CW on pSIM of the primary device.
+ 2. Let the pSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the pSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Hang up 2 calls from the 2nd and 3rd devices.
+ 6. Disable CW on pSIM of the primary device.
+ 7. Repeat step 2 & 3. In the step 3 the primary device should
+ not receive the incoming call.
+ """
+ result = True
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ None,
+ 0,
+ host_rat=["5g_volte", "5g_volte"],
+ merge=False, disable_cw=False):
+ result = False
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ None,
+ 0,
+ host_rat=["5g_volte", "5g_volte"],
+ merge=False,
+ disable_cw=True):
+ result = False
+ return result
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="74ae2673-fefb-459c-a415-366a12477956")
+ def test_msim_cw_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ """Call waiting test on eSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CW on eSIM of the primary device.
+ 2. Let the eSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the eSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Hang up 2 calls from the 2nd and 3rd devices.
+ 6. Disable CW on eSIM of the primary device.
+ 7. Repeat step 2 & 3. In the step 3 the primary device should
+ not receive the incoming call.
+ """
+ result = True
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ None,
+ 0,
+ host_rat=["5g_volte", "5g_volte"],
+ merge=False, disable_cw=False):
+ result = False
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ None,
+ 0,
+ host_rat=["5g_volte", "5g_volte"],
+ merge=False,
+ disable_cw=True):
+ result = False
+ return result
+
+ # psim 5g nsa volte & esim 5g nsa volte & dds slot 1
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="73b26c81-8080-4df0-a491-875e1290b5aa")
+ def test_msim_cw_psim_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ """Call waiting test on pSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+
+ Test steps:
+ 1. Enable CW on pSIM of the primary device.
+ 2. Let the pSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the pSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Hang up 2 calls from the 2nd and 3rd devices.
+ 6. Disable CW on pSIM of the primary device.
+ 7. Repeat step 2 & 3. In the step 3 the primary device should
+ not receive the incoming call.
+ """
+ result = True
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ None,
+ 1,
+ host_rat=["5g_volte", "5g_volte"],
+ merge=False, disable_cw=False):
+ result = False
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ None,
+ 1,
+ host_rat=["5g_volte", "5g_volte"],
+ merge=False,
+ disable_cw=True):
+ result = False
+ return result
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="32804d38-7def-4507-921d-f906d1cf9dfa")
+ def test_msim_cw_esim_5g_nsa_volte_psim_5g_nsa_volte_dds_1(self):
+ """Call waiting test on eSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+
+ Test steps:
+ 1. Enable CW on eSIM of the primary device.
+ 2. Let the eSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the eSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Hang up 2 calls from the 2nd and 3rd devices.
+ 6. Disable CW on eSIM of the primary device.
+ 7. Repeat step 2 & 3. In the step 3 the primary device should
+ not receive the incoming call.
+ """
+ result = True
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ None,
+ 1,
+ host_rat=["5g_volte", "5g_volte"],
+ merge=False, disable_cw=False):
+ result = False
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ None,
+ 1,
+ host_rat=["5g_volte", "5g_volte"],
+ merge=False,
+ disable_cw=True):
+ result = False
+ return result
+
+ # psim 5g nsa volte & esim 4g volte & dds slot 0
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="753a8651-8230-4714-aa5c-32ed7e7d7c04")
+ def test_msim_cw_psim_5g_nsa_volte_esim_4g_volte_dds_0(self):
+ """Call waiting test on pSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CW on pSIM of the primary device.
+ 2. Let the pSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the pSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Hang up 2 calls from the 2nd and 3rd devices.
+ 6. Disable CW on pSIM of the primary device.
+ 7. Repeat step 2 & 3. In the step 3 the primary device should
+ not receive the incoming call.
+ """
+ result = True
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ None,
+ 0,
+ host_rat=["5g_volte", "volte"],
+ merge=False, disable_cw=False):
+ result = False
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ None,
+ 0,
+ host_rat=["5g_volte", "volte"],
+ merge=False,
+ disable_cw=True):
+ result = False
+ return result
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="fc92c004-5862-4035-98b4-5ea3d3c2c5e9")
+ def test_msim_cw_esim_4g_volte_psim_5g_nsa_volte_dds_0(self):
+ """Call waiting test on eSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CW on eSIM of the primary device.
+ 2. Let the eSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the eSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Hang up 2 calls from the 2nd and 3rd devices.
+ 6. Disable CW on eSIM of the primary device.
+ 7. Repeat step 2 & 3. In the step 3 the primary device should
+ not receive the incoming call.
+ """
+ result = True
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ None,
+ 0,
+ host_rat=["5g_volte", "volte"],
+ merge=False, disable_cw=False):
+ result = False
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ None,
+ 0,
+ host_rat=["5g_volte", "volte"],
+ merge=False,
+ disable_cw=True):
+ result = False
+ return result
+
+ # psim 5g nsa volte & esim 4g volte & dds slot 1
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="753a8651-8230-4714-aa5c-32ed7e7d7c04")
+ def test_msim_cw_psim_5g_nsa_volte_esim_4g_volte_dds_1(self):
+ """Call waiting test on pSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CW on pSIM of the primary device.
+ 2. Let the pSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the pSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Hang up 2 calls from the 2nd and 3rd devices.
+ 6. Disable CW on pSIM of the primary device.
+ 7. Repeat step 2 & 3. In the step 3 the primary device should
+ not receive the incoming call.
+ """
+ result = True
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ None,
+ 1,
+ host_rat=["5g_volte", "volte"],
+ merge=False, disable_cw=False):
+ result = False
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ None,
+ 1,
+ host_rat=["5g_volte", "volte"],
+ merge=False,
+ disable_cw=True):
+ result = False
+ return result
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="fc92c004-5862-4035-98b4-5ea3d3c2c5e9")
+ def test_msim_cw_esim_4g_volte_psim_5g_nsa_volte_dds_1(self):
+ """Call waiting test on eSIM of the primary device
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CW on eSIM of the primary device.
+ 2. Let the eSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the eSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Hang up 2 calls from the 2nd and 3rd devices.
+ 6. Disable CW on eSIM of the primary device.
+ 7. Repeat step 2 & 3. In the step 3 the primary device should
+ not receive the incoming call.
+ """
+ result = True
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ None,
+ 1,
+ host_rat=["5g_volte", "volte"],
+ merge=False, disable_cw=False):
+ result = False
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ None,
+ 1,
+ host_rat=["5g_volte", "volte"],
+ merge=False,
+ disable_cw=True):
+ result = False
+ return result
+
+ # psim 4g volte & esim 5g nsa volte & dds slot 0
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="4c02fc60-b838-40a1-879f-675d8c4b91af")
+ def test_msim_cw_psim_4g_volte_esim_5g_nsa_volte_dds_0(self):
+ """Call waiting test on pSIM of the primary device
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CW on pSIM of the primary device.
+ 2. Let the pSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the pSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Hang up 2 calls from the 2nd and 3rd devices.
+ 6. Disable CW on pSIM of the primary device.
+ 7. Repeat step 2 & 3. In the step 3 the primary device should
+ not receive the incoming call.
+ """
+ result = True
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ None,
+ 0,
+ host_rat=["volte", "5g_volte"],
+ merge=False,
+ disable_cw=False):
+ result = False
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ None,
+ 0,
+ host_rat=["volte", "5g_volte"],
+ merge=False,
+ disable_cw=True):
+ result = False
+ return result
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="cbe58062-bd7f-48b5-aab1-84355a3fcf55")
+ def test_msim_cw_esim_5g_nsa_volte_psim_4g_volte_dds_0(self):
+ """Call waiting test on eSIM of the primary device
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Test steps:
+ 1. Enable CW on eSIM of the primary device.
+ 2. Let the eSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the eSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Hang up 2 calls from the 2nd and 3rd devices.
+ 6. Disable CW on eSIM of the primary device.
+ 7. Repeat step 2 & 3. In the step 3 the primary device should
+ not receive the incoming call.
+ """
+ result = True
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ None,
+ 0,
+ host_rat=["volte", "5g_volte"],
+ merge=False,
+ disable_cw=False):
+ result = False
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ None,
+ 0,
+ host_rat=["volte", "5g_volte"],
+ merge=False,
+ disable_cw=True):
+ result = False
+ return result
+
+ # psim 4g volte & esim 5g nsa volte & dds slot 1
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="80c7e356-9419-484f-9b34-65ca5544bc39")
+ def test_msim_cw_psim_4g_volte_esim_5g_nsa_volte_dds_1(self):
+ """Call waiting test on pSIM of the primary device
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CW on pSIM of the primary device.
+ 2. Let the pSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the pSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Hang up 2 calls from the 2nd and 3rd devices.
+ 6. Disable CW on pSIM of the primary device.
+ 7. Repeat step 2 & 3. In the step 3 the primary device should
+ not receive the incoming call.
+ """
+ result = True
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ None,
+ 1,
+ host_rat=["volte", "5g_volte"],
+ merge=False,
+ disable_cw=False):
+ result = False
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ None,
+ 1,
+ host_rat=["volte", "5g_volte"],
+ merge=False,
+ disable_cw=True):
+ result = False
+ return result
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="6cd6b062-d68a-4b1b-b6ca-92af72ebe3b9")
+ def test_msim_cw_esim_5g_nsa_volte_psim_4g_volte_dds_1(self):
+ """Call waiting test on eSIM of the primary device
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+
+ Test steps:
+ 1. Enable CW on eSIM of the primary device.
+ 2. Let the eSIM of primary device call the 2nd device. Keep the
+ call active.
+ 3. Let the 3rd device call the eSIM of the primary device. Keep
+ both calls active.
+ 4. Swap the call twice.
+ 5. Hang up 2 calls from the 2nd and 3rd devices.
+ 6. Disable CW on eSIM of the primary device.
+ 7. Repeat step 2 & 3. In the step 3 the primary device should
+ not receive the incoming call.
+ """
+ result = True
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ None,
+ 1,
+ host_rat=["volte", "5g_volte"],
+ merge=False,
+ disable_cw=False):
+ result = False
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ None,
+ 1,
+ host_rat=["volte", "5g_volte"],
+ merge=False,
+ disable_cw=True):
+ result = False
+ return result
\ No newline at end of file
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSVoiceTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSVoiceTest.py
new file mode 100644
index 0000000..3544b8d
--- /dev/null
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSVoiceTest.py
@@ -0,0 +1,2857 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - Google
+#
+# 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.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.tel.tel_dsds_utils import dsds_long_call_streaming_test
+from acts_contrib.test_utils.tel.tel_dsds_utils import dsds_voice_call_test
+from acts_contrib.test_utils.tel.tel_dsds_utils import enable_slot_after_voice_call_test
+from acts_contrib.test_utils.tel.tel_dsds_utils import enable_slot_after_data_call_test
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+
+
+class Nsa5gDSDSVoiceTest(TelephonyBaseTest):
+ def setup_class(self):
+ TelephonyBaseTest.setup_class(self)
+ self.tel_logger = TelephonyMetricLogger.for_test_case()
+
+ def teardown_test(self):
+ ensure_phones_idle(self.log, self.android_devices)
+
+ # psim 5g nsa volte & esim 5g nsa volte & dds slot 0
+ @test_tracker_info(uuid="8a8c3f42-f5d7-4299-8d84-64ac5377788f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_volte_esim_5g_nsa_volte_dds_0(self):
+ """A MO VoLTE call dialed at pSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 0,
+ mo_rat=["5g_volte", "5g_volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="b05b6aea-7c48-4412-b0b1-f57192fc786c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_volte_esim_5g_nsa_volte_dds_0(self):
+ """A MT VoLTE call received at pSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 0,
+ mt_rat=["5g_volte", "5g_volte"],
+ call_direction="mt")
+
+ @test_tracker_info(uuid="213d5e6f-97df-4c2a-9745-4e40a704853a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ """A MO VoLTE call dialed at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 0,
+ mo_rat=["5g_volte", "5g_volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="48a06a2f-b3d0-4b0e-85e5-2d439ee3147b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ """A MT VoLTE call received at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 0,
+ mt_rat=["5g_volte", "5g_volte"],
+ call_direction="mt")
+
+ # psim 5g nsa volte & esim 5g nsa volte & dds slot 1
+ @test_tracker_info(uuid="406bd5e5-b549-470d-b15a-20b4bb5ff3db")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ """A MO VoLTE call dialed at pSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 1,
+ mo_rat=["5g_volte", "5g_volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="a1e52cee-78ab-4d6e-859b-faf542b8056b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ """A MT VoLTE call received at pSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 1,
+ mt_rat=["5g_volte", "5g_volte"],
+ call_direction="mt")
+
+ @test_tracker_info(uuid="3b9d796c-b658-4bff-aae0-1243ce8c3d54")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_volte_psim_5g_nsa_volte_dds_1(self):
+ """A MO VoLTE call dialed at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 1,
+ mo_rat=["5g_volte", "5g_volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="e3edd065-72e1-4067-901c-1454706e9f43")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_volte_psim_5g_nsa_volte_dds_1(self):
+ """A MT VoLTE call received at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 1,
+ mt_rat=["5g_volte", "5g_volte"],
+ call_direction="mt")
+
+ # psim 5g nsa volte & esim 4g volte & dds slot 0
+ @test_tracker_info(uuid="2890827d-deb2-42ea-921d-3b45f7645d61")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_volte_esim_4g_volte_dds_0(self):
+ """A MO VoLTE call dialed at pSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 0,
+ mo_rat=["5g_volte", "volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="83d9b127-25da-4c19-a3a0-470a5ced020b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_volte_esim_4g_volte_dds_0(self):
+ """A MT VoLTE call received at pSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 0,
+ mt_rat=["5g_volte", "volte"],
+ call_direction="mt")
+
+ @test_tracker_info(uuid="14c29c79-d100-4f03-b3df-f2ae4a172cc5")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_4g_volte_psim_5g_nsa_volte_dds_0(self):
+ """A MO VoLTE call dialed at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 0,
+ mo_rat=["5g_volte", "volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="12a59cc1-8c1e-44a0-836b-0d842c0746a3")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_4g_volte_psim_5g_nsa_volte_dds_0(self):
+ """A MT VoLTE call received at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 0,
+ mt_rat=["5g_volte", "volte"],
+ call_direction="mt")
+
+ # psim 5g nsa volte & esim 4g volte & dds slot 1
+ @test_tracker_info(uuid="9dfa66cc-f464-4964-9e5a-07e01d3e263e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_volte_esim_4g_volte_dds_1(self):
+ """A MO VoLTE call dialed at pSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 1,
+ mo_rat=["5g_volte", "volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="97e9ecc0-e377-46a8-9b13-ecedcb98922b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_volte_esim_4g_volte_dds_1(self):
+ """A MT VoLTE call received at pSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 1,
+ mt_rat=["5g_volte", "volte"],
+ call_direction="mt")
+
+ @test_tracker_info(uuid="5814cd18-e33b-45c5-b129-bec7e3992d8e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_4g_volte_psim_5g_nsa_volte_dds_1(self):
+ """A MO VoLTE call dialed at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 1,
+ mo_rat=["5g_volte", "volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="457dd160-f7b1-4cfd-920f-1f5ab64f6d78")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_4g_volte_psim_5g_nsa_volte_dds_1(self):
+ """A MT VoLTE call received at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 1,
+ mt_rat=["5g_volte", "volte"],
+ call_direction="mt")
+
+ # psim 4g volte & esim 5g nsa volte & dds slot 0
+ @test_tracker_info(uuid="db5fca13-bcd8-420b-9953-256186efa290")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_4g_volte_esim_5g_nsa_volte_dds_0(self):
+ """A MO VoLTE call dialed at pSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 0,
+ mo_rat=["volte", "5g_volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="2fe76eda-20b2-46ab-a1f4-c2c2bc501f38")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_4g_volte_esim_5g_nsa_volte_dds_0(self):
+ """A MT VoLTE call received at pSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 0,
+ mt_rat=["volte", "5g_volte"],
+ call_direction="mt")
+
+ @test_tracker_info(uuid="90005074-e21f-47c3-9965-54b513214600")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_volte_psim_4g_volte_dds_0(self):
+ """A MO VoLTE call dialed at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 0,
+ mo_rat=["volte", "5g_volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="eaf94a45-66d0-41d0-8cb2-153fa3f751f9")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_volte_psim_4g_volte_dds_0(self):
+ """A MT VoLTE call received at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 0)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 0,
+ mt_rat=["volte", "5g_volte"],
+ call_direction="mt")
+
+ # psim 4g volte & esim 5g nsa volte & dds slot 1
+ @test_tracker_info(uuid="8ee47ad7-24b6-4cd3-9443-6ab677695eb7")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_4g_volte_esim_5g_nsa_volte_dds_1(self):
+ """A MO VoLTE call dialed at pSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 1,
+ mo_rat=["volte", "5g_volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="8795b95d-a138-45cd-b45c-41ad4021589a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_4g_volte_esim_5g_nsa_volte_dds_1(self):
+ """A MT VoLTE call received at pSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 1,
+ mt_rat=["volte", "5g_volte"],
+ call_direction="mt")
+
+ @test_tracker_info(uuid="33f2fa73-de7b-4b68-b9b8-aa08f6511e1a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_volte_psim_4g_volte_dds_1(self):
+ """A MO VoLTE call dialed at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 1,
+ mo_rat=["volte", "5g_volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="b1ae55f1-dfd4-4e50-a0e3-df3b3ae29c68")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_volte_psim_4g_volte_dds_1(self):
+ """A MT VoLTE call received at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 1,
+ mt_rat=["volte", "5g_volte"],
+ call_direction="mt")
+
+ @test_tracker_info(uuid="f94d5fd2-79ac-426a-9a0d-1ba72e070b19")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_volte_psim_5g_nsa_volte_disable_psim(self):
+ """Disable/enable pSIM with MO voice call
+ Test step:
+ 1. Set the RAT to 5G at both slots.
+ 2. Disable pSIM.
+ 3. Switch DDS to eSIM.
+ 4. Verify RAT at slot 1 (eSIM) and also internet connection.
+ 5. Make a MO voice call.
+ 6. Enable pSIM.
+ 7. Switch DDS to pSIM.
+ 8. Verify RAT at slot 0 (pSIM) and also internet connection.
+ """
+ return enable_slot_after_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 0,
+ mo_rat=["5g_volte", "5g_volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="3b58146a-72d2-4544-b50b-f685d10da20a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_volte_psim_5g_nsa_volte_disable_psim(self):
+ """Disable/enable pSIM with MT voice call
+ Test step:
+ 1. Set the RAT to 5G at both slots.
+ 2. Disable pSIM.
+ 3. Switch DDS to eSIM.
+ 4. Verify RAT at slot 1 (eSIM) and also internet connection.
+ 5. Make a MT voice call.
+ 6. Enable pSIM.
+ 7. Switch DDS to pSIM.
+ 8. Verify RAT at slot 0 (pSIM) and also internet connection.
+ """
+ return enable_slot_after_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 0,
+ mt_rat=["5g_volte", "5g_volte"],
+ call_direction="mt")
+
+ @test_tracker_info(uuid="6b7fde1b-d51a-49df-b7d4-bf5e3d091895")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_data_esim_5g_nsa_volte_psim_5g_nsa_volte_disable_psim(self):
+ """Disable/enable pSIM with data call
+ Test step:
+ 1. Set the RAT to 5G at both slots.
+ 2. Disable pSIM.
+ 3. Switch DDS to eSIM.
+ 4. Verify RAT at slot 1 (eSIM) and also internet connection.
+ 5. Make a data call by http download.
+ 6. Enable pSIM.
+ 7. Switch DDS to pSIM.
+ 8. Verify RAT at slot 0 (pSIM) and also internet connection.
+ """
+ return enable_slot_after_data_call_test(
+ self.log,
+ self.android_devices[0],
+ 0,
+ rat=["5g_volte", "5g_volte"])
+
+ @test_tracker_info(uuid="dc490360-66b6-4796-a649-73bb09ce0cc1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_volte_esim_5g_nsa_volte_disable_esim(self):
+ """Disable/enable eSIM with MO voice call
+ Test step:
+ 1. Set the RAT to 5G at both slots.
+ 2. Disable eSIM.
+ 3. Switch DDS to pSIM.
+ 4. Verify RAT at slot 0 (pSIM) and also internet connection.
+ 5. Make a MO voice call.
+ 6. Enable eSIM.
+ 7. Switch DDS to eSIM.
+ 8. Verify RAT at slot 1 (eSIM) and also internet connection.
+ """
+ return enable_slot_after_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 1,
+ mo_rat=["5g_volte", "5g_volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="63f57c95-75be-4a51-83c6-609356bb301b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_volte_esim_5g_nsa_volte_disable_esim(self):
+ """Disable/enable eSIM with MT voice call
+ Test step:
+ 1. Set the RAT to 5G at both slots.
+ 2. Disable eSIM.
+ 3. Switch DDS to pSIM.
+ 4. Verify RAT at slot 0 (pSIM) and also internet connection.
+ 5. Make a MT voice call.
+ 6. Enable eSIM.
+ 7. Switch DDS to eSIM.
+ 8. Verify RAT at slot 1 (eSIM) and also internet connection.
+ """
+ return enable_slot_after_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 1,
+ mt_rat=["5g_volte", "5g_volte"],
+ call_direction="mt")
+
+ @test_tracker_info(uuid="7ad9e84a-dfa0-44e2-adde-390ae521b50b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_data_psim_5g_nsa_volte_esim_5g_nsa_volte_disable_esim(self):
+ """Disable/enable eSIM with data call
+ Test step:
+ 1. Set the RAT to 5G at both slots.
+ 2. Disable eSIM.
+ 3. Switch DDS to pSIM.
+ 4. Verify RAT at slot 0 (pSIM) and also internet connection.
+ 5. Make a data call by http download.
+ 6. Enable eSIM.
+ 7. Switch DDS to eSIM.
+ 8. Verify RAT at slot 1 (eSIM) and also internet connection.
+ """
+ return enable_slot_after_data_call_test(
+ self.log,
+ self.android_devices[0],
+ 1,
+ rat=["5g_volte", "5g_volte"])
+
+ @test_tracker_info(uuid="b1b02578-6e75-4a96-b3f3-c724fafbae2a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_volte_psim_4g_volte_disable_psim(self):
+ """Disable/enable pSIM with MO voice call
+ Test step:
+ 1. Set the RAT to LTE at slot 0 and 5G at slot 1.
+ 2. Disable pSIM.
+ 3. Switch DDS to eSIM.
+ 4. Verify RAT at slot 1 (eSIM) and also internet connection.
+ 5. Make a MO voice call.
+ 6. Enable pSIM.
+ 7. Switch DDS to pSIM.
+ 8. Verify RAT at slot 0 (pSIM) and also internet connection.
+ """
+ return enable_slot_after_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 0,
+ mo_rat=["volte", "5g_volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="15bb2fdd-ec38-47dc-a2f0-3251c8d19e3c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_volte_psim_4g_volte_disable_psim(self):
+ """Disable/enable pSIM with MT voice call
+ Test step:
+ 1. Set the RAT to LTE at slot 0 and 5G at slot 1.
+ 2. Disable pSIM.
+ 3. Switch DDS to eSIM.
+ 4. Verify RAT at slot 1 (eSIM) and also internet connection.
+ 5. Make a MT voice call.
+ 6. Enable pSIM.
+ 7. Switch DDS to pSIM.
+ 8. Verify RAT at slot 0 (pSIM) and also internet connection.
+ """
+ return enable_slot_after_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 0,
+ mt_rat=["volte", "5g_volte"],
+ call_direction="mt")
+
+ @test_tracker_info(uuid="37d5e72b-723f-4a26-87e9-cf54726476a6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_data_esim_5g_nsa_volte_psim_4g_volte_disable_psim(self):
+ """Disable/enable pSIM with data call
+ Test step:
+ 1. Set the RAT to LTE at slot 0 and 5G at slot 1.
+ 2. Disable pSIM.
+ 3. Switch DDS to eSIM.
+ 4. Verify RAT at slot 1 (eSIM) and also internet connection.
+ 5. Make a data call by http download.
+ 6. Enable pSIM.
+ 7. Switch DDS to pSIM.
+ 8. Verify RAT at slot 0 (pSIM) and also internet connection.
+ """
+ return enable_slot_after_data_call_test(
+ self.log,
+ self.android_devices[0],
+ 0,
+ rat=["volte", "5g_volte"])
+
+ @test_tracker_info(uuid="bc0dea98-cfe7-4cdd-8dd9-84eda4212fd4")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_4g_volte_esim_5g_nsa_volte_disable_esim(self):
+ """Disable/enable eSIM with MO voice call
+ Test step:
+ 1. Set the RAT to LTE at slot 0 and 5G at slot 1.
+ 2. Disable eSIM.
+ 3. Switch DDS to pSIM.
+ 4. Verify RAT at slot 0 (pSIM) and also internet connection.
+ 5. Make a MO voice call.
+ 6. Enable eSIM.
+ 7. Switch DDS to eSIM.
+ 8. Verify RAT at slot 1 (eSIM) and also internet connection.
+ """
+ return enable_slot_after_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 1,
+ mo_rat=["volte", "5g_volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="cfb8b670-6049-46fd-88ff-b9565ab2b582")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_4g_volte_esim_5g_nsa_volte_disable_esim(self):
+ """Disable/enable eSIM with MT voice call
+ Test step:
+ 1. Set the RAT to LTE at slot 0 and 5G at slot 1.
+ 2. Disable eSIM.
+ 3. Switch DDS to pSIM.
+ 4. Verify RAT at slot 0 (pSIM) and also internet connection.
+ 5. Make a MT voice call.
+ 6. Enable eSIM.
+ 7. Switch DDS to eSIM.
+ 8. Verify RAT at slot 1 (eSIM) and also internet connection.
+ """
+ return enable_slot_after_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 1,
+ mt_rat=["volte", "5g_volte"],
+ call_direction="mt")
+
+ @test_tracker_info(uuid="e2a18907-d9a4-491b-82c4-11ca86fc7129")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_data_psim_4g_volte_esim_5g_nsa_volte_disable_esim(self):
+ """Disable/enable eSIM with data call
+ Test step:
+ 1. Set the RAT to LTE at slot 0 and 5G at slot 1.
+ 2. Disable eSIM.
+ 3. Switch DDS to pSIM.
+ 4. Verify RAT at slot 0 (pSIM) and also internet connection.
+ 5. Make a data call by http download.
+ 6. Enable eSIM.
+ 7. Switch DDS to eSIM.
+ 8. Verify RAT at slot 1 (eSIM) and also internet connection.
+ """
+ return enable_slot_after_data_call_test(
+ self.log,
+ self.android_devices[0],
+ 1,
+ rat=["volte", "5g_volte"])
+
+ @test_tracker_info(uuid="13220595-9774-4f62-b1fb-3b6b98b51df3")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_4g_volte_psim_5g_nsa_volte_disable_psim(self):
+ """Disable/enable pSIM with MO voice call
+ Test step:
+ 1. Set the RAT to 5G at slot 0 and LTE at slot 1.
+ 2. Disable pSIM.
+ 3. Switch DDS to eSIM.
+ 4. Verify RAT at slot 1 (eSIM) and also internet connection.
+ 5. Make a MO voice call.
+ 6. Enable pSIM.
+ 7. Switch DDS to pSIM.
+ 8. Verify RAT at slot 0 (pSIM) and also internet connection.
+ """
+ return enable_slot_after_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 0,
+ mo_rat=["5g_volte", "volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="57e3e643-26a9-4e32-ac55-a0f7e4a72148")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_4g_volte_psim_5g_nsa_volte_disable_psim(self):
+ """Disable/enable pSIM with MT voice call
+ Test step:
+ 1. Set the RAT to 5G at slot 0 and LTE at slot 1.
+ 2. Disable pSIM.
+ 3. Switch DDS to eSIM.
+ 4. Verify RAT at slot 1 (eSIM) and also internet connection.
+ 5. Make a MT voice call.
+ 6. Enable pSIM.
+ 7. Switch DDS to pSIM.
+ 8. Verify RAT at slot 0 (pSIM) and also internet connection.
+ """
+ return enable_slot_after_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 0,
+ mt_rat=["5g_volte", "volte"],
+ call_direction="mt")
+
+ @test_tracker_info(uuid="3d809e0d-e75e-4ccd-af38-80d465d14eb7")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_data_esim_4g_volte_psim_5g_nsa_volte_disable_psim(self):
+ """Disable/enable pSIM with data call
+ Test step:
+ 1. Set the RAT to 5G at slot 0 and LTE at slot 1.
+ 2. Disable pSIM.
+ 3. Switch DDS to eSIM.
+ 4. Verify RAT at slot 1 (eSIM) and also internet connection.
+ 5. Make a data call by http download.
+ 6. Enable pSIM.
+ 7. Switch DDS to pSIM.
+ 8. Verify RAT at slot 0 (pSIM) and also internet connection.
+ """
+ return enable_slot_after_data_call_test(
+ self.log,
+ self.android_devices[0],
+ 0,
+ rat=["5g_volte", "volte"])
+
+ @test_tracker_info(uuid="c54ab348-367f-43c9-9aae-fa2c3d3badec")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_volte_esim_4g_volte_disable_esim(self):
+ """Disable/enable eSIM with MO voice call
+ Test step:
+ 1. Set the RAT to 5G at slot 0 and LTE at slot 1.
+ 2. Disable eSIM.
+ 3. Switch DDS to pSIM.
+ 4. Verify RAT at slot 0 (pSIM) and also internet connection.
+ 5. Make a MO voice call.
+ 6. Enable eSIM.
+ 7. Switch DDS to eSIM.
+ 8. Verify RAT at slot 1 (eSIM) and also internet connection.
+ """
+ return enable_slot_after_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 1,
+ mo_rat=["5g_volte", "volte"],
+ call_direction="mo")
+
+ @test_tracker_info(uuid="db8e5cdc-c34f-48d4-8ebe-2a71e03c159f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_volte_esim_4g_volte_disable_esim(self):
+ """Disable/enable eSIM with MT voice call
+ Test step:
+ 1. Set the RAT to 5G at slot 0 and LTE at slot 1.
+ 2. Disable eSIM.
+ 3. Switch DDS to pSIM.
+ 4. Verify RAT at slot 0 (pSIM) and also internet connection.
+ 5. Make a MT voice call.
+ 6. Enable eSIM.
+ 7. Switch DDS to eSIM.
+ 8. Verify RAT at slot 1 (eSIM) and also internet connection.
+ """
+ return enable_slot_after_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 1,
+ mt_rat=["5g_volte", "volte"],
+ call_direction="mt")
+
+ @test_tracker_info(uuid="a271d5f2-4449-4961-8417-14943fa96144")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_data_psim_5g_nsa_volte_esim_4g_volte_disable_esim(self):
+ """Disable/enable eSIM with data call
+ Test step:
+ 1. Set the RAT to 5G at slot 0 and LTE at slot 1.
+ 2. Disable eSIM.
+ 3. Switch DDS to pSIM.
+ 4. Verify RAT at slot 0 (pSIM) and also internet connection.
+ 5. Make a data call by http download.
+ 6. Enable eSIM.
+ 7. Switch DDS to eSIM.
+ 8. Verify RAT at slot 1 (eSIM) and also internet connection.
+ """
+ return enable_slot_after_data_call_test(
+ self.log,
+ self.android_devices[0],
+ 1,
+ rat=["5g_volte", "volte"])
+
+ @test_tracker_info(uuid="f86faed8-5259-4e5d-9e49-40618ad41670")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_wfc_wifi_preferred_esim_5g_nsa_volte_dds_0(self):
+ """ A MO vowifi call at pSIM, where
+ - pSIM 5G WFC in Wi-Fi preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 0,
+ mo_rat=["5g_wfc", "5g_volte"],
+ call_direction="mo",
+ wfc_mode = [WFC_MODE_WIFI_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="1e13a8be-7ddd-4177-89cb-720d305d766e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_wfc_wifi_preferred_esim_5g_nsa_volte_dds_0(self):
+ """ A MT vowifi call at pSIM, where
+ - pSIM 5G WFC in Wi-Fi preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 0,
+ mt_rat=["5g_wfc", "5g_volte"],
+ call_direction="mt",
+ wfc_mode = [WFC_MODE_WIFI_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="d32696a1-6e6d-48ca-8612-06e24645cfc6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_wfc_wifi_preferred_psim_5g_nsa_volte_dds_0(self):
+ """ A MO vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G WFC in Wi-Fi preferred mode
+ - DDS at pSIM (slot 0)
+
+ Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 0,
+ mo_rat=["5g_volte", "5g_wfc"],
+ call_direction="mo",
+ wfc_mode = [None, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="9ed35291-ae87-469a-a12f-8df2c17daa6e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_wfc_wifi_preferred_psim_5g_nsa_volte_dds_0(self):
+ """ A MT vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G WFC in Wi-Fi preferred mode
+ - DDS at pSIM (slot 0)
+
+ Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 0,
+ mt_rat=["5g_volte", "5g_wfc"],
+ call_direction="mt",
+ wfc_mode = [None, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="a44352d0-8ded-4e42-bd77-59c9f5801954")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_wfc_wifi_preferred_esim_5g_nsa_volte_dds_1(self):
+ """ A MO vowifi call at pSIM, where
+ - pSIM 5G WFC in Wi-Fi preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+
+ Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 1,
+ mo_rat=["5g_wfc", "5g_volte"],
+ call_direction="mo",
+ wfc_mode = [WFC_MODE_WIFI_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="6e99a297-6deb-4674-90e1-1f703971501a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_wfc_wifi_preferred_esim_5g_nsa_volte_dds_1(self):
+ """ A MT vowifi call at pSIM, where
+ - pSIM 5G WFC in Wi-Fi preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+
+ Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 1,
+ mt_rat=["5g_wfc", "5g_volte"],
+ call_direction="mt",
+ wfc_mode = [WFC_MODE_WIFI_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="119f71a5-9d5d-4c66-b958-684672a95a87")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_wfc_wifi_preferred_psim_5g_nsa_volte_dds_1(self):
+ """ A MO vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G WFC in Wi-Fi preferred mode
+ - DDS at eSIM (slot 1)
+
+ Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 1,
+ mo_rat=["5g_volte", "5g_wfc"],
+ call_direction="mo",
+ wfc_mode = [None, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="55e651d2-4112-4fe9-a70d-f448287b078b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_wfc_wifi_preferred_psim_5g_nsa_volte_dds_1(self):
+ """ A MT vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G WFC in Wi-Fi preferred mode
+ - DDS at eSIM (slot 1)
+
+ Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 1,
+ mt_rat=["5g_volte", "5g_wfc"],
+ call_direction="mt",
+ wfc_mode = [None, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="10ce825e-8ed8-4bc8-a70f-e0822d391066")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_4g_wfc_wifi_preferred_esim_5g_nsa_volte_dds_0(self):
+ """ A MO vowifi call at pSIM, where
+ - pSIM 4G WFC in Wi-Fi preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 0,
+ mo_rat=["wfc", "5g_volte"],
+ call_direction="mo",
+ wfc_mode = [WFC_MODE_WIFI_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="39cb207c-10e5-4f6a-8ee4-0f26634070cb")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_4g_wfc_wifi_preferred_esim_5g_nsa_volte_dds_0(self):
+ """ A MT vowifi call at pSIM, where
+ - pSIM 4G WFC in Wi-Fi preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 0,
+ mt_rat=["wfc", "5g_volte"],
+ call_direction="mt",
+ wfc_mode = [WFC_MODE_WIFI_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="a2245d31-c3ca-42bf-a6ca-72f3d3dc32e9")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_wfc_wifi_preferred_psim_4g_volte_dds_0(self):
+ """ A MO vowifi call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G WFC in Wi-Fi preferred mode
+ - DDS at pSIM (slot 0)
+
+ Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 0,
+ mo_rat=["volte", "5g_wfc"],
+ call_direction="mo",
+ wfc_mode = [None, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="2d683601-b604-4dba-b5b8-8aec86d70f95")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_wfc_wifi_preferred_psim_4g_volte_dds_0(self):
+ """ A MT vowifi call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G WFC in Wi-Fi preferred mode
+ - DDS at pSIM (slot 0)
+
+ Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 0,
+ mt_rat=["volte", "5g_wfc"],
+ call_direction="mt",
+ wfc_mode = [None, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="7c79782e-e273-43a4-9176-48a7b5a8cb85")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_4g_wfc_wifi_preferred_esim_5g_nsa_volte_dds_1(self):
+ """ A MO vowifi call at pSIM, where
+ - pSIM 4G WFC in Wi-Fi preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+
+ Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 1,
+ mo_rat=["wfc", "5g_volte"],
+ call_direction="mo",
+ wfc_mode = [WFC_MODE_WIFI_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="1b9c6b37-2345-46af-a6eb-48ebd962c953")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_4g_wfc_wifi_preferred_esim_5g_nsa_volte_dds_1(self):
+ """ A MT vowifi call at pSIM, where
+ - pSIM 4G WFC in Wi-Fi preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+
+ Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 1,
+ mt_rat=["wfc", "5g_volte"],
+ call_direction="mt",
+ wfc_mode = [WFC_MODE_WIFI_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="ce37ebda-f83b-4482-9214-74e82e04ae7f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_wfc_wifi_preferred_psim_4g_volte_dds_1(self):
+ """ A MO vowifi call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G WFC in Wi-Fi preferred mode
+ - DDS at eSIM (slot 1)
+
+ Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 1,
+ mo_rat=["volte", "5g_wfc"],
+ call_direction="mo",
+ wfc_mode = [None, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="3ba071ba-bf6f-4c27-ae82-557dabb60291")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_wfc_wifi_preferred_psim_4g_volte_dds_1(self):
+ """ A MT vowifi call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G WFC in Wi-Fi preferred mode
+ - DDS at eSIM (slot 1)
+
+ Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 1,
+ mt_rat=["volte", "5g_wfc"],
+ call_direction="mt",
+ wfc_mode = [None, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="1385939f-272e-4ba7-ba5d-de1bff60ad01")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_wfc_wifi_preferred_esim_4g_volte_dds_0(self):
+ """ A MO vowifi call at pSIM, where
+ - pSIM 5G WFC in Wi-Fi preferred mode
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+
+ Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 0,
+ mo_rat=["5g_wfc", "volte"],
+ call_direction="mo",
+ wfc_mode = [WFC_MODE_WIFI_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="79d24164-bbcc-49c6-a538-99b39b65749b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_wfc_wifi_preferred_esim_4g_volte_dds_0(self):
+ """ A MT vowifi call at pSIM, where
+ - pSIM 5G WFC in Wi-Fi preferred mode
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+
+ Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 0,
+ mt_rat=["5g_wfc", "volte"],
+ call_direction="mt",
+ wfc_mode = [WFC_MODE_WIFI_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="837186d2-fe35-4d4a-900d-0bc5b71829b7")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_4g_wfc_wifi_preferred_psim_5g_nsa_volte_dds_0(self):
+ """ A MO vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G WFC in Wi-Fi preferred mode
+ - DDS at pSIM (slot 0)
+
+ Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 0,
+ mo_rat=["5g_volte", "wfc"],
+ call_direction="mo",
+ wfc_mode = [None, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="ace4d07a-07ba-4868-bfa1-c82a81bce4c9")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_4g_wfc_wifi_preferred_psim_5g_nsa_volte_dds_0(self):
+ """ A MT vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G WFC in Wi-Fi preferred mode
+ - DDS at pSIM (slot 0)
+
+ Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 0,
+ mt_rat=["5g_volte", "wfc"],
+ call_direction="mt",
+ wfc_mode = [None, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="17306fd2-842e-47d9-bd83-e5a34fce1d5a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_wfc_wifi_preferred_esim_4g_volte_dds_1(self):
+ """ A MO vowifi call at pSIM, where
+ - pSIM 5G WFC in Wi-Fi preferred mode
+ - eSIM 4G VoLTE
+ - DDS at eSIM (slot 1)
+
+ Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 1,
+ mo_rat=["5g_wfc", "volte"],
+ call_direction="mo",
+ wfc_mode = [WFC_MODE_WIFI_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="352b0f73-f89a-45cf-9810-147e8a1b1522")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_wfc_wifi_preferred_esim_4g_volte_dds_1(self):
+ """ A MT vowifi call at pSIM, where
+ - pSIM 5G WFC in Wi-Fi preferred mode
+ - eSIM 4G VoLTE
+ - DDS at eSIM (slot 1)
+
+ Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 1,
+ mt_rat=["5g_wfc", "volte"],
+ call_direction="mt",
+ wfc_mode = [WFC_MODE_WIFI_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="4a574fee-dc59-45a6-99a6-18098053adf3")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_4g_wfc_wifi_preferred_psim_5g_nsa_volte_dds_1(self):
+ """ A MO vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G WFC in Wi-Fi preferred mode
+ - DDS at eSIM (slot 1)
+
+ Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 1,
+ mo_rat=["5g_volte", "wfc"],
+ call_direction="mo",
+ wfc_mode = [None, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="c70a2aa8-5567-4f74-9a2c-a24214d6af74")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_4g_wfc_wifi_preferred_psim_5g_nsa_volte_dds_1(self):
+ """ A MT vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G WFC in Wi-Fi preferred mode
+ - DDS at eSIM (slot 1)
+
+ Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 1,
+ mt_rat=["5g_volte", "wfc"],
+ call_direction="mt",
+ wfc_mode = [None, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True)
+
+ @test_tracker_info(uuid="1f5f9721-0dbb-443d-b54f-2e4acdc2e1a6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_wfc_cellular_preferred_esim_5g_nsa_volte_dds_0(self):
+ """ A MO vowifi call at pSIM, where
+ - pSIM 5G WFC in cellular preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 0,
+ mo_rat=["5g_wfc", "5g_volte"],
+ call_direction="mo",
+ is_airplane_mode=True,
+ wfc_mode = [WFC_MODE_CELLULAR_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="00723b82-3fa5-4263-b56f-a27ba76f24bd")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_wfc_cellular_preferred_esim_5g_nsa_volte_dds_0(self):
+ """ A MT vowifi call at pSIM, where
+ - pSIM 5G WFC in cellular preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 0,
+ mt_rat=["5g_wfc", "5g_volte"],
+ call_direction="mt",
+ is_airplane_mode=True,
+ wfc_mode = [WFC_MODE_CELLULAR_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="5d024b1c-e345-45e8-9759-9f8729799a05")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_wfc_cellular_preferred_psim_5g_nsa_volte_dds_0(self):
+ """ A MO vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G WFC in cellular preferred mode
+ - DDS at pSIM (slot 0)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 0,
+ mo_rat=["5g_volte", "5g_wfc"],
+ call_direction="mo",
+ is_airplane_mode=True,
+ wfc_mode = [None, WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="9627755c-3dea-4296-8140-eac0037c4f17")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_wfc_cellular_preferred_psim_5g_nsa_volte_dds_0(self):
+ """ A MT vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G WFC in cellular preferred mode
+ - DDS at pSIM (slot 0)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 0,
+ mt_rat=["5g_volte", "5g_wfc"],
+ call_direction="mt",
+ is_airplane_mode=True,
+ wfc_mode = [None, WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="aeddb446-8ec1-4692-9b6c-417aa89205eb")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_wfc_cellular_preferred_esim_5g_nsa_volte_dds_1(self):
+ """ A MO vowifi call at pSIM, where
+ - pSIM 5G WFC in cellular preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 1,
+ mo_rat=["5g_wfc", "5g_volte"],
+ call_direction="mo",
+ is_airplane_mode=True,
+ wfc_mode = [WFC_MODE_CELLULAR_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="4e56a128-0706-4f48-a031-93c77faa5e5a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_wfc_cellular_preferred_esim_5g_nsa_volte_dds_1(self):
+ """ A MT vowifi call at pSIM, where
+ - pSIM 5G WFC in cellular preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 1,
+ mt_rat=["5g_wfc", "5g_volte"],
+ call_direction="mt",
+ is_airplane_mode=True,
+ wfc_mode = [WFC_MODE_CELLULAR_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="8adbe013-4f93-4778-8f82-f7db3be8c318")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_wfc_cellular_preferred_psim_5g_nsa_volte_dds_1(self):
+ """ A MO vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G WFC in cellular preferred mode
+ - DDS at eSIM (slot 1)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 1,
+ mo_rat=["5g_volte", "5g_wfc"],
+ call_direction="mo",
+ is_airplane_mode=True,
+ wfc_mode = [None, WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="75fe4f90-8945-4886-92ad-29d0d536163d")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_wfc_cellular_preferred_psim_5g_nsa_volte_dds_1(self):
+ """ A MT vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G WFC in cellular preferred mode
+ - DDS at eSIM (slot 1)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 1,
+ mt_rat=["5g_volte", "5g_wfc"],
+ call_direction="mt",
+ is_airplane_mode=True,
+ wfc_mode = [None, WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="25716018-d4cc-4b62-ac00-77d34b3920e1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_4g_wfc_cellular_preferred_esim_5g_nsa_volte_dds_0(self):
+ """ A MO vowifi call at pSIM, where
+ - pSIM 4G WFC in cellular preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 0,
+ mo_rat=["wfc", "5g_volte"],
+ call_direction="mo",
+ is_airplane_mode=True,
+ wfc_mode = [WFC_MODE_CELLULAR_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="ae7a19bb-f257-4853-83ff-25dd70696d76")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_4g_wfc_cellular_preferred_esim_5g_nsa_volte_dds_0(self):
+ """ A MT vowifi call at pSIM, where
+ - pSIM 4G WFC in cellular preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 0,
+ mt_rat=["wfc", "5g_volte"],
+ call_direction="mt",
+ is_airplane_mode=True,
+ wfc_mode = [WFC_MODE_CELLULAR_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="c498a7fc-8c5d-4b5d-bd9e-47bd77032765")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_wfc_cellular_preferred_psim_4g_volte_dds_0(self):
+ """ A MO vowifi call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G WFC in cellular preferred mode
+ - DDS at pSIM (slot 0)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 0,
+ mo_rat=["volte", "5g_wfc"],
+ call_direction="mo",
+ is_airplane_mode=True,
+ wfc_mode = [None, WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="ce7b23af-41f1-4977-a140-6e1a456487dc")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_wfc_cellular_preferred_psim_4g_volte_dds_0(self):
+ """ A MT vowifi call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G WFC in cellular preferred mode
+ - DDS at pSIM (slot 0)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 0,
+ mt_rat=["volte", "5g_wfc"],
+ call_direction="mt",
+ is_airplane_mode=True,
+ wfc_mode = [None, WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="808fab1e-1fe7-406a-b479-8e9e6a5c2ef5")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_4g_wfc_cellular_preferred_esim_5g_nsa_volte_dds_1(self):
+ """ A MO vowifi call at pSIM, where
+ - pSIM 4G WFC in cellular preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 1,
+ mo_rat=["wfc", "5g_volte"],
+ call_direction="mo",
+ is_airplane_mode=True,
+ wfc_mode = [WFC_MODE_CELLULAR_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="4b0f73a8-a508-4e77-aca2-0155b54b4e2c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_4g_wfc_cellular_preferred_esim_5g_nsa_volte_dds_1(self):
+ """ A MT vowifi call at pSIM, where
+ - pSIM 4G WFC in cellular preferred mode
+ - eSIM 5G NSA VoLTE
+ - DDS at eSIM (slot 1)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 1,
+ mt_rat=["wfc", "5g_volte"],
+ call_direction="mt",
+ is_airplane_mode=True,
+ wfc_mode = [WFC_MODE_CELLULAR_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="4a73fdb3-abf3-4094-9317-74b758991c0a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_5g_nsa_wfc_cellular_preferred_psim_4g_volte_dds_1(self):
+ """ A MO vowifi call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G WFC in cellular preferred mode
+ - DDS at eSIM (slot 1)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 1,
+ mo_rat=["volte", "5g_wfc"],
+ call_direction="mo",
+ is_airplane_mode=True,
+ wfc_mode = [None, WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="5247d0dc-2d60-4760-8c27-a9b358992849")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_5g_nsa_wfc_cellular_preferred_psim_4g_volte_dds_1(self):
+ """ A MT vowifi call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G WFC in cellular preferred mode
+ - DDS at eSIM (slot 1)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 1,
+ mt_rat=["volte", "5g_wfc"],
+ call_direction="mt",
+ is_airplane_mode=True,
+ wfc_mode = [None, WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="df037a28-c130-4d00-ba2e-28723af26128")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_wfc_cellular_preferred_esim_4g_volte_dds_0(self):
+ """ A MO vowifi call at pSIM, where
+ - pSIM 5G WFC in cellular preferred mode
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 0,
+ mo_rat=["5g_wfc", "volte"],
+ call_direction="mo",
+ is_airplane_mode=True,
+ wfc_mode = [WFC_MODE_CELLULAR_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="900a7a74-064b-43df-b40a-8257ea9a1598")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_wfc_cellular_preferred_esim_4g_volte_dds_0(self):
+ """ A MT vowifi call at pSIM, where
+ - pSIM 5G WFC in cellular preferred mode
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 0,
+ mt_rat=["5g_wfc", "volte"],
+ call_direction="mt",
+ is_airplane_mode=True,
+ wfc_mode = [WFC_MODE_CELLULAR_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="08057239-a1de-42e5-8ff2-560d6a7a7e35")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_4g_wfc_cellular_preferred_psim_5g_nsa_volte_dds_0(self):
+ """ A MO vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G WFC in cellular preferred mode
+ - DDS at pSIM (slot 0)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 0,
+ mo_rat=["5g_volte", "wfc"],
+ call_direction="mo",
+ is_airplane_mode=True,
+ wfc_mode = [None, WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="edd15dd4-4abe-4de0-905e-6dd2aebf2697")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_4g_wfc_cellular_preferred_psim_5g_nsa_volte_dds_0(self):
+ """ A MT vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G WFC in cellular preferred mode
+ - DDS at pSIM (slot 0)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 0,
+ mt_rat=["5g_volte", "wfc"],
+ call_direction="mt",
+ is_airplane_mode=True,
+ wfc_mode = [None, WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="c230b98b-fbe2-4fc5-b0a0-cc91c5613ade")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mo_5g_nsa_wfc_cellular_preferred_esim_4g_volte_dds_1(self):
+ """ A MO vowifi call at pSIM, where
+ - pSIM 5G WFC in cellular preferred mode
+ - eSIM 4G VoLTE
+ - DDS at eSIM (slot 1)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ 1,
+ mo_rat=["5g_wfc", "volte"],
+ call_direction="mo",
+ is_airplane_mode=True,
+ wfc_mode = [WFC_MODE_CELLULAR_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="1e0eb29c-4850-4f42-b83f-d831305eeaa7")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_psim_mt_5g_nsa_wfc_cellular_preferred_esim_4g_volte_dds_1(self):
+ """ A MT vowifi call at pSIM, where
+ - pSIM 5G WFC in cellular preferred mode
+ - eSIM 4G VoLTE
+ - DDS at eSIM (slot 1)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the pSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 0,
+ 1,
+ mt_rat=["5g_wfc", "volte"],
+ call_direction="mt",
+ is_airplane_mode=True,
+ wfc_mode = [WFC_MODE_CELLULAR_PREFERRED, None],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="2fd7d04f-1ce7-40d0-86f1-ebf042dfad8b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mo_4g_wfc_cellular_preferred_psim_5g_nsa_volte_dds_1(self):
+ """ A MO vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G WFC in cellular preferred mode
+ - DDS at eSIM (slot 1)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ 1,
+ mo_rat=["5g_volte", "wfc"],
+ call_direction="mo",
+ is_airplane_mode=True,
+ wfc_mode = [None, WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="fd3bace9-f9ce-4870-8818-74f9b1605716")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_voice_esim_mt_4g_wfc_cellular_preferred_psim_5g_nsa_volte_dds_1(self):
+ """ A MT vowifi call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G WFC in cellular preferred mode
+ - DDS at eSIM (slot 1)
+ - Airplane mode
+
+ Airplane mode and Wi-Fi will be turned off in the end to ensure the eSIM will attach to
+ the network with assigned RAT successfully.
+ """
+ return dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ None,
+ 1,
+ 1,
+ mt_rat=["5g_volte", "wfc"],
+ call_direction="mt",
+ is_airplane_mode=True,
+ wfc_mode = [None, WFC_MODE_CELLULAR_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass,
+ turn_off_wifi_in_the_end=True,
+ turn_off_airplane_mode_in_the_end=True)
+
+ @test_tracker_info(uuid="f07a4924-0752-41fd-8e52-e75c3c78c538")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_esim_mo_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ """ A MO VoLTE long call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mo",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="cac09fa6-5db1-4523-910a-7fe9918a04ac")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_esim_mt_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ """ A MT VoLTE long call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mt",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="a0039ac0-9d3d-4acf-801b-4b0d01971153")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_esim_mo_volte_psim_5g_nsa_volte_dds_0(self):
+ """ A MO VoLTE long call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mo",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="9cf03491-df27-4eda-9e3d-7782a44c0674")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_esim_mt_volte_psim_5g_nsa_volte_dds_0(self):
+ """ A MT VoLTE long call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mt",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="6c8c7e67-3bec-49b4-8164-963e488df14f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_esim_mo_5g_nsa_volte_psim_volte_dds_0(self):
+ """ A MO VoLTE long call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "5g_volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mo",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="9a2bc9a2-18a2-471f-9b21-fd0aea1b126b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_esim_mt_5g_nsa_volte_psim_volte_dds_0(self):
+ """ A MT VoLTE long call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "5g_volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mt",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="c88a0ed6-f8b6-4033-93db-b160c29d4b9e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_psim_mo_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ """ A MO VoLTE long call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mo",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="b4aa294d-679d-4a0e-8cc9-9261bfe8b392")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_psim_mt_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ """ A MT VoLTE long call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mt",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="2e20f05f-9434-410f-a40a-a01c0303d1a0")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_psim_mo_5g_nsa_volte_esim_volte_dds_1(self):
+ """ A MO VoLTE long call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mo",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="3f89b354-0cdc-4522-8a67-76773219e5af")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_psim_mt_5g_nsa_volte_esim_volte_dds_1(self):
+ """ A MT VoLTE long call at eSIM, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mt",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="f18c61c5-3c3b-4645-90eb-e7bdef9b7c74")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_psim_mo_volte_esim_5g_nsa_volte_dds_1(self):
+ """ A MO VoLTE long call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "5g_volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mo",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="8324ffe2-1332-47fc-af92-a3ed7be9b629")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_psim_mt_volte_esim_5g_nsa_volte_dds_1(self):
+ """ A MT VoLTE long call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "5g_volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mt",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="e6760078-2a5e-4182-8ba1-57788fc607f1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_esim_mo_volte_psim_volte_dds_0(self):
+ """ A MO VoLTE long call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mo",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="c736e4f0-8dbc-480a-8da6-68453cc13d07")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_esim_mt_volte_psim_volte_dds_0(self):
+ """ A MO VoLTE long call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mt",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="19dc55b5-b989-481d-a980-fcd0ff56abc2")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_psim_mo_volte_esim_volte_dds_1(self):
+ """ A MO VoLTE long call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mo",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="494e9c90-6c56-4fa1-9fac-ac8f2b1c0dba")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_psim_mt_volte_esim_volte_dds_1(self):
+ """ A MT VoLTE long call at eSIM, where
+ - pSIM 4G VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mt",
+ duration=360,
+ streaming=False)
+
+ @test_tracker_info(uuid="d253553d-7dc9-4e38-8e20-0839326c20aa")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_esim_mo_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ """ A MO VoLTE long call at eSIM during streaming, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mo",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="80a201c5-0bfe-4d7f-b08b-52b7c53b6468")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_esim_mt_5g_nsa_volte_psim_5g_nsa_volte_dds_0(self):
+ """ A MT VoLTE long call at eSIM during streaming, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mt",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="8938575b-2544-4075-9cf9-3d938ad4d9cb")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_esim_mo_volte_psim_5g_nsa_volte_dds_0(self):
+ """ A MO VoLTE long call at eSIM during streaming, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mo",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="200c7cce-aba2-40f8-a274-9b05177d00e0")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_esim_mt_volte_psim_5g_nsa_volte_dds_0(self):
+ """ A MT VoLTE long call at eSIM during streaming, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 0)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mt",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="26bb9415-44f4-43df-b2e6-abbdfacf33c2")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_esim_mo_5g_nsa_volte_psim_volte_dds_0(self):
+ """ A MO VoLTE long call at eSIM during streaming, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "5g_volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mo",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="8a8dc1ca-6a85-4dc8-9e34-e17abe61f7b8")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_esim_mt_5g_nsa_volte_psim_volte_dds_0(self):
+ """ A MT VoLTE long call at eSIM during streaming, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 0)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "5g_volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mt",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="903a2813-6b27-4020-aaf2-b5ab8b29fa13")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_psim_mo_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ """ A MO VoLTE long call at eSIM during streaming, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mo",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="33d8ba2c-fa45-4ec0-aef5-b191b6ddd9a6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_psim_mt_5g_nsa_volte_esim_5g_nsa_volte_dds_1(self):
+ """ A MT VoLTE long call at eSIM during streaming, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "5g_volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mt",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="6db23c84-13d9-47fa-b8f1-45c56e2d6428")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_psim_mo_5g_nsa_volte_esim_volte_dds_1(self):
+ """ A MO VoLTE long call at eSIM during streaming, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mo",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="3a77b38f-c327-4c43-addf-48832bca7148")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_psim_mt_5g_nsa_volte_esim_volte_dds_1(self):
+ """ A MT VoLTE long call at eSIM during streaming, where
+ - pSIM 5G NSA VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["5g_volte", "volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mt",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="2898eb67-3dfe-4322-8c69-817e0a95dfda")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_psim_mo_volte_esim_5g_nsa_volte_dds_1(self):
+ """ A MO VoLTE long call at eSIM during streaming, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "5g_volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mo",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="780e8187-2068-4eca-a9de-e5f2f3491403")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_psim_mt_volte_esim_5g_nsa_volte_dds_1(self):
+ """ A MT VoLTE long call at eSIM during streaming, where
+ - pSIM 4G VoLTE
+ - eSIM 5G NSA VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "5g_volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mt",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="9b84bd00-fae3-45c0-9e44-dd57d1719bb9")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_esim_mo_volte_psim_volte_dds_0(self):
+ """ A MO VoLTE long call at eSIM during streaming, where
+ - pSIM 4G VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mo",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="813c6059-bcef-42d3-b70b-9b0ba67ffc20")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_esim_mt_volte_psim_volte_dds_0(self):
+ """ A MO VoLTE long call at eSIM during streaming, where
+ - pSIM 4G VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "volte"],
+ test_slot=1,
+ dds_slot=0,
+ direction="mt",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="970b1d31-195b-4599-80bc-bc46ede43a90")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_psim_mo_volte_esim_volte_dds_1(self):
+ """ A MO VoLTE long call at eSIM during streaming, where
+ - pSIM 4G VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mo",
+ duration=360,
+ streaming=True)
+
+ @test_tracker_info(uuid="62843f60-5d1c-44ed-9936-e10d2691e787")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_long_voice_streaming_psim_mt_volte_esim_volte_dds_1(self):
+ """ A MT VoLTE long call at eSIM during streaming, where
+ - pSIM 4G VoLTE
+ - eSIM 4G VoLTE
+ - DDS at pSIM (slot 1)
+
+ After call end will check the eSIM if is attach to the network
+ with assigned RAT successfully and data works fine.
+ """
+ return dsds_long_call_streaming_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ test_rat=["volte", "volte"],
+ test_slot=0,
+ dds_slot=1,
+ direction="mt",
+ duration=360,
+ streaming=True)
\ No newline at end of file
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSWfcSupplementaryServiceTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSWfcSupplementaryServiceTest.py
new file mode 100644
index 0000000..de31b45
--- /dev/null
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gDSDSWfcSupplementaryServiceTest.py
@@ -0,0 +1,318 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - Google
+#
+# 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 signals
+from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_CONFERENCE
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.tel.tel_dsds_utils import erase_call_forwarding
+from acts_contrib.test_utils.tel.tel_dsds_utils import msim_volte_wfc_call_forwarding
+from acts_contrib.test_utils.tel.tel_dsds_utils import msim_volte_wfc_call_voice_conf
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
+from acts_contrib.test_utils.tel.tel_test_utils import get_capability_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_wifi_utils import set_wifi_to_default
+
+
+class Nsa5gDSDSWfcSupplementaryServiceTest(TelephonyBaseTest):
+ def setup_class(self):
+ TelephonyBaseTest.setup_class(self)
+ self.tel_logger = TelephonyMetricLogger.for_test_case()
+ toggle_airplane_mode(self.log, self.android_devices[0], False)
+ erase_call_forwarding(self.log, self.android_devices[0])
+ if not get_capability_for_subscription(
+ self.android_devices[0],
+ CAPABILITY_CONFERENCE,
+ get_outgoing_voice_sub_id(self.android_devices[0])):
+ self.android_devices[0].log.error(
+ "Conference call is not supported, abort test.")
+ raise signals.TestAbortClass(
+ "Conference call is not supported, abort test.")
+
+ def teardown_test(self):
+ toggle_airplane_mode(self.log, self.android_devices[0], False)
+ ensure_phones_idle(self.log, self.android_devices)
+ erase_call_forwarding(self.log, self.android_devices[0])
+ set_wifi_to_default(self.log, self.android_devices[0])
+
+ @test_tracker_info(uuid="53169ee2-eb70-423e-bbe0-3112f34d2d73")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_psim_5g_nsa_wfc_wifi_preferred_apm_off_dds_0(self):
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ 0,
+ callee_rat=['5g_wfc', 'general'],
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="f0b1c9ce-a386-4b25-8a44-8ca4897fc650")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_psim_5g_nsa_wfc_wifi_preferred_apm_off_dds_1(self):
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ 1,
+ callee_rat=['5g_wfc', 'general'],
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="c952fe28-823d-412d-a3ac-797bd6e2dc09")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_psim_5g_nsa_volte_cellular_preferred_wifi_on_dds_0(self):
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ 0,
+ callee_rat=["5g_volte", "general"],
+ is_wifi_connected=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="d9e58366-46ea-454a-a1b1-466ec91112ef")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_esim_5g_nsa_wfc_wifi_preferred_apm_off_dds_0(self):
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ 0,
+ callee_rat=['general', '5g_wfc'],
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="18ce70a6-972c-4723-8e65-0c9814d14e76")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_esim_5g_nsa_wfc_wifi_preferred_apm_off_dds_1(self):
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ 1,
+ callee_rat=['general', '5g_wfc'],
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="d843d4cd-c562-47f1-b35b-57a84896314e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cfu_esim_5g_nsa_volte_cellular_preferred_wifi_on_dds_0(self):
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ 0,
+ callee_rat=["general", "5g_volte"],
+ is_wifi_connected=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="556a0737-f2c2-44c4-acfd-4eeb57e4c15e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cw_hold_swap_psim_5g_nsa_wfc_wifi_preferred_apm_off_dds_0(self):
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ 0,
+ host_rat=['5g_wfc', 'general'],
+ merge=False,
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="d86de799-73ed-432e-b9b8-e762df459ad0")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cw_hold_swap_psim_5g_nsa_wfc_wifi_preferred_apm_off_dds_1(self):
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ 1,
+ host_rat=['5g_wfc', 'general'],
+ merge=False,
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="9b9a9cd0-218f-4694-b5b7-ec2818abad48")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cw_hold_swap_psim_5g_nsa_volte_cellular_preferred_wifi_on_dds_0(self):
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ 0,
+ host_rat=["5g_volte", "general"],
+ merge=False,
+ is_airplane_mode=False,
+ is_wifi_connected=True,
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="02dd5686-0a55-497f-8b0c-9f624b6d7af5")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cw_hold_swap_esim_5g_nsa_wfc_wifi_preferred_apm_off_dds_0(self):
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ 0,
+ host_rat=['general', '5g_wfc'],
+ merge=False,
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="1527f060-8226-4507-a502-09e55096da0a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cw_hold_swap_esim_5g_nsa_wfc_wifi_preferred_apm_off_dds_1(self):
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ 1,
+ host_rat=['general', '5g_wfc'],
+ merge=False,
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="e6db2878-8d64-4566-95f9-e8cbf28723e8")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_cw_hold_swap_esim_5g_nsa_volte_cellular_preferred_wifi_on_dds_0(self):
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ 0,
+ host_rat=["general", "5g_volte"],
+ merge=False,
+ is_airplane_mode=False,
+ is_wifi_connected=True,
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="5dfb45b7-2706-418f-a5c1-2f8ca9602a29")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_conf_psim_5g_nsa_wfc_wifi_preferred_apm_off_dds_0(self):
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ 0,
+ host_rat=['5g_wfc', 'general'],
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="3b520d38-e1f4-46dd-90a7-90d91766e290")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_conf_psim_5g_nsa_wfc_wifi_preferred_apm_off_dds_1(self):
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ 1,
+ host_rat=['5g_wfc', 'general'],
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="f3f09280-bd34-46dc-b813-e017d671ddba")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_conf_psim_5g_nsa_volte_cellular_preferred_wifi_on_dds_0(self):
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ 0,
+ host_rat=["5g_volte", "general"],
+ is_wifi_connected=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="f157ba39-b4ae-464a-840a-56e94ba62736")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_conf_esim_5g_wfc_wifi_preferred_apm_off_dds_0(self):
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ 0,
+ host_rat=['general', '5g_wfc'],
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="872413fa-ae9c-4482-9e87-a3a4a2738bab")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_conf_esim_5g_nsa_wfc_wifi_preferred_apm_off_dds_1(self):
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ 1,
+ host_rat=['general', '5g_wfc'],
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="18023ab7-fa96-4dda-a9ed-dd7562a0d185")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_msim_conf_esim_5g_nsa_volte_cellular_preferred_wifi_on_dds_0(self):
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ 0,
+ host_rat=["general", "5g_volte"],
+ is_wifi_connected=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
\ No newline at end of file
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gDataTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gDataTest.py
index 905225b..8dfc5a6 100755
--- a/acts_tests/tests/google/nr/nsa5g/Nsa5gDataTest.py
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gDataTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3.4
#
-# Copyright 2020 - Google
+# Copyright 2022 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -25,14 +25,22 @@
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_USER_PLANE_DATA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_NR_LTE_GSM_WCDMA
from acts_contrib.test_utils.tel.tel_defines import NetworkCallbackCapabilitiesChanged
-from acts_contrib.test_utils.tel.tel_defines import NetworkCallbackLost
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK
+from acts_contrib.test_utils.tel.tel_data_utils import browsing_test
+from acts_contrib.test_utils.tel.tel_data_utils import check_data_stall_detection
+from acts_contrib.test_utils.tel.tel_data_utils import check_data_stall_recovery
+from acts_contrib.test_utils.tel.tel_data_utils import check_network_validation_fail
+from acts_contrib.test_utils.tel.tel_data_utils import data_connectivity_single_bearer
+from acts_contrib.test_utils.tel.tel_data_utils import test_data_connectivity_multi_bearer
+from acts_contrib.test_utils.tel.tel_data_utils import test_wifi_connect_disconnect
+from acts_contrib.test_utils.tel.tel_data_utils import verify_for_network_callback
+from acts_contrib.test_utils.tel.tel_data_utils import wifi_cell_switching
+from acts_contrib.test_utils.tel.tel_data_utils import airplane_mode_test
+from acts_contrib.test_utils.tel.tel_data_utils import reboot_test
+from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g
+from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
from acts_contrib.test_utils.tel.tel_test_utils import break_internet_except_sl4a_port
-from acts_contrib.test_utils.tel.tel_test_utils import check_data_stall_detection
-from acts_contrib.test_utils.tel.tel_test_utils import check_data_stall_recovery
-from acts_contrib.test_utils.tel.tel_test_utils import check_network_validation_fail
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
from acts_contrib.test_utils.tel.tel_test_utils import get_current_override_network_type
from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
from acts_contrib.test_utils.tel.tel_test_utils import iperf_test_by_adb
@@ -43,30 +51,21 @@
from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_success_using_sl4a
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_reset
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_toggle_state
-from acts_contrib.test_utils.tel.tel_data_utils import browsing_test
-from acts_contrib.test_utils.tel.tel_data_utils import data_connectivity_single_bearer
-from acts_contrib.test_utils.tel.tel_data_utils import test_data_connectivity_multi_bearer
-from acts_contrib.test_utils.tel.tel_data_utils import test_wifi_connect_disconnect
-from acts_contrib.test_utils.tel.tel_data_utils import verify_for_network_callback
-from acts_contrib.test_utils.tel.tel_data_utils import wifi_cell_switching
-from acts_contrib.test_utils.tel.tel_data_utils import airplane_mode_test
-from acts_contrib.test_utils.tel.tel_data_utils import reboot_test
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_nsa
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
-from acts_contrib.test_utils.tel.tel_5g_test_utils import set_preferred_mode_for_5g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_reset
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
class Nsa5gDataTest(TelephonyBaseTest):
def setup_class(self):
super().setup_class()
self.iperf_server_ip = self.user_params.get("iperf_server", '0.0.0.0')
- self.iperf_tcp_port = self.user_params.get("iperf_tcp_port", 0)
- self.iperf_udp_port = self.user_params.get("iperf_udp_port", 0)
- self.iperf_duration = self.user_params.get("iperf_duration", 60)
+ self.iperf_tcp_port = int(
+ self.user_params.get("iperf_tcp_port", 0))
+ self.iperf_udp_port = int(
+ self.user_params.get("iperf_udp_port", 0))
+ self.iperf_duration = int(
+ self.user_params.get("iperf_duration", 60))
def setup_test(self):
TelephonyBaseTest.setup_test(self)
@@ -100,7 +99,7 @@
return False
ad.log.info("Set network mode to NSA successfully")
ad.log.info("Waiting for 5g NSA attach for 60 secs")
- if is_current_network_5g_nsa(ad, timeout=60):
+ if is_current_network_5g(ad, nr_type = 'nsa', timeout=60):
ad.log.info("Success! attached on 5g NSA")
else:
ad.log.error("Failure - expected NR_NSA, current %s",
@@ -147,7 +146,7 @@
wifi_toggle_state(ad.log, ad, False)
toggle_airplane_mode(ad.log, ad, False)
- if not provision_device_for_5g(ad.log, ad):
+ if not provision_device_for_5g(ad.log, ad, nr_type='nsa'):
return False
cmd = ('ss -l -p -n | grep "tcp.*droid_script" | tr -s " " '
@@ -204,7 +203,7 @@
try:
wifi_toggle_state(ad.log, ad, False)
toggle_airplane_mode(ad.log, ad, False)
- if not provision_device_for_5g(ad.log, ad):
+ if not provision_device_for_5g(ad.log, ad, nr_type='nsa'):
return False
return verify_for_network_callback(ad.log, ad,
@@ -229,7 +228,7 @@
ad = self.android_devices[0]
try:
toggle_airplane_mode(ad.log, ad, False)
- if not provision_device_for_5g(ad.log, ad):
+ if not provision_device_for_5g(ad.log, ad, nr_type='nsa'):
return False
wifi_toggle_state(ad.log, ad, True)
if not ensure_wifi_connected(ad.log, ad,
@@ -261,7 +260,7 @@
ad = self.android_devices[0]
try:
toggle_airplane_mode(ad.log, ad, False)
- if not provision_device_for_5g(ad.log, ad):
+ if not provision_device_for_5g(ad.log, ad, nr_type='nsa'):
return False
wifi_toggle_state(ad.log, ad, False)
return iperf_udp_test_by_adb(ad.log,
@@ -290,7 +289,7 @@
ad = self.android_devices[0]
try:
toggle_airplane_mode(ad.log, ad, False)
- if not provision_device_for_5g(ad.log, ad):
+ if not provision_device_for_5g(ad.log, ad, nr_type='nsa'):
return False
wifi_toggle_state(ad.log, ad, False)
return iperf_test_by_adb(ad.log,
@@ -319,7 +318,7 @@
ad = self.android_devices[0]
try:
toggle_airplane_mode(ad.log, ad, False)
- if not provision_device_for_5g(ad.log, ad):
+ if not provision_device_for_5g(ad.log, ad, nr_type='nsa'):
return False
wifi_toggle_state(ad.log, ad, False)
return iperf_udp_test_by_adb(ad.log,
@@ -334,20 +333,6 @@
ad.log.error(e)
return False
-
- @test_tracker_info(uuid="cd1429e8-94d7-44de-ae48-68cf42f3246b")
- @TelephonyBaseTest.tel_test_wrap
- def test_5g_nsa_browsing(self):
- ad = self.android_devices[0]
- ad.log.info("Connect to NR and verify internet connection.")
- if not provision_device_for_5g(ad.log, ad):
- return False
- if not verify_internet_connection(ad.log, ad):
- return False
-
- return browsing_test(ad.log, ad)
-
-
@test_tracker_info(uuid="7179f0f1-f0ca-4496-8f4a-7eebc616a41a")
@TelephonyBaseTest.tel_test_wrap
def test_5g_nsa_wifi_switching(self):
@@ -365,7 +350,7 @@
"""
ad = self.android_devices[0]
return wifi_cell_switching(ad.log, ad, GEN_5G, self.wifi_network_ssid,
- self.wifi_network_pass)
+ self.wifi_network_pass, nr_type='nsa')
@test_tracker_info(uuid="75066e0a-0e2e-4346-a253-6ed11d1c4d23")
@@ -388,12 +373,12 @@
if not phone_setup_volte(ads[0].log, ads[0]):
ads[0].log.error("Failed to setup VoLTE")
return False
- return test_data_connectivity_multi_bearer(self.log, ads, GEN_5G)
+ return test_data_connectivity_multi_bearer(self.log, ads, GEN_5G, nr_type='nsa')
@test_tracker_info(uuid="e88b226e-3842-4c45-a33e-d4fee7d8f6f0")
@TelephonyBaseTest.tel_test_wrap
- def test_5g_nsa(self):
+ def test_5g_nsa_data_connectivity(self):
"""Test data connection in nsa5g.
Turn off airplane mode, disable WiFi, enable Cellular Data.
@@ -409,7 +394,7 @@
ad = self.android_devices[0]
wifi_reset(ad.log, ad)
wifi_toggle_state(ad.log, ad, False)
- return data_connectivity_single_bearer(ad.log, ad, GEN_5G)
+ return data_connectivity_single_bearer(ad.log, ad, GEN_5G, nr_type='nsa')
@test_tracker_info(uuid="4c70e09d-f215-4c5b-8c61-f9e9def43d30")
@@ -431,7 +416,7 @@
wifi_reset(ad.log, ad)
wifi_toggle_state(ad.log, ad, False)
wifi_toggle_state(ad.log, ad, True)
- return data_connectivity_single_bearer(ad.log, ad, GEN_5G)
+ return data_connectivity_single_bearer(ad.log, ad, GEN_5G, nr_type='nsa')
@test_tracker_info(uuid="8308bf40-7f1b-443f-bde6-19d9ff97e471")
@@ -453,7 +438,7 @@
True if success.
False if failed.
"""
- if not provision_device_for_5g(self.log, self.provider):
+ if not provision_device_for_5g(self.log, self.provider, nr_type='nsa'):
return False
return test_wifi_connect_disconnect(self.log, self.provider, self.wifi_network_ssid, self.wifi_network_pass)
@@ -472,15 +457,24 @@
Returns:
True if pass; False if fail.
"""
- if not provision_device_for_5g(self.log, self.android_devices[0]):
+ if not provision_device_for_5g(self.log, self.android_devices[0], nr_type='nsa'):
return False
return airplane_mode_test(self.log, self.android_devices[0])
@test_tracker_info(uuid="091cde37-0bac-4399-83aa-cbd5a83b07a1")
@TelephonyBaseTest.tel_test_wrap
def test_5g_nsa_reboot(self):
- """Test 5G NSA service availability after reboot."""
- if not provision_device_for_5g(self.log, self.android_devices[0]):
+ """Test 5G NSA service availability after reboot.
+
+ Ensure phone is on 5G NSA.
+ Ensure phone attach, data on, WiFi off and verify Internet.
+ Reboot Device.
+ Verify Network Connection.
+
+ Returns:
+ True if pass; False if fail.
+ """
+ if not provision_device_for_5g(self.log, self.android_devices[0], nr_type='nsa'):
return False
if not verify_internet_connection(self.log, self.android_devices[0]):
return False
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gDsdsMessageTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gDsdsMessageTest.py
deleted file mode 100644
index 01888cf..0000000
--- a/acts_tests/tests/google/nr/nsa5g/Nsa5gDsdsMessageTest.py
+++ /dev/null
@@ -1,357 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2021 - Google
-#
-# 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 signals
-from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
-from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
-from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
-from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
-from acts_contrib.test_utils.tel.tel_defines import GEN_5G
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_message_subid
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_data
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_0
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_1
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import sms_send_receive_verify_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import sms_in_collision_send_receive_verify_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import sms_rx_power_off_multiple_send_receive_verify_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import voice_call_in_collision_with_mt_sms_msim
-from acts_contrib.test_utils.tel.tel_test_utils import mms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.tel.tel_test_utils import log_messaging_screen_shot
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import get_slot_index_from_subid
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_general_for_subscription
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_on_rat
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_on_rat
-from acts.utils import rand_ascii_str
-
-CallResult = TelephonyVoiceTestResult.CallResult.Value
-
-class Nsa5gDsdsMessageTest(TelephonyBaseTest):
- def setup_class(self):
- TelephonyBaseTest.setup_class(self)
- self.message_lengths = (50, 160, 180)
- self.tel_logger = TelephonyMetricLogger.for_test_case()
-
- def teardown_test(self):
- ensure_phones_idle(self.log, self.android_devices)
-
- def _msim_message_test(
- self,
- ad_mo,
- ad_mt,
- mo_sub_id,
- mt_sub_id, msg="SMS",
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
- expected_result=True):
- """Make MO/MT SMS/MMS at specific slot.
-
- Args:
- ad_mo: Android object of the device sending SMS/MMS
- ad_mt: Android object of the device receiving SMS/MMS
- mo_sub_id: Sub ID of MO device
- mt_sub_id: Sub ID of MT device
- max_wait_time: Max wait time before SMS/MMS is received.
- expected_result: True for successful sending/receiving and False on
- the contrary
-
- Returns:
- True if the result matches expected_result and False on the
- contrary.
- """
-
- if msg == "SMS":
- for length in self.message_lengths:
- message_array = [rand_ascii_str(length)]
- if not sms_send_receive_verify_for_subscription(
- self.log,
- ad_mo,
- ad_mt,
- mo_sub_id,
- mt_sub_id,
- message_array,
- max_wait_time):
- ad_mo.log.warning(
- "%s of length %s test failed", msg, length)
- return False
- else:
- ad_mo.log.info(
- "%s of length %s test succeeded", msg, length)
- self.log.info("%s test of length %s characters succeeded.",
- msg, self.message_lengths)
-
- elif msg == "MMS":
- for length in self.message_lengths:
- message_array = [("Test Message", rand_ascii_str(length), None)]
-
- if not mms_send_receive_verify(
- self.log,
- ad_mo,
- ad_mt,
- message_array,
- max_wait_time,
- expected_result):
- self.log.warning("%s of body length %s test failed",
- msg, length)
- return False
- else:
- self.log.info(
- "%s of body length %s test succeeded", msg, length)
- self.log.info("%s test of body lengths %s succeeded",
- msg, self.message_lengths)
- return True
-
- def _test_msim_message(
- self,
- mo_slot,
- mt_slot,
- dds_slot,
- msg="SMS",
- mo_rat=["", ""],
- mt_rat=["", ""],
- direction="mo",
- expected_result=True):
- """Make MO/MT SMS/MMS at specific slot in specific RAT with DDS at
- specific slot.
-
- Test step:
- 1. Get sub IDs of specific slots of both MO and MT devices.
- 2. Switch DDS to specific slot.
- 3. Check HTTP connection after DDS switch.
- 4. Set up phones in desired RAT.
- 5. Send SMS/MMS.
-
- Args:
- mo_slot: Slot sending MO SMS (0 or 1)
- mt_slot: Slot receiving MT SMS (0 or 1)
- dds_slot: Preferred data slot
- mo_rat: RAT for both slots of MO device
- mt_rat: RAT for both slots of MT device
- direction: "mo" or "mt"
- expected_result: True of False
-
- Returns:
- TestFailure if failed.
- """
- ads = self.android_devices
-
- if direction == "mo":
- ad_mo = ads[0]
- ad_mt = ads[1]
- else:
- ad_mo = ads[1]
- ad_mt = ads[0]
-
- if mo_slot is not None:
- mo_sub_id = get_subid_from_slot_index(self.log, ad_mo, mo_slot)
- if mo_sub_id == INVALID_SUB_ID:
- ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot)
- return False
- mo_other_sub_id = get_subid_from_slot_index(
- self.log, ad_mo, 1-mo_slot)
- set_message_subid(ad_mo, mo_sub_id)
- else:
- _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(
- ads, type="sms")
- if mo_sub_id == INVALID_SUB_ID:
- ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot)
- return False
- mo_slot = "auto"
- set_message_subid(ad_mo, mo_sub_id)
- if msg == "MMS":
- set_subid_for_data(ad_mo, mo_sub_id)
- ad_mo.droid.telephonyToggleDataConnection(True)
- ad_mo.log.info("Sub ID for outgoing %s at slot %s: %s", msg, mo_slot,
- get_outgoing_message_sub_id(ad_mo))
-
- if mt_slot is not None:
- mt_sub_id = get_subid_from_slot_index(self.log, ad_mt, mt_slot)
- if mt_sub_id == INVALID_SUB_ID:
- ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
- return False
- mt_other_sub_id = get_subid_from_slot_index(
- self.log, ad_mt, 1-mt_slot)
- set_message_subid(ad_mt, mt_sub_id)
- else:
- _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(
- ads, type="sms")
- if mt_sub_id == INVALID_SUB_ID:
- ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
- return False
- mt_slot = "auto"
- set_message_subid(ad_mt, mt_sub_id)
- if msg == "MMS":
- set_subid_for_data(ad_mt, mt_sub_id)
- ad_mt.droid.telephonyToggleDataConnection(True)
- ad_mt.log.info("Sub ID for incoming %s at slot %s: %s", msg, mt_slot,
- get_outgoing_message_sub_id(ad_mt))
-
- self.log.info("Step 1: Switch DDS.")
- if dds_slot:
- if not set_dds_on_slot_1(ads[0]):
- self.log.warning(
- "Failed to set DDS at eSIM on %s", ads[0].serial)
- return False
- else:
- if not set_dds_on_slot_0(ads[0]):
- self.log.warning(
- "Failed to set DDS at pSIM on %s", ads[0].serial)
- return False
-
- self.log.info("Step 2: Check HTTP connection after DDS switch.")
- if not verify_http_connection(self.log,
- ads[0],
- url="https://www.google.com",
- retry=5,
- retry_interval=15,
- expected_state=True):
-
- self.log.error("Failed to verify http connection.")
- return False
- else:
- self.log.info("Verify http connection successfully.")
-
- mo_phone_setup_func_argv = (self.log, ad_mo, mo_sub_id)
- mt_phone_setup_func_argv = (self.log, ad_mt, mt_sub_id)
-
- if mo_slot in (0, 1):
- # set up the rat on mo side another slot which not to be test(primary device)
- phone_setup_on_rat(self.log, ad_mo, mo_rat[1-mo_slot], mo_other_sub_id)
- # get phone setup function and required argument of primary device
- if '5g' in mo_rat[mo_slot].lower():
- mo_phone_setup_func_argv = (self.log, ad_mo, mo_sub_id, GEN_5G)
- mo_phone_setup_func = phone_setup_on_rat(
- self.log,
- ad_mo,
- mo_rat[mo_slot],
- only_return_fn=True)
- else:
- # set up the rat and get phone setup function on mo side(non-primary device)
- phone_setup_on_rat(self.log, ad_mo, 'general', sub_id_type='sms')
- mo_phone_setup_func = phone_setup_voice_general_for_subscription
-
- if mt_slot in (0, 1):
- # set up the rat on mt side another slot which not to be test(primary device)
- phone_setup_on_rat(self.log, ad_mt, mt_rat[1-mt_slot], mt_other_sub_id)
- # get phone setup function and required argument of primary device
- if '5g' in mt_rat[mt_slot].lower():
- mt_phone_setup_func_argv = (self.log, ad_mt, mt_sub_id, GEN_5G)
- mt_phone_setup_func = phone_setup_on_rat(
- self.log,
- ad_mt,
- mt_rat[mt_slot],
- only_return_fn=True)
- else:
- # set up the rat and get phone setup function on mt side(non-primary device)
- phone_setup_on_rat(self.log, ad_mt, 'general', sub_id_type='sms')
- mt_phone_setup_func = phone_setup_voice_general_for_subscription
-
- self.log.info("Step 3: Set up phones in desired RAT.")
- tasks = [(mo_phone_setup_func, mo_phone_setup_func_argv),
- (mt_phone_setup_func, mt_phone_setup_func_argv)]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
-
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- self.log.info("Step 4: Send %s.", msg)
-
- if msg == "MMS":
- for ad, current_data_sub_id, current_msg_sub_id in [
- [ ads[0],
- get_default_data_sub_id(ads[0]),
- get_outgoing_message_sub_id(ads[0]) ],
- [ ads[1],
- get_default_data_sub_id(ads[1]),
- get_outgoing_message_sub_id(ads[1]) ]]:
- if current_data_sub_id != current_msg_sub_id:
- ad.log.warning(
- "Current data sub ID (%s) does not match message"
- " sub ID (%s). MMS should NOT be sent.",
- current_data_sub_id,
- current_msg_sub_id)
- expected_result = False
-
- result = self._msim_message_test(ad_mo, ad_mt, mo_sub_id, mt_sub_id,
- msg=msg, expected_result=expected_result)
-
- if not result:
- log_messaging_screen_shot(ad_mo, test_name="%s_tx" % msg)
- log_messaging_screen_shot(ad_mt, test_name="%s_rx" % msg)
-
- return result
-
- @test_tracker_info(uuid="183cda35-45aa-485d-b3d4-975d78f7d361")
- @TelephonyBaseTest.tel_test_wrap
- def test_msim_sms_mo_psim_volte_esim_nsa_5g_volte_dds_1(self):
- return self._test_msim_message(
- 0, None, 1, mo_rat=["volte", "5g_volte"], msg="SMS", direction="mo")
-
- @test_tracker_info(uuid="d9cb69ce-c462-4fd4-b716-bfb1fd2ed86a")
- @TelephonyBaseTest.tel_test_wrap
- def test_msim_sms_mt_psim_volte_esim_nsa_5g_volte_dds_1(self):
- return self._test_msim_message(
- None, 0, 1, mt_rat=["volte", "5g_volte"], msg="SMS", direction="mt")
-
- @test_tracker_info(uuid="51d5e05d-66e7-4369-91e0-6cdc573d9a59")
- @TelephonyBaseTest.tel_test_wrap
- def test_msim_sms_mo_esim_nsa_5g_volte_psim_volte_dds_1(self):
- return self._test_msim_message(
- 1, None, 1, mo_rat=["volte", "5g_volte"], msg="SMS", direction="mo")
-
- @test_tracker_info(uuid="38271a0f-2efb-4991-9f24-6da9f003ddd4")
- @TelephonyBaseTest.tel_test_wrap
- def test_msim_sms_mt_esim_nsa_5g_volte_psim_volte_dds_1(self):
- return self._test_msim_message(
- None, 1, 1, mt_rat=["volte", "5g_volte"], msg="SMS", direction="mt")
-
- @test_tracker_info(uuid="87759475-0208-4d9b-b5b9-814fdb97f09c")
- @TelephonyBaseTest.tel_test_wrap
- def test_msim_sms_mo_psim_nsa_5g_volte_esim_volte_dds_0(self):
- return self._test_msim_message(
- 0, None, 0, mo_rat=["5g_volte", "volte"], msg="SMS", direction="mo")
-
- @test_tracker_info(uuid="2f14e81d-330f-4cdd-837c-1168185ffec4")
- @TelephonyBaseTest.tel_test_wrap
- def test_msim_sms_mt_psim_nsa_5g_volte_esim_volte_dds_0(self):
- return self._test_msim_message(
- None, 0, 0, mt_rat=["5g_volte", "volte"], msg="SMS", direction="mt")
-
- @test_tracker_info(uuid="9cc45474-1fca-4008-8499-87829d6516ea")
- @TelephonyBaseTest.tel_test_wrap
- def test_msim_sms_mo_esim_volte_psim_nsa_5g_volte_dds_0(self):
- return self._test_msim_message(
- 1, None, 0, mo_rat=["5g_volte", "volte"], msg="SMS", direction="mo")
-
- @test_tracker_info(uuid="341786de-5b23-438a-a91b-97cf420ef5fd")
- @TelephonyBaseTest.tel_test_wrap
- def test_msim_sms_mt_esim_volte_psim_nsa_5g_volte_dds_0(self):
- return self._test_msim_message(
- None, 1, 0, mt_rat=["5g_volte", "volte"], msg="SMS", direction="mt")
-
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gImsSettingsTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gImsSettingsTest.py
index 6e2b143..127942e 100644
--- a/acts_tests/tests/google/nr/nsa5g/Nsa5gImsSettingsTest.py
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gImsSettingsTest.py
@@ -17,26 +17,19 @@
Test Script for 5G IMS Settings scenarios
"""
-import time
-
from acts import signals
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import CarrierConfigs
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
from acts_contrib.test_utils.tel.tel_defines import RAT_NR
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_on_rat
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
from acts_contrib.test_utils.tel.tel_test_utils import dumpsys_carrier_config
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_nsa
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
-from acts_contrib.test_utils.tel.tel_5g_test_utils import set_preferred_mode_for_5g
-from acts_contrib.test_utils.tel.tel_ims_utils import change_ims_setting
+from acts_contrib.test_utils.tel.tel_voice_utils import change_ims_setting
class Nsa5gImsSettingsTest(TelephonyBaseTest):
@@ -82,11 +75,8 @@
4. DUT WiFi Calling feature bit return False, network rat is not iwlan.
"""
- if not phone_setup_volte(self.log, self.dut):
- self.log.error("Failed to setup VoLTE")
- return False
-
- if not provision_device_for_5g(self.log, self.dut):
+ if not phone_setup_on_rat(self.log, self.dut, rat='5g_volte'):
+ self.log.error("Phone Failed to setup Properly")
return False
if not change_ims_setting(log=self.log,
@@ -151,13 +141,10 @@
4. DUT WiFi Calling feature bit return False, network rat is not iwlan.
"""
- if not phone_setup_csfb(self.log, self.dut):
+ if not phone_setup_on_rat(self.log, self.dut, rat='5g_csfb'):
self.log.error("Phone Failed to setup Properly")
return False
- if not provision_device_for_5g(self.log, self.dut):
- return False
-
if not change_ims_setting(log=self.log,
ad=self.dut,
dut_client= self.dut_client,
@@ -217,12 +204,8 @@
3. DUT WiFi Calling feature bit return True, network rat is iwlan.
4. DUT WiFi Calling feature bit return False, network rat is not iwlan.
"""
- if not phone_setup_volte(self.log, self.dut):
- self.log.error("Failed to setup VoLTE")
- return False
-
- ads = self.android_devices
- if not provision_device_for_5g(self.log, ads):
+ if not phone_setup_on_rat(self.log, self.dut, rat='5g_volte'):
+ self.log.error("Phone Failed to setup Properly")
return False
if not change_ims_setting(log=self.log,
@@ -284,11 +267,8 @@
3. DUT WiFi Calling feature bit return True, network rat is iwlan.
4. DUT WiFi Calling feature bit return False, network rat is not iwlan.
"""
- if not phone_setup_csfb(self.log, self.dut):
- self.log.error("Failed to setup CSFB")
- return False
-
- if not provision_device_for_5g(self.log, self.dut):
+ if not phone_setup_on_rat(self.log, self.dut, rat='5g_csfb'):
+ self.log.error("Phone Failed to setup Properly")
return False
if not change_ims_setting(log=self.log,
@@ -356,11 +336,8 @@
3. DUT WiFi Calling feature bit return True, network rat is iwlan.
4. DUT WiFi Calling feature bit return True, network rat is iwlan.
"""
- if not phone_setup_volte(self.log, self.dut):
- self.dut.log.error("Phone Failed to setup properly")
- return False
-
- if not provision_device_for_5g(self.log, self.dut):
+ if not phone_setup_on_rat(self.log, self.dut, rat='5g_volte'):
+ self.log.error("Phone Failed to setup Properly")
return False
if not change_ims_setting(log=self.log,
@@ -429,11 +406,8 @@
raise signals.TestSkip(
"WFC_MODE_CELLULAR_PREFERRED is not supported")
- if not phone_setup_volte(self.log, self.dut):
- self.dut.log.error("Phone Failed to setup properly.")
- return False
-
- if not provision_device_for_5g(self.log, self.dut):
+ if not phone_setup_on_rat(self.log, self.dut, rat='5g_volte'):
+ self.log.error("Phone Failed to setup Properly")
return False
if not change_ims_setting(log=self.log,
@@ -488,11 +462,8 @@
raise signals.TestSkip(
"WFC_MODE_CELLULAR_PREFERRED is not supported")
- if not phone_setup_csfb(self.log, self.dut):
- self.dut.log.error("Failed to setup properly")
- return False
-
- if not provision_device_for_5g(self.log, self.dut):
+ if not phone_setup_on_rat(self.log, self.dut, rat='5g_csfb'):
+ self.log.error("Phone Failed to setup Properly")
return False
if not change_ims_setting(log=self.log,
@@ -547,11 +518,8 @@
if WFC_MODE_CELLULAR_PREFERRED not in self.dut_wfc_modes:
raise signals.TestSkip(
"WFC_MODE_CELLULAR_PREFERRED is not supported")
- if not phone_setup_volte(self.log, self.dut):
- self.dut.log.error("Phone Failed to setup properly")
- return False
-
- if not provision_device_for_5g(self.log, self.dut):
+ if not phone_setup_on_rat(self.log, self.dut, rat='5g_volte'):
+ self.log.error("Phone Failed to setup Properly")
return False
if not change_ims_setting(log=self.log,
@@ -606,11 +574,8 @@
raise signals.TestSkip(
"WFC_MODE_CELLULAR_PREFERRED is not supported")
- if not phone_setup_csfb(self.log, self.dut):
- self.dut.log.error("Phone Failed to setup properly")
- return False
-
- if not provision_device_for_5g(self.log, self.dut):
+ if not phone_setup_on_rat(self.log, self.dut, rat='5g_csfb'):
+ self.log.error("Phone Failed to setup Properly")
return False
if not change_ims_setting(log=self.log,
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gMmsTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gMmsTest.py
index 22c8842..e7bcb5a 100755
--- a/acts_tests/tests/google/nr/nsa5g/Nsa5gMmsTest.py
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gMmsTest.py
@@ -21,49 +21,31 @@
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
-from acts_contrib.test_utils.tel.tel_defines import SMS_OVER_WIFI_PROVIDERS
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_default_state
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
-from acts_contrib.test_utils.tel.tel_5g_test_utils import connect_both_devices_to_wifi
-from acts_contrib.test_utils.tel.tel_5g_test_utils import disable_apm_mode_both_devices
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
+from acts_contrib.test_utils.tel.tel_message_utils import message_test
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_task
+from acts_contrib.test_utils.tel.tel_test_utils import install_message_apk
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_both_devices_for_volte
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_both_devices_for_wfc_cell_pref
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_both_devices_for_wfc_wifi_pref
-from acts_contrib.test_utils.tel.tel_5g_test_utils import verify_5g_attach_for_both_devices
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_both_devices_for_csfb
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_nsa
-from acts_contrib.test_utils.tel.tel_mms_utils import _mms_test_mo
-from acts_contrib.test_utils.tel.tel_mms_utils import _mms_test_mt
-from acts_contrib.test_utils.tel.tel_mms_utils import _long_mms_test_mo
-from acts_contrib.test_utils.tel.tel_mms_utils import test_mms_mo_in_call
+from acts.libs.utils.multithread import run_multithread_func
class Nsa5gMmsTest(TelephonyBaseTest):
def setup_class(self):
super().setup_class()
- self.number_of_devices = 2
- self.message_lengths = (50, 160, 180)
- is_roaming = False
- for ad in self.android_devices:
- ad.sms_over_wifi = False
- # verizon supports sms over wifi. will add more carriers later
- for sub in ad.telephony["subscription"].values():
- if sub["operator"] in SMS_OVER_WIFI_PROVIDERS:
- ad.sms_over_wifi = True
- if getattr(ad, 'roaming', False):
- is_roaming = True
- if is_roaming:
- # roaming device does not allow message of length 180
- self.message_lengths = (50, 160)
+ self.message_util = self.user_params.get("message_apk", None)
+ if isinstance(self.message_util, list):
+ self.message_util = self.message_util[0]
+
+ if self.message_util:
+ ads = self.android_devices
+ for ad in ads:
+ install_message_apk(ad, self.message_util)
def setup_test(self):
TelephonyBaseTest.setup_test(self)
@@ -73,8 +55,6 @@
""" Tests Begin """
-
-
@test_tracker_info(uuid="bc484c2c-8086-42db-94cd-a1e4a35f35cf")
@TelephonyBaseTest.tel_test_wrap
def test_5g_nsa_mms_mo_mt(self):
@@ -88,19 +68,55 @@
True if success.
False if failed.
"""
- ads = self.android_devices
- if not provision_device_for_5g(self.log, ads):
- return False
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g',
+ mt_rat='5g',
+ msg_type='mms')
- if not _mms_test_mo(self.log, ads):
- return False
+ @test_tracker_info(uuid="88bd6658-30fa-41b1-b5d9-0f9dadd83219")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mo_general(self):
+ """Test MO MMS for 1 phone in 5g NSA. The other phone in any network
- if not verify_5g_attach_for_both_devices(self.log, ads):
- return False
+ Provision PhoneA in 5g NSA
+ Send and Verify MMS from PhoneA to PhoneB
+ Verify phoneA is still on 5g NSA
- self.log.info("PASS - mms test over 5g nsa validated")
- return True
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g',
+ mt_rat='default',
+ msg_type='mms')
+ @test_tracker_info(uuid="11f2e2c8-bb63-43fa-b279-e7bb32f80596")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mt_general(self):
+ """Test MT MMS for 1 phone in 5g NSA. The other phone in any network
+
+ Provision PhoneA in 5g NSA
+ Send and Verify MMS from PhoneB to PhoneA
+ Verify phoneA is still on 5g NSA
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g',
+ msg_type='mms')
@test_tracker_info(uuid="51d42104-cb87-4c9b-9a16-302e246a21dc")
@TelephonyBaseTest.tel_test_wrap
@@ -116,23 +132,13 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
- if not provision_both_devices_for_volte(self.log, ads):
- return False
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- if not _mms_test_mo(self.log, ads):
- return False
-
- if not verify_5g_attach_for_both_devices(self.log, ads):
- return False
-
- self.log.info("PASS - volte mms test over 5g nsa validated")
- return True
-
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_volte',
+ mt_rat='5g_volte',
+ msg_type='mms')
@test_tracker_info(uuid="97d6b071-aef2-40c1-8245-7be6c31870a6")
@TelephonyBaseTest.tel_test_wrap
@@ -148,31 +154,14 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
- if not provision_both_devices_for_volte(self.log, ads):
- return False
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- self.log.info("Begin Incall mms test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_volte,
- verify_callee_func=None):
- return False
-
- if not _mms_test_mo(self.log, ads):
- return False
-
- if not verify_5g_attach_for_both_devices(self.log, ads):
- return False
- self.log.info("PASS - Incall volte mms test over 5g nsa validated")
- return True
-
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_volte',
+ mt_rat='5g_volte',
+ msg_type='mms',
+ msg_in_call=True)
@test_tracker_info(uuid="bbb4b80c-fc1b-4377-b3c7-eeed642c5980")
@TelephonyBaseTest.tel_test_wrap
@@ -188,28 +177,18 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
- if not disable_apm_mode_both_devices(self.log, ads):
- return False
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- if not provision_both_devices_for_wfc_cell_pref(self.log,
- ads,
- self.wifi_network_ssid,
- self.wifi_network_pass,
- apm_mode=True):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not _mms_test_mo(self.log, ads):
- return False
-
- self.log.info("PASS - iwlan mms test over 5g nsa validated")
- return True
-
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_wfc',
+ mt_rat='5g_wfc',
+ msg_type='mms',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="d36d95dc-0973-4711-bb08-c29ce23495e4")
@TelephonyBaseTest.tel_test_wrap
@@ -225,31 +204,17 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
- if not disable_apm_mode_both_devices(self.log, ads):
- return False
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- if not provision_both_devices_for_wfc_wifi_pref(self.log,
- ads,
- self.wifi_network_ssid,
- self.wifi_network_pass,
- apm_mode=False):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not _mms_test_mo(self.log, ads):
- self.log.error("Failed to send receive sms over 5g nsa")
- return False
- self.log.info("PASS - iwlan mms test over 5g nsa validated")
-
- if not verify_5g_attach_for_both_devices(self.log, ads):
- return False
- return True
-
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_wfc',
+ mt_rat='5g_wfc',
+ msg_type='mms',
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="74ffb79e-f1e9-4087-a9d2-e07878e47869")
@TelephonyBaseTest.tel_test_wrap
@@ -265,35 +230,19 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- if not disable_apm_mode_both_devices(self.log, ads):
- return False
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- if not provision_both_devices_for_wfc_wifi_pref(self.log,
- ads,
- self.wifi_network_ssid,
- self.wifi_network_pass,
- apm_mode=True):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- self.log.info("Begin Incall mms test")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_iwlan,
- verify_callee_func=None):
- return False
-
- return _mms_test_mo(self.log, ads)
-
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_wfc',
+ mt_rat='5g_wfc',
+ msg_type='mms',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="68c8e0ca-bea4-45e4-92cf-19424ee47ca4")
@TelephonyBaseTest.tel_test_wrap
@@ -309,36 +258,16 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
- if not provision_both_devices_for_volte(self.log, ads):
- return False
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- if not connect_both_devices_to_wifi(self.log,
- ads,
- self.wifi_network_ssid,
- self.wifi_network_pass):
- return False
-
- self.log.info("Begin In Call MMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_volte,
- verify_callee_func=None):
- return False
-
- if not _mms_test_mo(self.log, ads):
- return False
-
- if not verify_5g_attach_for_both_devices(self.log, ads):
- return False
- return True
-
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_volte',
+ mt_rat='5g_volte',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="8c795c3a-59d4-408c-9b99-5287e79ba00b")
@TelephonyBaseTest.tel_test_wrap
@@ -353,17 +282,14 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- if not disable_apm_mode_both_devices(self.log, ads):
- return False
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- return _long_mms_test_mo(self.log, ads)
-
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g',
+ mt_rat='5g',
+ msg_type='mms',
+ long_msg=True)
@test_tracker_info(uuid="e09b82ab-69a9-4eae-8cbe-b6f2cff993ad")
@TelephonyBaseTest.tel_test_wrap
@@ -379,20 +305,15 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- if not disable_apm_mode_both_devices(self.log, ads):
- return False
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
-
- return _mms_test_mo(self.log, ads)
-
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g',
+ mt_rat='general',
+ msg_type='mms',
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="fedae24f-2577-4f84-9d76-53bbbe109d48")
@TelephonyBaseTest.tel_test_wrap
@@ -408,20 +329,15 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- if not disable_apm_mode_both_devices(self.log, ads):
- return False
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
-
- return _mms_test_mt(self.log, ads)
-
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='5g',
+ msg_type='mms',
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="156bf832-acc2-4729-a69d-b471cd5cfbde")
@TelephonyBaseTest.tel_test_wrap
@@ -439,85 +355,516 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_csfb',
+ mt_rat='5g_csfb',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
- if not disable_apm_mode_both_devices(self.log, ads):
- return False
-
- if not provision_both_devices_for_csfb(self.log, ads):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not provision_both_devices_for_5g(self.log, ads):
- return False
-
- if not connect_both_devices_to_wifi(self.log,
- ads,
- self.wifi_network_ssid,
- self.wifi_network_pass):
- return False
- if not test_mms_mo_in_call(self.log,
- ads,
- wifi=True,
- caller_func=is_phone_in_call_csfb):
- return False
-
-
- @test_tracker_info(uuid="88bd6658-30fa-41b1-b5d9-0f9dadd83219")
+ @test_tracker_info(uuid="a76e4adc-ce37-47d4-9925-4ebe175f7b9c")
@TelephonyBaseTest.tel_test_wrap
- def test_5g_nsa_mms_mo_general(self):
- """Test MO MMS for 1 phone in 5g NSA. The other phone in any network
+ def test_5g_nsa_mms_mo_volte(self):
+ """Test MO MMS for 1 phone with VoLTE on 5G NSA
+ Provision PhoneA on VoLTE
Provision PhoneA in 5g NSA
Send and Verify MMS from PhoneA to PhoneB
- Verify phoneA is still on 5g NSA
+ Verify PhoneA is still on 5g NSA
Returns:
True if success.
False if failed.
"""
- ads = self.android_devices
- tasks = [(provision_device_for_5g, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- return Fals
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_volte',
+ mt_rat='default',
+ msg_type='mms')
- if not _mms_test_mo(self.log, ads):
- return False
-
- if not is_current_network_5g_nsa(ads[0]):
- return False
-
- self.log.info("PASS - MO mms test over 5g nsa validated")
- return True
-
-
- @test_tracker_info(uuid="11f2e2c8-bb63-43fa-b279-e7bb32f80596")
+ @test_tracker_info(uuid="c2282b01-e89f-49db-8925-79d38b63a373")
@TelephonyBaseTest.tel_test_wrap
- def test_5g_nsa_mms_mt_general(self):
- """Test MT MMS for 1 phone in 5g NSA. The other phone in any network
+ def test_5g_nsa_mms_mt_volte(self):
+ """Test MT MMS for 1 phone with VoLTE on 5G NSA
+ Provision PhoneA on VoLTE
Provision PhoneA in 5g NSA
Send and Verify MMS from PhoneB to PhoneA
- Verify phoneA is still on 5g NSA
+ Verify PhoneA is still on 5g NSA
Returns:
True if success.
False if failed.
"""
- ads = self.android_devices
- tasks = [(provision_device_for_5g, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_volte',
+ msg_type='mms')
+
+ @test_tracker_info(uuid="fd9bc699-940f-4a4a-abf1-31080e54ab56")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mo_in_call_volte(self):
+ """ Test MO MMS during a VoLTE call over 5G NSA.
+
+ Provision PhoneA on VoLTE
+ Provision PhoneA in 5g NSA
+ Make a Voice call from PhoneA to PhoneB
+ Send and Verify MMS from PhoneA to PhoneB
+ Verify PhoneA is still on 5g NSA
+
+ Returns:
+ True if pass; False if fail.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_volte',
+ mt_rat='default',
+ msg_type='mms',
+ msg_in_call=True)
+
+ @test_tracker_info(uuid="cfbae1e0-842a-470a-914a-a3a25a18dc81")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mt_in_call_volte(self):
+ """ Test MT MMS during a VoLTE call over 5G NSA.
+
+ Provision PhoneA on VoLTE
+ Provision PhoneA in 5g NSA
+ Make a Voice call from PhoneB to PhoneA
+ Send and Verify MMS from PhoneB to PhoneA
+ Verify PhoneA is still on 5g NSA
+
+ Returns:
+ True if pass; False if fail.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_volte',
+ msg_type='mms',
+ msg_in_call=True)
+
+ @test_tracker_info(uuid="fc8a996b-04b5-40e0-be25-cbbabf4d7957")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mo_iwlan(self):
+ """ Test MO MMS text function for 1 phone in APM,
+ WiFi connected, WFC Cell Preferred mode.
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA
+ Provision PhoneA for WFC Cell Pref with APM ON
+ Send and Verify MMS from PhoneA to PhoneB
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_wfc',
+ mt_rat='default',
+ msg_type='mms',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="7f354997-38b5-49cd-8bee-12d0589e0380")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mt_iwlan(self):
+ """ Test MT MMS text function for 1 phone in APM,
+ WiFi connected, WFC Cell Preferred mode.
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA
+ Provision PhoneA for WFC Cell Pref with APM ON
+ Send and Verify MMS from PhoneB to PhoneA
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_wfc',
+ msg_type='mms',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="592ea897-cba1-4ab5-a4ed-54ac1f8d3039")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mo_iwlan_apm_off(self):
+ """ Test MO MMS, Phone in APM off, WiFi connected, WFC WiFi Pref Mode
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA
+ Provision PhoneA for WFC Wifi Pref with APM OFF
+ Send and Verify MMS from PhoneA to PhoneB
+ Verify 5g NSA attach for PhoneA
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_wfc',
+ mt_rat='default',
+ msg_type='mms',
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="3824205d-6a36-420f-a448-51ebb30948c2")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mt_iwlan_apm_off(self):
+ """ Test MT MMS, Phone in APM off, WiFi connected, WFC WiFi Pref Mode
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA
+ Provision PhoneA for WFC Wifi Pref with APM OFF
+ Send and Verify MMS from PhoneB to PhoneA
+ Verify 5g NSA attach for PhoneA
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_wfc',
+ msg_type='mms',
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="91da5493-c810-4b1e-84f0-9d292a7b23eb")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mo_in_call_iwlan(self):
+ """ Test MO MMS, Phone in APM, WiFi connected, WFC WiFi Pref mode
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA
+ Provision PhoneA for WFC Wifi Pref with APM ON
+ Make a Voice call from PhoneA to PhoneB
+ Send and Verify MMS from PhoneA to PhoneB
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_wfc',
+ mt_rat='default',
+ msg_type='mms',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="3e6a6700-1fcb-4db1-a757-e80801032605")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mt_in_call_iwlan(self):
+ """ Test MT MMS, Phone in APM, WiFi connected, WFC WiFi Pref mode
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA
+ Provision PhoneA for WFC Wifi Pref with APM ON
+ Make a Voice call from PhoneB to PhoneA
+ Send and Verify MMS from PhoneB to PhoneA
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_wfc',
+ msg_type='mms',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="dc483cc-d7c7-4cdd-9500-4bfc4f1b5bab")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mo_in_call_volte_wifi(self):
+ """ Test MO MMS during VoLTE call and WiFi connected
+
+ Make sure PhoneA is in 5G NSA (with VoLTE).
+ Make sure PhoneA is able to make call.
+ Connect PhoneA to Wifi.
+ Call from PhoneA to PhoneB, accept on PhoneB, send MMS on PhoneA.
+ Make sure PhoneA is in 5G NSA.
+
+ Returns:
+ True if pass; False if fail.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_volte',
+ mt_rat='default',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="95472ce7-0947-4199-bb6a-8fbb189f3c5c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mt_in_call_volte_wifi(self):
+ """ Test MT MMS during VoLTE call and WiFi connected
+
+ Make sure PhoneA is in 5G NSA (with VoLTE).
+ Make sure PhoneA is able to receive call.
+ Connect PhoneA to Wifi.
+ Call from PhoneB to PhoneA, accept on PhoneA, send MMS on PhoneB.
+ Make sure PhoneA is in 5G NSA.
+
+ Returns:
+ True if pass; False if fail.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_volte',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="738e2d29-c82d-4a4a-9f4b-e8f8688151ee")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_long_message_mo(self):
+ """Test MO long MMS basic function for 1 phone in nsa 5G network.
+
+ Airplane mode is off. PhoneA in nsa 5G.
+ Send long MMS from PhoneA to PhoneB.
+ Verify received message on PhoneB is correct.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g',
+ mt_rat='default',
+ msg_type='mms',
+ long_msg=True)
+
+ @test_tracker_info(uuid="68f4f0d6-b798-4d0b-9500-ce49f009b61a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_long_message_mt(self):
+ """Test MT long MMS basic function for 1 phone in nsa 5G network.
+
+ Airplane mode is off. PhoneA in nsa 5G.
+ Send long MMS from PhoneB to PhoneA.
+ Verify received message on PhoneA is correct.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g',
+ msg_type='mms',
+ long_msg=True)
+
+ @test_tracker_info(uuid="a379fac4-1aa6-46e0-8cef-6d2452702e04")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mo_in_call_csfb_wifi(self):
+ """ Test MO MMS during a MO csfb call and device connects to Wifi.
+
+ Disable APM on PhoneA
+ Set up PhoneA in CSFB mode.
+ Provision PhoneA in 5g NSA.
+ Make sure PhoneA is able to make call.
+ Connect PhoneA to Wifi.
+ Call from PhoneA to PhoneB, accept on PhoneB, send MMS on PhoneA,
+ receive MMS on B.
+
+ Returns:
+ True if pass; False if fail.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_csfb',
+ mt_rat='default',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="1a6543b1-b7d6-4260-8276-88aee649c4b2")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_mt_in_call_csfb_wifi(self):
+ """ Test MT MMS during a MT csfb call and device connects to Wifi.
+
+ Disable APM on PhoneA
+ Set up PhoneA is CSFB mode.
+ Provision PhoneA in 5g NSA.
+ Make sure PhoneA is able to receive call.
+ Connect PhoneA to Wifi.
+ Call from PhoneB to PhoneA, accept on PhoneA, send MMS on PhoneB,
+ receive MMS on A.
+
+ Returns:
+ True if pass; False if fail.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_csfb',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+ @test_tracker_info(uuid="536c8e25-2d72-46a6-89e1-03f70c5a28a3")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_multiple_pdns_mo(self):
+ """Test 5G NSA for multiple pdns
+
+ Steps:
+ (1) UE supports EN-DC option 3.
+ (2) SIM with 5G service.
+ (3) UE is provisioned for 5G service and powered off.
+ (4) NR cell (Cell 2) that is within the coverage of LTE cell (Cell 1).
+ (5) UE is in near cell coverage for LTE (Cell 1) and NR (Cell 2).
+ (6) Power on the UE.
+ (7) Initiate data transfer while UE is in idle mode.
+ (8) During data transferring, send a MO MMS.
+ (9) End the data transfer
+
+ Returns:
+ True if pass; False if fail.
+ """
+ cell_1 = self.android_devices[0]
+ cell_2 = self.android_devices[1]
+ if not phone_setup_volte(self.log, cell_1):
+ cell_1.log.error("Failed to setup on VoLTE")
return False
- if not _mms_test_mt(self.log, ads):
+ if not verify_internet_connection(self.log, cell_1):
+ return False
+ if not provision_device_for_5g(self.log, cell_2, nr_type='nsa'):
+ cell_2.log.error("Failed to setup on 5G NSA")
+ return False
+ if not verify_internet_connection(self.log, cell_2):
+ return False
+ if not active_file_download_task(self.log, cell_2):
+ return False
+ download_task = active_file_download_task(self.log, cell_2, "10MB")
+ message_task = (message_test, (self.log, cell_2, cell_1,
+ '5g', 'volte', 'mms'))
+ results = run_multithread_func(self.log, [download_task, message_task])
+
+ if ((results[0]) & (results[1])):
+ self.log.info("PASS - MO MMS test validated over active data transfer")
+ elif ((results[0] == False) & (results[1] == True)):
+ self.log.error("FAIL - Data Transfer failed")
+ elif ((results[0] == True) & (results[1] == False)):
+ self.log.error("FAIL - Sending MMS failed")
+ else:
+ self.log.error("FAILED - MO MMS test over active data transfer")
+
+ return results
+
+ @test_tracker_info(uuid="10212ab7-a03f-4e11-889e-236b8d1d8afc")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mms_multiple_pdns_mt(self):
+ """Test 5G NSA for multiple pdns
+
+ Steps:
+ (1) UE supports EN-DC option 3.
+ (2) SIM with 5G service.
+ (3) UE is provisioned for 5G service and powered off.
+ (4) NR cell (Cell 2) that is within the coverage of LTE cell (Cell 1).
+ (5) UE is in near cell coverage for LTE (Cell 1) and NR (Cell 2).
+ (6) Power on the UE.
+ (7) Initiate data transfer while UE is in idle mode.
+ (8) During data transferring, send a MT MMS.
+ (9) End the data transfer.
+
+ Returns:
+ True if pass; False if fail.
+ """
+ cell_1 = self.android_devices[0]
+ cell_2 = self.android_devices[1]
+
+ if not phone_setup_volte(self.log, cell_1):
+ cell_1.log.error("Failed to setup on VoLTE")
+ return False
+ if not verify_internet_connection(self.log, cell_1):
+ return False
+ if not provision_device_for_5g(self.log, cell_2, nr_type='nsa'):
+ cell_2.log.error("Failed to setup on 5G NSA")
+ return False
+ if not verify_internet_connection(self.log, cell_2):
+ return False
+ if not active_file_download_task(self.log, cell_2):
return False
- if not is_current_network_5g_nsa(ads[0]):
- return False
+ download_task = active_file_download_task(self.log, cell_2, "10MB")
+ message_task = (message_test, (self.log, cell_1, cell_2,
+ 'volte', '5g', 'mms'))
+ results = run_multithread_func(self.log, [download_task, message_task])
- self.log.info("PASS - MT mms test over 5g nsa validated")
- return True
+ if ((results[0]) & (results[1])):
+ self.log.info("PASS - MT MMS test validated over active data transfer")
+ elif ((results[0] == False) & (results[1] == True)):
+ self.log.error("FAIL - Data Transfer failed")
+ elif ((results[0] == True) & (results[1] == False)):
+ self.log.error("FAIL - Sending MMS failed")
+ else:
+ self.log.error("FAILED - MT MMS test over active data transfer")
+
+ return results
""" Tests End """
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gSmsTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gSmsTest.py
index 26ab60a..f1df4f4 100755
--- a/acts_tests/tests/google/nr/nsa5g/Nsa5gSmsTest.py
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gSmsTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3.4
#
-# Copyright 2020 - Google
+# Copyright 2022 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -18,41 +18,35 @@
"""
import time
-from acts.utils import rand_ascii_str
+
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_default_state
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_5g_test_utils import disable_apm_mode_both_devices
from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_both_devices_for_volte
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_both_devices_for_wfc_cell_pref
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_both_devices_for_wfc_wifi_pref
-from acts_contrib.test_utils.tel.tel_5g_test_utils import verify_5g_attach_for_both_devices
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_both_devices_for_csfb
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g_nsa
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_nsa
-from acts_contrib.test_utils.tel.tel_sms_utils import _sms_test_mo
-from acts_contrib.test_utils.tel.tel_sms_utils import _sms_test_mt
-from acts_contrib.test_utils.tel.tel_sms_utils import _long_sms_test_mo
-from acts_contrib.test_utils.tel.tel_sms_utils import test_sms_mo_in_call
+from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_task
+from acts_contrib.test_utils.tel.tel_message_utils import message_test
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_test_utils import install_message_apk
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
+from acts.libs.utils.multithread import run_multithread_func
class Nsa5gSmsTest(TelephonyBaseTest):
def setup_class(self):
super().setup_class()
+ self.message_util = self.user_params.get("message_apk", None)
+ if isinstance(self.message_util, list):
+ self.message_util = self.message_util[0]
+
+ if self.message_util:
+ ads = self.android_devices
+ for ad in ads:
+ install_message_apk(ad, self.message_util)
+
def setup_test(self):
TelephonyBaseTest.setup_test(self)
@@ -61,8 +55,6 @@
""" Tests Begin """
-
-
@test_tracker_info(uuid="4a64a262-7433-4a7f-b5c6-a36ff60aeaa2")
@TelephonyBaseTest.tel_test_wrap
def test_5g_nsa_sms_mo_mt(self):
@@ -76,19 +68,12 @@
True if success.
False if failed.
"""
- ads = self.android_devices
- if not provision_device_for_5g(self.log, ads):
- return False
-
- if not _sms_test_mo(self.log, ads):
- return False
-
- if not verify_5g_attach_for_both_devices(self.log, ads):
- return False
-
- self.log.info("PASS - SMS test over 5G NSA validated")
- return True
-
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g',
+ mt_rat='5g')
@test_tracker_info(uuid="52b16764-0c9e-45c0-910f-a39d17c7cf7e")
@TelephonyBaseTest.tel_test_wrap
@@ -103,22 +88,12 @@
True if success.
False if failed.
"""
- ads = self.android_devices
-
- tasks = [(provision_device_for_5g, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- return False
-
- if not _sms_test_mo(self.log, ads):
- return False
-
- if not is_current_network_5g_nsa(ads[0]):
- return False
-
- self.log.info("PASS - MO SMS test over 5G NSA validated")
- return True
-
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g',
+ mt_rat='default')
@test_tracker_info(uuid="e9b2494a-0e40-449c-b877-1e4ddc78c536")
@TelephonyBaseTest.tel_test_wrap
@@ -133,22 +108,12 @@
True if success.
False if failed.
"""
- ads = self.android_devices
-
- tasks = [(provision_device_for_5g, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- return False
-
- if not _sms_test_mt(self.log, ads):
- return False
-
- if not is_current_network_5g_nsa(ads[0]):
- return False
-
- self.log.info("PASS - MT SMS test over 5G NSA validated")
- return True
-
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g')
@test_tracker_info(uuid="2ce809d4-cbf6-4233-81ad-43f91107b201")
@TelephonyBaseTest.tel_test_wrap
@@ -164,27 +129,12 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
- if not provision_both_devices_for_volte(self.log, ads):
- return False
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- if not _sms_test_mo(self.log, ads):
- return False
-
- if not hangup_call(self.log, ads[0]):
- ads[0].log.info("Failed to hang up call.!")
- return False
-
- if not verify_5g_attach_for_both_devices(self.log, ads):
- return False
-
- self.log.info("PASS - VoLTE SMS test over 5G NSA validated")
- return True
-
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_volte',
+ mt_rat='5g_volte')
@test_tracker_info(uuid="e51f3dbb-bb16-4400-b2be-f9422f511087")
@TelephonyBaseTest.tel_test_wrap
@@ -200,25 +150,12 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
- if not phone_setup_volte(self.log, ads[0]):
- return False
-
- tasks = [(provision_device_for_5g, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- return False
-
- if not _sms_test_mo(self.log, ads):
- return False
-
- if not is_current_network_5g_nsa(ads[0]):
- return False
-
- self.log.info("PASS - MO VoLTE SMS test over 5G NSA validated")
- return True
-
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_volte',
+ mt_rat='default')
@test_tracker_info(uuid="5217d427-04a2-4b2b-9ed8-28951e71fc21")
@TelephonyBaseTest.tel_test_wrap
@@ -234,25 +171,12 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
- if not phone_setup_volte(self.log, ads[0]):
- return False
-
- tasks = [(provision_device_for_5g, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- return False
-
- if not _sms_test_mt(self.log, ads):
- return False
-
- if not is_current_network_5g_nsa(ads[0]):
- return False
-
- self.log.info("PASS - MT VoLTE SMS test over 5G NSA validated")
- return True
-
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_volte')
@test_tracker_info(uuid="49bfb4b3-a6ec-45d4-ad96-09282fb07d1d")
@TelephonyBaseTest.tel_test_wrap
@@ -268,23 +192,13 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
- if not provision_both_devices_for_volte(self.log, ads):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- if not test_sms_mo_in_call(self.log,
- ads,
- caller_func=is_phone_in_call_volte):
- return False
-
- if not verify_5g_attach_for_both_devices(self.log, ads):
- return False
- return True
-
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_volte',
+ mt_rat='5g_volte',
+ msg_in_call=True)
@test_tracker_info(uuid="3d5c8f60-1eaa-4f4a-b539-c529fa36db91")
@TelephonyBaseTest.tel_test_wrap
@@ -300,25 +214,13 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
- if not phone_setup_volte(self.log, ads[0]):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- tasks = [(provision_device_for_5g, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- return False
-
- if not test_sms_mo_in_call(self.log,
- ads,
- caller_func=is_phone_in_call_volte):
- return False
-
- if not is_current_network_5g_nsa(ads[0]):
- return False
- return True
-
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_volte',
+ mt_rat='default',
+ msg_in_call=True)
@test_tracker_info(uuid="c71813f3-bb04-4115-8519-e23046349689")
@TelephonyBaseTest.tel_test_wrap
@@ -334,25 +236,13 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
- if not phone_setup_volte(self.log, ads[0]):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- tasks = [(provision_device_for_5g, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- return False
-
- if not test_sms_mo_in_call(self.log,
- [ads[1], ads[0]],
- callee_func=is_phone_in_call_volte):
- return False
-
- if not is_current_network_5g_nsa(ads[0]):
- return False
- return True
-
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_volte',
+ msg_in_call=True)
@test_tracker_info(uuid="1f914d5c-ac24-4794-9fcb-cb28e483d69a")
@TelephonyBaseTest.tel_test_wrap
@@ -368,28 +258,69 @@
Returns:
True if pass; False if fail.
"""
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_wfc',
+ mt_rat='5g_wfc',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
- ads = self.android_devices
- if not disable_apm_mode_both_devices(self.log, ads):
- return False
+ @test_tracker_info(uuid="2d375f20-a785-42e0-b5a1-968d19bc693d")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_sms_mo_iwlan(self):
+ """ Test MO SMS for 1 phone in APM,
+ WiFi connected, WFC Cell Preferred mode.
- if not provision_device_for_5g(self.log, ads):
- return False
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA
+ Provision PhoneA for WFC Cell Pref with APM ON
+ Send and Verify SMS from PhoneA to PhoneB
- if not provision_both_devices_for_wfc_cell_pref(self.log,
- ads,
- self.wifi_network_ssid,
- self.wifi_network_pass,
- apm_mode=True):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_wfc',
+ mt_rat='general',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
- if not _sms_test_mo(self.log, ads):
- return False
+ @test_tracker_info(uuid="db8b2b5b-bf9e-4a99-9fdb-dbd028567705")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_sms_mt_iwlan(self):
+ """ Test MT SMS for 1 phone in APM,
+ WiFi connected, WFC Cell Preferred mode.
- self.log.info("PASS - iwlan sms test over 5g nsa validated")
- return True
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA
+ Provision PhoneA for WFC Cell Pref with APM ON
+ Send and Verify SMS from PhoneB to PhoneA
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='5g_wfc',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="7274be32-b9dd-4ce3-83d1-f32ab14ce05e")
@TelephonyBaseTest.tel_test_wrap
@@ -405,31 +336,68 @@
Returns:
True if pass; False if fail.
"""
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_wfc',
+ mt_rat='5g_wfc',
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
- ads = self.android_devices
- if not disable_apm_mode_both_devices(self.log, ads):
- return False
+ @test_tracker_info(uuid="5997a618-efee-478f-8fa9-6cf8ba9cfc58")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_sms_mo_iwlan_apm_off(self):
+ """ Test MO SMS for 1 Phone in APM off, WiFi connected,
+ WFC WiFi Preferred mode.
- if not provision_device_for_5g(self.log, ads):
- return False
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA
+ Provision PhoneA for WFC Wifi Pref with APM OFF
+ Send and Verify SMS from PhoneA to PhoneB
+ Verify 5g NSA attach for PhoneA
- if not provision_both_devices_for_wfc_wifi_pref(self.log,
- ads,
- self.wifi_network_ssid,
- self.wifi_network_pass,
- apm_mode=False):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_wfc',
+ mt_rat='general',
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
- if not _sms_test_mo(self.log, ads):
- self.log.error("failed to send receive sms over 5g nsa")
- return False
- self.log.info("PASS - iwlan sms test over 5g nsa validated")
+ @test_tracker_info(uuid="352ca023-2cd1-4b08-877c-20c5d50cc265")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_sms_mt_iwlan_apm_off(self):
+ """ Test MT SMS for 1 Phone in APM off, WiFi connected,
+ WFC WiFi Preferred mode.
- if not verify_5g_attach_for_both_devices(self.log, ads):
- return False
- return True
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA
+ Provision PhoneA for WFC Wifi Pref with APM OFF
+ Send and Verify SMS from PhoneB to PhoneA
+ Verify 5g NSA attach for PhoneA
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='5g_wfc',
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="2d1787f2-d6fe-4b41-b389-2a8f817594e4")
@TelephonyBaseTest.tel_test_wrap
@@ -445,27 +413,18 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- if not disable_apm_mode_both_devices(self.log, ads):
- return False
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- if not provision_both_devices_for_wfc_wifi_pref(self.log,
- ads,
- self.wifi_network_ssid,
- self.wifi_network_pass,
- apm_mode=True):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return test_sms_mo_in_call(self.log,
- ads,
- caller_func=is_phone_in_call_iwlan)
-
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_wfc',
+ mt_rat='5g_wfc',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="784062e8-02a4-49ce-8fc1-5359ab40bbdd")
@TelephonyBaseTest.tel_test_wrap
@@ -480,17 +439,13 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- if not disable_apm_mode_both_devices(self.log, ads):
- return False
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- return _long_sms_test_mo(self.log, ads)
-
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g',
+ mt_rat='5g',
+ long_msg=True)
@test_tracker_info(uuid="45dbd61a-6a90-473e-9cfa-03e2408d5f15")
@TelephonyBaseTest.tel_test_wrap
@@ -507,188 +462,259 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_csfb',
+ mt_rat='5g_csfb',
+ msg_in_call=True)
- if not disable_apm_mode_both_devices(self.log, ads):
- return False
-
- if not provision_both_devices_for_csfb(self.log, ads):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not provision_device_for_5g_nsa(self.log, ads):
- return False
-
- return test_sms_mo_in_call(self.log,
- ads,
- caller_func=is_phone_in_call_csfb)
-
-
- @test_tracker_info(uuid="2d375f20-a785-42e0-b5a1-968d19bc693d")
+ @test_tracker_info(uuid="709d5322-3da3-4c77-9180-281bc54ad78e")
@TelephonyBaseTest.tel_test_wrap
- def test_5g_nsa_sms_mo_iwlan(self):
- """ Test MO SMS for 1 phone in APM,
- WiFi connected, WFC Cell Preferred mode.
+ def test_5g_nsa_sms_mo_in_call_iwlan(self):
+ """ Test MO SMS for 1 Phone in APM, WiFi connected,
+ WFC WiFi Preferred mode.
- Disable APM on PhoneA
+ Disable APM on both devices
Provision PhoneA in 5g NSA
- Provision PhoneA for WFC Cell Pref with APM ON
+ Provision PhoneA for WFC Wifi Pref with APM ON
+ Make a Voice call from PhoneA to PhoneB
Send and Verify SMS from PhoneA to PhoneB
Returns:
True if pass; False if fail.
"""
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_wfc',
+ mt_rat='default',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
- ads = self.android_devices
- if not toggle_airplane_mode(self.log, ads[0], False):
- return False
-
- tasks = [(provision_device_for_5g, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- return False
-
- if not phone_setup_iwlan(self.log,
- ads[0],
- True,
- WFC_MODE_CELLULAR_PREFERRED,
- self.wifi_network_ssid,
- self.wifi_network_pass):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not _sms_test_mo(self.log, ads):
- return False
-
- self.log.info("PASS - iwlan mo sms test over 5g nsa validated")
- return True
-
-
- @test_tracker_info(uuid="db8b2b5b-bf9e-4a99-9fdb-dbd028567705")
+ @test_tracker_info(uuid="6af38572-bbf7-4c11-8f0c-ab2f9b25ac49")
@TelephonyBaseTest.tel_test_wrap
- def test_5g_nsa_sms_mt_iwlan(self):
- """ Test MT SMS for 1 phone in APM,
- WiFi connected, WFC Cell Preferred mode.
+ def test_5g_nsa_sms_mt_in_call_iwlan(self):
+ """ Test MT SMS for 1 Phone in APM, WiFi connected,
+ WFC WiFi Preferred mode.
- Disable APM on PhoneA
+ Disable APM on both devices
Provision PhoneA in 5g NSA
- Provision PhoneA for WFC Cell Pref with APM ON
+ Provision PhoneA for WFC Wifi Pref with APM ON
+ Make a Voice call from PhoneB to PhoneA
Send and Verify SMS from PhoneB to PhoneA
Returns:
True if pass; False if fail.
"""
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_wfc',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
- ads = self.android_devices
- if not toggle_airplane_mode(self.log, ads[0], False):
- return False
-
- tasks = [(provision_device_for_5g, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- return False
-
- if not phone_setup_iwlan(self.log,
- ads[0],
- True,
- WFC_MODE_CELLULAR_PREFERRED,
- self.wifi_network_ssid,
- self.wifi_network_pass):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not _sms_test_mo(self.log, [ads[1], ads[0]]):
- return False
-
- self.log.info("PASS - iwlan mt sms test over 5g nsa validated")
- return True
-
-
- @test_tracker_info(uuid="5997a618-efee-478f-8fa9-6cf8ba9cfc58")
+ @test_tracker_info(uuid="1437adb8-dfb0-49fb-8ecc-b456f60d7f64")
@TelephonyBaseTest.tel_test_wrap
- def test_5g_nsa_sms_mo_iwlan_apm_off(self):
- """ Test MO SMS for 1 Phone in APM off, WiFi connected,
- WFC WiFi Preferred mode.
+ def test_5g_nsa_sms_long_message_mo(self):
+ """Test MO long SMS function for 1 phone in nsa 5G network.
Disable APM on PhoneA
Provision PhoneA in 5g NSA
- Provision PhoneA for WFC Wifi Pref with APM OFF
- Send and Verify SMS from PhoneA to PhoneB
- Verify 5g NSA attach for PhoneA
+ Send SMS from PhoneA to PhoneB
+ Verify received message on PhoneB is correct
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g',
+ mt_rat='default',
+ long_msg=True)
+
+ @test_tracker_info(uuid="d34a4840-d1fa-46f1-885b-f67456225f50")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_sms_long_message_mt(self):
+ """Test MT long SMS function for 1 phone in nsa 5G network.
+
+ Disable APM on PhoneA
+ Provision PhoneA in 5g NSA
+ Send SMS from PhoneB to PhoneA
+ Verify received message on PhoneA is correct
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g',
+ long_msg=True)
+
+ @test_tracker_info(uuid="84e40f15-1d02-44b0-8103-f25f73dae7a1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_sms_mo_in_call_csfb(self):
+ """ Test MO SMS during a MO csfb call over 5G NSA.
+
+ Disable APM on PhoneA
+ Set up PhoneA are in CSFB mode.
+ Provision PhoneA in 5g NSA.
+ Make sure PhoneA is able to make call.
+ Call from PhoneA to PhoneB, accept on PhoneB, send SMS on PhoneA,
+ receive SMS on PhoneB.
Returns:
True if pass; False if fail.
"""
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_csfb',
+ mt_rat='default',
+ msg_in_call=True)
- ads = self.android_devices
- if not toggle_airplane_mode(self.log, ads[0], False):
- return False
-
- tasks = [(provision_device_for_5g, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- return False
-
- if not phone_setup_iwlan(self.log,
- ads[0],
- False,
- WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid,
- self.wifi_network_pass):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not _sms_test_mo(self.log, ads):
- self.log.error("failed to send receive sms over 5g nsa")
- return False
- self.log.info("PASS - iwlan MO sms test over 5g nsa validated")
-
- if not is_current_network_5g_nsa(ads[0]):
- return False
- return True
-
-
- @test_tracker_info(uuid="352ca023-2cd1-4b08-877c-20c5d50cc265")
+ @test_tracker_info(uuid="259ccd94-2d70-450e-adf4-949889096cce")
@TelephonyBaseTest.tel_test_wrap
- def test_5g_nsa_sms_mt_iwlan_apm_off(self):
- """ Test MT SMS for 1 Phone in APM off, WiFi connected,
- WFC WiFi Preferred mode.
+ def test_5g_nsa_sms_mt_in_call_csfb(self):
+ """ Test MT SMS during a MT csfb call over 5G NSA.
Disable APM on PhoneA
- Provision PhoneA in 5g NSA
- Provision PhoneA for WFC Wifi Pref with APM OFF
- Send and Verify SMS from PhoneB to PhoneA
- Verify 5g NSA attach for PhoneA
+ Set up PhoneA are in CSFB mode.
+ Provision PhoneA in 5g NSA.
+ Make sure PhoneA is able to receive call.
+ Call from PhoneB to PhoneA, accept on PhoneA, send SMS on PhoneB,
+ receive SMS on PhoneA.
Returns:
True if pass; False if fail.
"""
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_csfb',
+ msg_in_call=True)
- ads = self.android_devices
- if not toggle_airplane_mode(self.log, ads[0], False):
+ @test_tracker_info(uuid="303d5c2f-15bd-4608-96b8-37d16341004e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_sms_multiple_pdns_mo(self):
+ """Test 5G NSA for multiple pdns
+
+ Steps:
+ (1) UE supports EN-DC option 3.
+ (2) SIM with 5G service.
+ (3) UE is provisioned for 5G service and powered off.
+ (4) NR cell (Cell 2) that is within the coverage of LTE cell (Cell 1).
+ (5) UE is in near cell coverage for LTE (Cell 1) and NR (Cell 2).
+ (6) Power on the UE.
+ (7) Initiate data transfer while UE is in idle mode.
+ (8) During data transferring, send a MO SMS.
+ (9) End the data transfer
+
+ Returns:
+ True if pass; False if fail.
+ """
+ cell_1 = self.android_devices[0]
+ cell_2 = self.android_devices[1]
+ if not phone_setup_volte(self.log, cell_1):
+ cell_1.log.error("Failed to setup on VoLTE")
return False
- tasks = [(provision_device_for_5g, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
+ if not verify_internet_connection(self.log, cell_1):
+ return False
+ if not provision_device_for_5g(self.log, cell_2, nr_type='nsa'):
+ cell_2.log.error("Failed to setup on 5G NSA")
+ return False
+ if not verify_internet_connection(self.log, cell_2):
+ return False
+ if not active_file_download_task(self.log, cell_2):
+ return False
+ download_task = active_file_download_task(self.log, cell_2, "10MB")
+ message_task = (message_test, (self.log, cell_2, cell_1,
+ '5g', 'volte', 'sms'))
+ results = run_multithread_func(self.log, [download_task, message_task])
+
+ if ((results[0]) & (results[1])):
+ self.log.info("PASS - MO SMS test validated over active data transfer")
+ elif ((results[0] == False) & (results[1] == True)):
+ self.log.error("FAIL - Data Transfer failed")
+ elif ((results[0] == True) & (results[1] == False)):
+ self.log.error("FAIL - Sending SMS failed")
+ else:
+ self.log.error("FAILED - MO SMS test over active data transfer")
+
+ return results
+
+ @test_tracker_info(uuid="cc9d2b46-80cc-47a8-926b-3ccf8095cefb")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_sms_multiple_pdns_mt(self):
+ """Test 5G NSA for multiple pdns
+
+ Steps:
+ (1) UE supports EN-DC option 3.
+ (2) SIM with 5G service.
+ (3) UE is provisioned for 5G service and powered off.
+ (4) NR cell (Cell 2) that is within the coverage of LTE cell (Cell 1).
+ (5) UE is in near cell coverage for LTE (Cell 1) and NR (Cell 2).
+ (6) Power on the UE.
+ (7) Initiate data transfer while UE is in idle mode.
+ (8) During data transferring, send a MT SMS.
+ (9) End the data transfer.
+
+ Returns:
+ True if pass; False if fail.
+ """
+ cell_1 = self.android_devices[0]
+ cell_2 = self.android_devices[1]
+
+ if not phone_setup_volte(self.log, cell_1):
+ cell_1.log.error("Failed to setup on VoLTE")
+ return False
+ if not verify_internet_connection(self.log, cell_1):
+ return False
+ if not provision_device_for_5g(self.log, cell_2, nr_type='nsa'):
+ cell_2.log.error("Failed to setup on 5G NSA")
+ return False
+ if not verify_internet_connection(self.log, cell_2):
+ return False
+ if not active_file_download_task(self.log, cell_2):
return False
- if not phone_setup_iwlan(self.log,
- ads[0],
- False,
- WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid,
- self.wifi_network_pass):
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+ download_task = active_file_download_task(self.log, cell_2, "10MB")
+ message_task = (message_test, (self.log, cell_1, cell_2,
+ 'volte', '5g', 'sms'))
+ results = run_multithread_func(self.log, [download_task, message_task])
- if not _sms_test_mt(self.log, ads):
- self.log.error("failed to send receive sms over 5g nsa")
- return False
- self.log.info("PASS - iwlan MT sms test over 5g nsa validated")
+ if ((results[0]) & (results[1])):
+ self.log.info("PASS - MT SMS test validated over active data transfer")
+ elif ((results[0] == False) & (results[1] == True)):
+ self.log.error("FAIL - Data Transfer failed")
+ elif ((results[0] == True) & (results[1] == False)):
+ self.log.error("FAIL - Sending SMS failed")
+ else:
+ self.log.error("FAILED - MT SMS test over active data transfer")
- if not is_current_network_5g_nsa(ads[0]):
- return False
- return True
+ return results
""" Tests End """
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gTetheringTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gTetheringTest.py
index 2558d89..4f43881 100755
--- a/acts_tests/tests/google/nr/nsa5g/Nsa5gTetheringTest.py
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gTetheringTest.py
@@ -20,8 +20,6 @@
import time
from acts.utils import rand_ascii_str
-from acts.utils import enable_doze
-from acts.utils import disable_doze
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
@@ -32,15 +30,15 @@
from acts_contrib.test_utils.tel.tel_defines import TETHERING_PASSWORD_HAS_ESCAPE
from acts_contrib.test_utils.tel.tel_defines import TETHERING_SPECIAL_SSID_LIST
from acts_contrib.test_utils.tel.tel_defines import TETHERING_SPECIAL_PASSWORD_LIST
-from acts_contrib.test_utils.tel.tel_defines import \
- WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING
+from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from acts_contrib.test_utils.tel.tel_bt_utils import verify_bluetooth_tethering_connection
from acts_contrib.test_utils.tel.tel_data_utils import run_stress_test
from acts_contrib.test_utils.tel.tel_data_utils import test_wifi_tethering
from acts_contrib.test_utils.tel.tel_data_utils import test_setup_tethering
from acts_contrib.test_utils.tel.tel_data_utils import test_start_wifi_tethering_connect_teardown
from acts_contrib.test_utils.tel.tel_data_utils import test_tethering_wifi_and_voice_call
from acts_contrib.test_utils.tel.tel_data_utils import tethering_check_internet_connection
-from acts_contrib.test_utils.tel.tel_data_utils import verify_bluetooth_tethering_connection
from acts_contrib.test_utils.tel.tel_data_utils import verify_toggle_apm_tethering_internet_connection
from acts_contrib.test_utils.tel.tel_data_utils import verify_tethering_entitlement_check
from acts_contrib.test_utils.tel.tel_data_utils import wifi_tethering_cleanup
@@ -51,19 +49,18 @@
from acts_contrib.test_utils.tel.tel_data_utils import setup_device_internet_connection_then_reboot
from acts_contrib.test_utils.tel.tel_data_utils import verify_internet_connection_in_doze_mode
from acts_contrib.test_utils.tel.tel_data_utils import verify_toggle_data_during_wifi_tethering
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_generation
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_default_state
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_default_state
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_reset
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_reset
class Nsa5gTetheringTest(TelephonyBaseTest):
@@ -104,7 +101,8 @@
RAT_5G,
WIFI_CONFIG_APBAND_5G,
check_interval=10,
- check_iteration=10)
+ check_iteration=10,
+ nr_type= 'nsa')
@test_tracker_info(uuid="0af10a6b-7c01-41fd-95ce-d839a787aa98")
@@ -128,7 +126,8 @@
RAT_5G,
WIFI_CONFIG_APBAND_2G,
check_interval=10,
- check_iteration=10)
+ check_iteration=10,
+ nr_type= 'nsa')
@test_tracker_info(uuid="d7ab31d5-5f96-4b48-aa92-810e6cfcf845")
@@ -158,7 +157,8 @@
check_interval=10,
check_iteration=2,
do_cleanup=False,
- ssid=ssid):
+ ssid=ssid,
+ nr_type= 'nsa'):
self.log.error("WiFi Tethering failed.")
return False
@@ -191,7 +191,8 @@
if not verify_toggle_data_during_wifi_tethering(self.log,
self.provider,
self.clients,
- new_gen=RAT_5G):
+ new_gen=RAT_5G,
+ nr_type= 'nsa'):
return False
return True
@@ -206,7 +207,7 @@
True if entitlement check returns True.
"""
- if not provision_device_for_5g(self.log, self.provider):
+ if not provision_device_for_5g(self.log, self.provider, nr_type= 'nsa'):
return False
return verify_tethering_entitlement_check(self.log,
self.provider)
@@ -235,7 +236,8 @@
RAT_5G,
WIFI_CONFIG_APBAND_2G,
check_interval=10,
- check_iteration=10)
+ check_iteration=10,
+ nr_type= 'nsa')
return run_stress_test(self.log, self.stress_test_number, precondition, test_case)
@@ -263,7 +265,8 @@
WIFI_CONFIG_APBAND_2G,
check_interval=10,
check_iteration=10,
- ssid=ssid)
+ ssid=ssid,
+ nr_type= 'nsa')
@test_tracker_info(uuid="678c6b04-6733-41e1-bb0c-af8c9d1183cb")
@@ -292,7 +295,8 @@
WIFI_CONFIG_APBAND_2G,
check_interval=10,
check_iteration=10,
- password=password)
+ password=password,
+ nr_type= 'nsa')
@test_tracker_info(uuid="eacc5412-fe75-400b-aba9-c0c38bdfff71")
@@ -307,7 +311,11 @@
True if WiFi tethering succeed on all SSIDs.
False if failed.
"""
- if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G):
+ if not test_setup_tethering(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ nr_type='nsa'):
self.log.error("Setup Failed.")
return False
ssid_list = TETHERING_SPECIAL_SSID_LIST
@@ -342,7 +350,11 @@
True if WiFi tethering succeed on all passwords.
False if failed.
"""
- if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G):
+ if not test_setup_tethering(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ nr_type='nsa'):
self.log.error("Setup Failed.")
return False
password_list = TETHERING_SPECIAL_PASSWORD_LIST
@@ -381,11 +393,17 @@
True if success.
False if failed.
"""
- if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G):
+ if not test_setup_tethering(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ nr_type='nsa'):
self.log.error("Verify 5G Internet access failed.")
return False
- return verify_bluetooth_tethering_connection(self.log, self.provider, self.clients)
+ return verify_bluetooth_tethering_connection(self.log,
+ self.provider,
+ self.clients)
@test_tracker_info(uuid="db70c6ec-5edc-44c2-b61b-1c39516a7475")
@@ -404,12 +422,20 @@
True if success.
False if failed.
"""
- if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G):
+ if not test_setup_tethering(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ nr_type='nsa'):
self.log.error("Verify 5G Internet access failed.")
return False
- return verify_bluetooth_tethering_connection(self.log, self.provider, self.clients,
- toggle_tethering=False, toggle_bluetooth=False, voice_call=True)
+ return verify_bluetooth_tethering_connection(self.log,
+ self.provider,
+ self.clients,
+ toggle_tethering=False,
+ toggle_bluetooth=False,
+ voice_call=True)
@test_tracker_info(uuid="12efb94f-7466-40e9-9a79-59b4074ab4dd")
@@ -428,12 +454,20 @@
True if success.
False if failed.
"""
- if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G):
+ if not test_setup_tethering(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ nr_type='nsa'):
self.log.error("Verify 5G Internet access failed.")
return False
- return verify_bluetooth_tethering_connection(self.log, self.provider, self.clients,
- toggle_tethering=False, toggle_bluetooth=False, toggle_data=True)
+ return verify_bluetooth_tethering_connection(self.log,
+ self.provider,
+ self.clients,
+ toggle_tethering=False,
+ toggle_bluetooth=False,
+ toggle_data=True)
@test_tracker_info(uuid="475b485a-1228-4f18-b9f2-593f96850165")
@@ -452,12 +486,20 @@
True if success.
False if failed.
"""
- if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G):
+ if not test_setup_tethering(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ nr_type='nsa'):
self.log.error("Verify 5G Internet access failed.")
return False
- return verify_bluetooth_tethering_connection(self.log, self.provider, self.clients,
- toggle_tethering=True, toggle_bluetooth=False, toggle_data=False)
+ return verify_bluetooth_tethering_connection(self.log,
+ self.provider,
+ self.clients,
+ toggle_tethering=True,
+ toggle_bluetooth=False,
+ toggle_data=False)
@test_tracker_info(uuid="07f8e523-b471-4156-b057-558123973a5b")
@@ -476,15 +518,21 @@
True if success.
False if failed.
"""
- if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G):
+ if not test_setup_tethering(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ nr_type='nsa'):
self.log.error("Verify 5G Internet access failed.")
return False
- return verify_bluetooth_tethering_connection(self.log, self.provider, self.clients,
- toggle_tethering=False,
- toggle_bluetooth=False,
- toggle_data=False,
- change_rat=RAT_4G)
+ return verify_bluetooth_tethering_connection(self.log,
+ self.provider,
+ self.clients,
+ toggle_tethering=False,
+ toggle_bluetooth=False,
+ toggle_data=False,
+ change_rat=RAT_4G)
@test_tracker_info(uuid="93040a69-fa85-431f-ac9d-80091c6c8223")
@@ -503,15 +551,21 @@
True if success.
False if failed.
"""
- if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G):
+ if not test_setup_tethering(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ nr_type='nsa'):
self.log.error("Verify 5G Internet access failed.")
return False
- return verify_bluetooth_tethering_connection(self.log, self.provider, self.clients,
- toggle_tethering=False,
- toggle_bluetooth=False,
- toggle_data=False,
- change_rat=RAT_3G)
+ return verify_bluetooth_tethering_connection(self.log,
+ self.provider,
+ self.clients,
+ toggle_tethering=False,
+ toggle_bluetooth=False,
+ toggle_data=False,
+ change_rat=RAT_3G)
@test_tracker_info(uuid="6cc17fc7-13a0-4493-9673-920952a16fcc")
@@ -530,15 +584,21 @@
True if success.
False if failed.
"""
- if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G):
+ if not test_setup_tethering(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ nr_type='nsa'):
self.log.error("Verify 5G Internet access failed.")
return False
- return verify_bluetooth_tethering_connection(self.log, self.provider, self.clients,
- toggle_tethering=False,
- toggle_bluetooth=False,
- toggle_data=False,
- change_rat=RAT_2G)
+ return verify_bluetooth_tethering_connection(self.log,
+ self.provider,
+ self.clients,
+ toggle_tethering=False,
+ toggle_bluetooth=False,
+ toggle_data=False,
+ change_rat=RAT_2G)
# Invalid Live Test. Can't rely on the result of this test with live network.
@@ -560,7 +620,11 @@
True if success.
False if failed.
"""
- if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G):
+ if not test_setup_tethering(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ nr_type='nsa'):
self.log.error("Verify 5G Internet access failed.")
return False
try:
@@ -623,7 +687,10 @@
True if success.
False if failed.
"""
- if not test_setup_tethering(self.log, self.provider, self.clients, RAT_3G):
+ if not test_setup_tethering(self.log,
+ self.provider,
+ self.clients,
+ RAT_3G):
self.log.error("Verify 3G Internet access failed.")
return False
try:
@@ -650,7 +717,9 @@
toggle_apm_after_setting=False):
self.log.error("Provider failed to reselect to LTE")
return False
- if not provision_device_for_5g(self.log, self.provider):
+ if not provision_device_for_5g(self.log,
+ self.provider,
+ nr_type='nsa'):
self.log.error("Provider failed to reselect to nsa 5G")
return False
time.sleep(WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING)
@@ -688,7 +757,11 @@
True if success.
False if failed.
"""
- if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G):
+ if not test_setup_tethering(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ nr_type='nsa'):
self.log.error("Verify 5G Internet access failed.")
return False
try:
@@ -751,7 +824,10 @@
True if success.
False if failed.
"""
- if not test_setup_tethering(self.log, self.provider, self.clients, RAT_4G):
+ if not test_setup_tethering(self.log,
+ self.provider,
+ self.clients,
+ RAT_4G):
self.log.error("Verify 4G Internet access failed.")
return False
try:
@@ -778,7 +854,9 @@
toggle_apm_after_setting=False):
self.log.error("Provider failed to reselect to LTE")
return False
- if not provision_device_for_5g(self.log, self.provider):
+ if not provision_device_for_5g(self.log,
+ self.provider,
+ nr_type='nsa'):
self.log.error("Provider failed to reselect to nsa 5G")
return False
time.sleep(WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING)
@@ -812,8 +890,13 @@
True if success.
False if failed.
"""
- return test_tethering_wifi_and_voice_call(self.log, self.provider, self.clients,
- RAT_5G, phone_setup_volte, is_phone_in_call_volte)
+ return test_tethering_wifi_and_voice_call(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ phone_setup_volte,
+ is_phone_in_call_volte,
+ nr_type='nsa')
@test_tracker_info(uuid="f4b96666-ac71-49f2-89db-a792da7bb88c")
@TelephonyBaseTest.tel_test_wrap
@@ -830,8 +913,13 @@
True if success.
False if failed.
"""
- return test_tethering_wifi_and_voice_call(self.log, self.provider, self.clients,
- RAT_5G, phone_setup_csfb, is_phone_in_call_csfb)
+ return test_tethering_wifi_and_voice_call(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ phone_setup_csfb,
+ is_phone_in_call_csfb,
+ nr_type='nsa')
@test_tracker_info(uuid="8cfa6ab6-6dcd-4ee5-97f2-db3b0f52ae17")
@TelephonyBaseTest.tel_test_wrap
@@ -848,8 +936,13 @@
True if success.
False if failed.
"""
- return test_tethering_wifi_and_voice_call(self.log, self.provider, self.clients,
- RAT_5G, phone_setup_voice_3g, is_phone_in_call_3g)
+ return test_tethering_wifi_and_voice_call(self.log,
+ self.provider,
+ self.clients,
+ RAT_5G,
+ phone_setup_voice_3g,
+ is_phone_in_call_3g,
+ nr_type='nsa')
@test_tracker_info(uuid="ff1f71d7-142c-4e0d-94be-cadbc30828fd")
@TelephonyBaseTest.tel_test_wrap
@@ -873,7 +966,8 @@
WIFI_CONFIG_APBAND_2G,
check_interval=10,
check_iteration=10,
- password="")
+ password="",
+ nr_type='nsa')
@test_tracker_info(uuid="fd6daa93-2ecb-4a23-8f29-6d2db3b940c4")
@TelephonyBaseTest.tel_test_wrap
@@ -900,7 +994,8 @@
WIFI_CONFIG_APBAND_2G,
check_interval=10,
check_iteration=2,
- do_cleanup=False):
+ do_cleanup=False,
+ nr_type='nsa'):
return False
if not verify_wifi_tethering_when_reboot(self.log,
@@ -955,7 +1050,8 @@
check_interval=10,
check_iteration=2,
do_cleanup=False,
- pre_teardown_func=setup_provider_internet_connection):
+ pre_teardown_func=setup_provider_internet_connection,
+ nr_type='nsa'):
return False
if not verify_wifi_tethering_when_reboot(self.log,
@@ -1002,7 +1098,8 @@
WIFI_CONFIG_APBAND_2G,
check_interval=10,
check_iteration=2,
- pre_teardown_func=setup_provider_internet_connect_then_reboot)
+ pre_teardown_func=setup_provider_internet_connect_then_reboot,
+ nr_type='nsa')
@test_tracker_info(uuid="70f20bcf-8064-49e3-a3f0-ff151374d1ac")
@TelephonyBaseTest.tel_test_wrap
@@ -1032,7 +1129,8 @@
WIFI_CONFIG_APBAND_2G,
check_interval=10,
check_iteration=2,
- do_cleanup=False):
+ do_cleanup=False,
+ nr_type='nsa'):
return False
if not verify_internet_connection_in_doze_mode(self.log,
self.provider,
@@ -1078,7 +1176,8 @@
WIFI_CONFIG_APBAND_2G,
check_interval=10,
check_iteration=2,
- pre_teardown_func=setup_provider_internet_connection):
+ pre_teardown_func=setup_provider_internet_connection,
+ nr_type='nsa'):
return False
if not wait_and_verify_device_internet_connection(self.log, self.provider):
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gVoiceConfTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gVoiceConfTest.py
index bbe738b..b4bbbd0 100644
--- a/acts_tests/tests/google/nr/nsa5g/Nsa5gVoiceConfTest.py
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gVoiceConfTest.py
@@ -22,32 +22,32 @@
import time
from acts import signals
from acts.test_decorators import test_tracker_info
+from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_ACTIVE
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_CONFERENCE
+from acts_contrib.test_utils.tel.tel_defines import GEN_5G
+from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_ss_utils import three_phone_call_forwarding_short_seq
+from acts_contrib.test_utils.tel.tel_ss_utils import three_phone_call_waiting_short_seq
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.tel_test_utils import get_capability_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import install_dialer_apk
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_wcdma
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _get_expected_call_state
-from acts_contrib.test_utils.tel.tel_voice_conf_utils import \
- _test_ims_conference_merge_drop_first_call_from_host
-from acts_contrib.test_utils.tel.tel_voice_conf_utils import \
- _test_ims_conference_merge_drop_first_call_from_participant
-from acts_contrib.test_utils.tel.tel_voice_conf_utils import \
- _test_ims_conference_merge_drop_second_call_from_host
-from acts_contrib.test_utils.tel.tel_voice_conf_utils import \
- _test_ims_conference_merge_drop_second_call_from_participant
+from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_ims_conference_merge_drop_first_call_from_host
+from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_ims_conference_merge_drop_first_call_from_participant
+from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_ims_conference_merge_drop_second_call_from_host
+from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_ims_conference_merge_drop_second_call_from_participant
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_call_mo_mo_add_swap_x
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_call_mo_mt_add_swap_x
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_call_mt_mt_add_swap_x
-from acts_contrib.test_utils.tel.tel_voice_conf_utils import \
- _three_phone_hangup_call_verify_call_state
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_nsa
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from acts_contrib.test_utils.tel.tel_voice_conf_utils import _three_phone_hangup_call_verify_call_state
class Nsa5gVoiceConfTest(TelephonyBaseTest):
@@ -62,6 +62,15 @@
raise signals.TestAbortClass(
"Conference call is not supported, abort test.")
+ self.dialer_util = self.user_params.get("dialer_apk", None)
+ if isinstance(self.dialer_util, list):
+ self.dialer_util = self.dialer_util[0]
+
+ if self.dialer_util:
+ ads = self.android_devices
+ for ad in ads:
+ install_dialer_apk(ad, self.dialer_util)
+
def teardown_test(self):
ensure_phones_idle(self.log, self.android_devices)
@@ -2429,3 +2438,325 @@
call_state=_get_expected_call_state(ads[0]),
ads_active=[ads[0], ads[2]])
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="f4990e20-4a40-4238-9a2a-a75d9be3d354")
+ def test_5g_nsa_volte_call_forwarding_unconditional(self):
+
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0], GEN_5G)),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_forwarding_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_forwarding_type="unconditional")
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="26b85c3f-5a38-465a-a6e3-dfd03c6ea315")
+ def test_5g_nsa_volte_call_forwarding_busy(self):
+
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0], GEN_5G)),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_forwarding_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_forwarding_type="busy")
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="96638a39-efe2-40e2-afb6-6a97f87c4af5")
+ def test_5g_nsa_volte_call_forwarding_not_answered(self):
+
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0], GEN_5G)),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_forwarding_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_forwarding_type="not_answered")
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="a13e586a-3345-49d8-9e84-ca33bd3fbd7d")
+ def test_5g_nsa_volte_call_forwarding_not_reachable(self):
+
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0], GEN_5G)),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_forwarding_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_forwarding_type="not_reachable")
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="e9a6027b-7dd1-4dca-a700-e4d42c9c947d")
+ def test_call_waiting_scenario_1(self):
+ """ Call waiting scenario 1: 1st call ended first by caller1 during 2nd
+ call incoming. 2nd call ended by caller2.
+ """
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0], GEN_5G)),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_waiting_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_waiting=True,
+ scenario=1)
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="3fe02cb7-68d7-4762-882a-02bff8ce32f9")
+ def test_call_waiting_scenario_2(self):
+ """ Call waiting scenario 2: 1st call ended first by caller1 during 2nd
+ call incoming. 2nd call ended by callee.
+ """
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0], GEN_5G)),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_waiting_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_waiting=True,
+ scenario=2)
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="bf5eb9ad-1fa2-468d-99dc-3cbcee8c89f8")
+ def test_call_waiting_scenario_3(self):
+ """ Call waiting scenario 3: 1st call ended first by callee during 2nd
+ call incoming. 2nd call ended by caller2.
+ """
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0], GEN_5G)),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_waiting_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_waiting=True,
+ scenario=3)
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="f2e4b6a9-6a6f-466c-884c-c0ef79d6ff01")
+ def test_call_waiting_scenario_4(self):
+ """Call waiting scenario 4: 1st call ended first by callee during 2nd
+ call incoming. 2nd call ended by callee.
+ """
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0], GEN_5G)),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_waiting_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_waiting=True,
+ scenario=4)
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="f2d36f45-63f6-4e01-9844-6fa53c26def7")
+ def test_call_waiting_scenario_5(self):
+ """ Call waiting scenario 5: 1st call ended by caller1. 2nd call ended
+ by caller2.
+ """
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0], GEN_5G)),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_waiting_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_waiting=True,
+ scenario=5)
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="7eb2a89d-30ad-4a34-8e63-87d0181b91aa")
+ def test_call_waiting_scenario_6(self):
+ """Call waiting scenario 6: 1st call ended by caller1. 2nd call ended by
+ callee.
+ """
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0], GEN_5G)),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_waiting_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_waiting=True,
+ scenario=6)
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="c63882e5-5b72-4ca6-8e36-260c50f42028")
+ def test_call_waiting_scenario_7(self):
+ """ Call waiting scenario 7: 1st call ended by callee. 2nd call ended by
+ caller2.
+ """
+ ads = self.android_devices
+
+ tasks = [(phone_setup_voice_general, (self.log, ads[0])),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_waiting_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_waiting=True,
+ scenario=7)
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="f9be652f-a307-4fa5-9b30-ea78404110bd")
+ def test_call_waiting_scenario_8(self):
+ """Call waiting scenario 8: 1st call ended by callee. 2nd call ended by
+ callee.
+ """
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0], GEN_5G)),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_waiting_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_waiting=True,
+ scenario=8)
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="b2e816b5-8e8f-4863-981c-47847d9527e0")
+ def test_call_waiting_deactivated(self):
+
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0], GEN_5G)),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_waiting_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_waiting=False)
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gVoiceTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gVoiceTest.py
index eff3227..38cbe45 100644
--- a/acts_tests/tests/google/nr/nsa5g/Nsa5gVoiceTest.py
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gVoiceTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3.4
#
-# Copyright 2020 - Google
+# Copyright 2022 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,10 +17,9 @@
Test Script for 5G Voice scenarios
"""
-import time
-
from acts import signals
-from acts.utils import adb_shell_ping
+from acts.libs.utils.multithread import multithread_func
+from acts.libs.utils.multithread import run_multithread_func
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
@@ -29,51 +28,51 @@
from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_TERMINATED
from acts_contrib.test_utils.tel.tel_defines import GEN_5G
from acts_contrib.test_utils.tel.tel_defines import TOTAL_LONG_CALL_DURATION
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL_FOR_IMS
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import \
- call_voicemail_erase_all_pending_voicemail
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import get_mobile_data_usage
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call_active
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import remove_mobile_data_usage_limit
-from acts_contrib.test_utils.tel.tel_test_utils import set_mobile_data_usage_limit
+from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g
+from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_both_devices_for_volte
+from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from acts_contrib.test_utils.tel.tel_5g_test_utils import verify_5g_attach_for_both_devices
+from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_task
+from acts_contrib.test_utils.tel.tel_data_utils import call_epdg_to_epdg_wfc
+from acts_contrib.test_utils.tel.tel_data_utils import get_mobile_data_usage
+from acts_contrib.test_utils.tel.tel_data_utils import remove_mobile_data_usage_limit
+from acts_contrib.test_utils.tel.tel_data_utils import set_mobile_data_usage_limit
+from acts_contrib.test_utils.tel.tel_data_utils import test_call_setup_in_active_data_transfer
+from acts_contrib.test_utils.tel.tel_data_utils import test_call_setup_in_active_youtube_video
+from acts_contrib.test_utils.tel.tel_data_utils import wifi_cell_switching
+from acts_contrib.test_utils.tel.tel_data_utils import test_wifi_cell_switching_in_call
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_2g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_2g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_test_utils import install_dialer_apk
from acts_contrib.test_utils.tel.tel_voice_utils import _test_call_long_duration
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_volte
from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_call_hold_unhold_test
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_general
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import call_voicemail_erase_all_pending_voicemail
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_active
from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_leave_voice_mail
from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_long_seq
from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_short_seq
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_nsa
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_both_devices_for_volte
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
-from acts_contrib.test_utils.tel.tel_5g_test_utils import set_preferred_mode_for_5g
-from acts_contrib.test_utils.tel.tel_5g_test_utils import verify_5g_attach_for_both_devices
-from acts_contrib.test_utils.tel.tel_5g_test_utils import disable_apm_mode_both_devices
-from acts_contrib.test_utils.tel.tel_data_utils import call_epdg_to_epdg_wfc
-from acts_contrib.test_utils.tel.tel_data_utils import test_call_setup_in_active_data_transfer
-from acts_contrib.test_utils.tel.tel_data_utils import test_call_setup_in_active_youtube_video
-from acts_contrib.test_utils.tel.tel_data_utils import wifi_cell_switching
-from acts_contrib.test_utils.tel.tel_data_utils import test_wifi_cell_switching_in_call
+from acts_contrib.test_utils.tel.tel_ops_utils import initiate_call_verify_operation
+
+
CallResult = TelephonyVoiceTestResult.CallResult.Value
@@ -88,6 +87,15 @@
"long_call_duration",
TOTAL_LONG_CALL_DURATION)
+ self.dialer_util = self.user_params.get("dialer_apk", None)
+ if isinstance(self.dialer_util, list):
+ self.dialer_util = self.dialer_util[0]
+
+ if self.dialer_util:
+ ads = self.android_devices
+ for ad in ads:
+ install_dialer_apk(ad, self.dialer_util)
+
def setup_test(self):
TelephonyBaseTest.setup_test(self)
@@ -114,7 +122,7 @@
if not provision_both_devices_for_volte(self.log, ads):
return False
- if not provision_device_for_5g(self.log, ads):
+ if not provision_device_for_5g(self.log, ads, nr_type='nsa'):
return False
# VoLTE calls
@@ -126,7 +134,7 @@
self.log.error("Failure is volte call during 5g nsa")
return False
- if not verify_5g_attach_for_both_devices(self.log, ads):
+ if not verify_5g_attach_for_both_devices(self.log, ads, nr_type='nsa'):
return False
self.log.info("PASS - volte test over 5g nsa validated")
@@ -155,7 +163,7 @@
self.log.error("Phone failed to set up in volte/3g")
return False
- if not provision_device_for_5g(self.log, ads[0]):
+ if not provision_device_for_5g(self.log, ads[0], nr_type='nsa'):
return False
# VoLTE to 3G
@@ -168,7 +176,7 @@
return False
# Attach nsa5g
- if not is_current_network_5g_nsa(ads[0]):
+ if not is_current_network_5g(ads[0], nr_type = 'nsa'):
ads[0].log.error("Phone not attached on 5g nsa after call end.")
return False
@@ -195,7 +203,7 @@
if not provision_both_devices_for_volte(self.log, ads):
return False
- if not provision_device_for_5g(self.log, ads):
+ if not provision_device_for_5g(self.log, ads, nr_type='nsa'):
return False
if not phone_setup_call_hold_unhold_test(self.log,
@@ -204,7 +212,7 @@
caller_func=is_phone_in_call_volte):
return False
- if not verify_5g_attach_for_both_devices(self.log, ads):
+ if not verify_5g_attach_for_both_devices(self.log, ads, nr_type='nsa'):
return False
return True
@@ -227,7 +235,7 @@
if not provision_both_devices_for_volte(self.log, ads):
return False
- if not provision_device_for_5g(self.log, ads):
+ if not provision_device_for_5g(self.log, ads, nr_type='nsa'):
return False
if not phone_setup_call_hold_unhold_test(self.log,
@@ -236,7 +244,7 @@
callee_func=is_phone_in_call_volte):
return False
- if not verify_5g_attach_for_both_devices(self.log, ads):
+ if not verify_5g_attach_for_both_devices(self.log, ads, nr_type='nsa'):
return False
return True
@@ -297,67 +305,6 @@
DIRECTION_MOBILE_TERMINATED)
- @test_tracker_info(uuid="3a607dee-7e92-4567-8ca0-05099590b773")
- @TelephonyBaseTest.tel_test_wrap
- def test_5g_nsa_volte_in_call_wifi_toggling(self):
- """ Test data connection network switching during VoLTE call in 5G NSA.
-
- 1. Make Sure PhoneA in VoLTE.
- 2. Make Sure PhoneB in VoLTE.
- 3. Make sure Phones are in 5G NSA
- 4. Call from PhoneA to PhoneB.
- 5. Toggling Wifi connection in call.
- 6. Verify call is active.
- 7. Hung up the call on PhoneA
- 8. Make sure Phones are in 5G NSA
-
- Returns:
- True if pass; False if fail.
- """
- ads = self.android_devices
- result = True
- if not provision_both_devices_for_volte(self.log, ads):
- return False
-
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not provision_device_for_5g(self.log, ads):
- return False
-
- if not verify_5g_attach_for_both_devices(self.log, ads):
- self.log.error("Phone not attached on 5G NSA before call.")
- return False
-
- if not call_setup_teardown(self.log, ads[0], ads[1], None, None, None,
- 5):
- self.log.error("Call setup failed")
- return False
- else:
- self.log.info("Call setup succeed")
-
- if not wifi_cell_switching(self.log, ads[0], None, self.wifi_network_ssid,
- self.wifi_network_pass):
- ads[0].log.error("Failed to do WIFI and Cell switch in call")
- result = False
-
- if not is_phone_in_call_active(ads[0]):
- return False
- else:
- if not ads[0].droid.telecomCallGetAudioState():
- ads[0].log.error("Audio is not on call")
- result = False
- else:
- ads[0].log.info("Audio is on call")
- hangup_call(self.log, ads[0])
-
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not verify_5g_attach_for_both_devices(self.log, ads):
- self.log.error("Phone not attached on 5G NSA after call.")
- return False
- return result
-
-
@test_tracker_info(uuid="96b7d8c9-d32a-4abf-8326-6b060d116ac2")
@TelephonyBaseTest.tel_test_wrap
def test_5g_nsa_call_epdg_to_epdg_wfc_wifi_preferred(self):
@@ -522,7 +469,7 @@
"Failed to setup iwlan with APM off and WIFI and WFC on")
return False
- if not provision_device_for_5g(self.log, ads[0]):
+ if not provision_device_for_5g(self.log, ads[0], nr_type='nsa'):
return False
if not phone_setup_call_hold_unhold_test(self.log,
@@ -531,7 +478,7 @@
caller_func=is_phone_in_call_iwlan):
return False
- if not is_current_network_5g_nsa(ads[0]):
+ if not is_current_network_5g(ads[0], nr_type = 'nsa'):
ads[0].log.error("Phone not attached on 5G NSA after call.")
return False
return True
@@ -561,7 +508,7 @@
"Failed to setup iwlan with APM off and WIFI and WFC on")
return False
- if not provision_device_for_5g(self.log, ads[0]):
+ if not provision_device_for_5g(self.log, ads[0], nr_type='nsa'):
return False
if not phone_setup_call_hold_unhold_test(self.log,
@@ -570,7 +517,7 @@
callee_func=is_phone_in_call_iwlan):
return False
- if not is_current_network_5g_nsa(ads[0]):
+ if not is_current_network_5g(ads[0], nr_type = 'nsa'):
ads[0].log.error("Phone not attached on 5G NSA after call.")
return False
return True
@@ -597,7 +544,7 @@
self.log.error("Phone failed to set up in VoLTE/CSFB")
return False
- if not provision_device_for_5g(self.log, ads[0]):
+ if not provision_device_for_5g(self.log, ads[0], nr_type='nsa'):
return False
result = two_phone_call_short_seq(
@@ -630,7 +577,7 @@
self.log.error("Phone failed to set up in VoLTE/2G")
return False
- if not provision_device_for_5g(self.log, ads[0]):
+ if not provision_device_for_5g(self.log, ads[0], nr_type='nsa'):
return False
result = two_phone_call_short_seq(
@@ -665,7 +612,7 @@
self.log.error("Phone failed to set up in VoLTE")
return False
- if not provision_device_for_5g(self.log, ads[1]):
+ if not provision_device_for_5g(self.log, ads[1], nr_type='nsa'):
return False
result = two_phone_call_short_seq(
@@ -701,7 +648,7 @@
self.log.error("Phone failed to set up in VoLTE")
return False
- if not provision_device_for_5g(self.log, ads[1]):
+ if not provision_device_for_5g(self.log, ads[1], nr_type='nsa'):
return False
result = two_phone_call_short_seq(
@@ -737,7 +684,7 @@
self.log.error("Phone failed to set up in VoLTE")
return False
- if not provision_device_for_5g(self.log, ads[1]):
+ if not provision_device_for_5g(self.log, ads[1], nr_type='nsa'):
return False
result = two_phone_call_short_seq(
@@ -769,7 +716,7 @@
if not provision_both_devices_for_volte(self.log, ads):
return False
- if not provision_device_for_5g(self.log, ads[1]):
+ if not provision_device_for_5g(self.log, ads[1], nr_type='nsa'):
return False
result = two_phone_call_long_seq(
@@ -805,7 +752,7 @@
if not provision_both_devices_for_volte(self.log, ads):
return False
- if not provision_device_for_5g(self.log, ads[1]):
+ if not provision_device_for_5g(self.log, ads[1], nr_type='nsa'):
return False
success_count = 0
@@ -859,7 +806,7 @@
self.log.error("Phone Failed to Set Up Properly.")
return False
- if not provision_device_for_5g(self.log, ads[0]):
+ if not provision_device_for_5g(self.log, ads[0], nr_type='nsa'):
return False
if not call_voicemail_erase_all_pending_voicemail(self.log, ads[0]):
@@ -895,7 +842,7 @@
self.log.error("Phone Failed to Set Up Properly.")
return False
- if not provision_device_for_5g(self.log, ads[0]):
+ if not provision_device_for_5g(self.log, ads[0], nr_type='nsa'):
return False
return _test_call_long_duration(self.log, ads,
@@ -922,7 +869,7 @@
data_usage = get_mobile_data_usage(ads[0], subscriber_id)
set_mobile_data_usage_limit(ads[0], data_usage, subscriber_id)
- if not provision_device_for_5g(self.log, ads):
+ if not provision_device_for_5g(self.log, ads, nr_type='nsa'):
self.log.error("Phone Failed to Set Up Properly.")
self.tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
raise signals.TestFailure("Failed",
@@ -959,7 +906,7 @@
ads = self.android_devices
result = True
- if not provision_device_for_5g(self.log, ads):
+ if not provision_device_for_5g(self.log, ads, nr_type='nsa'):
self.log.error("Phone Failed to Set Up Properly.")
self.tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
raise signals.TestFailure("Failed",
@@ -1052,7 +999,7 @@
True if success.
False if failed.
"""
- if not provision_device_for_5g(self.log, self.android_devices[0]):
+ if not provision_device_for_5g(self.log, self.android_devices[0], nr_type='nsa'):
self.android_devices[0].log.error("Phone not attached on 5G NSA before call.")
return False
@@ -1082,7 +1029,7 @@
True if success.
False if failed.
"""
- if not provision_device_for_5g(self.log, self.android_devices[0]):
+ if not provision_device_for_5g(self.log, self.android_devices[0], nr_type='nsa'):
self.android_devices[0].log.error("Phone not attached on 5G NSA before call.")
return False
@@ -1111,7 +1058,7 @@
True if success.
False if failed.
"""
- if not provision_device_for_5g(self.log, self.android_devices[0]):
+ if not provision_device_for_5g(self.log, self.android_devices[0], nr_type='nsa'):
self.android_devices[0].log.error("Phone not attached on 5G NSA before call.")
return False
@@ -1140,7 +1087,7 @@
True if success.
False if failed.
"""
- if not provision_device_for_5g(self.log, self.android_devices[0]):
+ if not provision_device_for_5g(self.log, self.android_devices[0], nr_type='nsa'):
self.android_devices[0].log.error("Phone not attached on 5G NSA before call.")
return False
@@ -1174,7 +1121,7 @@
ads = self.android_devices
- if not provision_device_for_5g(self.log, ads):
+ if not provision_device_for_5g(self.log, ads, nr_type='nsa'):
return False
tasks = [(phone_setup_iwlan,
(self.log, ads[0], False, WFC_MODE_WIFI_PREFERRED,
@@ -1189,4 +1136,109 @@
self.wifi_network_ssid,
self.wifi_network_pass)
+ @test_tracker_info(uuid="e42cb2bc-db0b-4053-a052-7d95e55bc815")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_volte_call_during_data_idle_and_transfer_mo(self):
+ """Test 5G NSA for VoLTE call during data idle and data transfer.
+
+ Steps:
+ (1) Provision both devices on 5G NSA.
+ (2) Initiate MO VoLTE call during data idle.
+ (3) End call.
+ (4) Initiate a MO VoLTE call and start a download.
+ (5) Start another download and initiate MO VoLTE call during data transferring.
+ (6) End call.
+ (7) Initiate a MO VoLTE call and start a download.
+
+ Returns:
+ True if pass; False if fail.
+ """
+ cell_1 = self.android_devices[0]
+ cell_2 = self.android_devices[1]
+
+ if not provision_device_for_5g(self.log, [cell_1, cell_2], nr_type='nsa'):
+ cell_1.log.error("Failed to setup on 5G NSA")
+ return False
+
+ # Initiate call during data idle and end call
+ if not initiate_call_verify_operation(self.log, cell_1, cell_2):
+ cell_1.log.error("Phone was unable to initate a call")
+ return False
+
+ # Initiate call and start a download
+ if not initiate_call_verify_operation(self.log, cell_1, cell_2, True):
+ cell_1.log.error("Phone was unable to initate a call and verify download")
+ return False
+
+ download_task = active_file_download_task(self.log, cell_1, "10MB")
+ call_task = (initiate_call_verify_operation, (self.log, cell_1, cell_2))
+
+ results = run_multithread_func(self.log, [download_task, call_task])
+
+ if ((results[0]) & (results[1])):
+ self.log.info("PASS - Validate VoLTE call during data transferring")
+ elif ((results[0] == False) & (results[1] == True)):
+ self.log.error("FAIL - Data Transfer failed")
+ elif ((results[0] == True) & (results[1] == False)):
+ self.log.error("FAIL - Call Initiation failed")
+ else:
+ self.log.error("FAILED - Validate VoLTE call during data transferring")
+
+ if not initiate_call_verify_operation(self.log, cell_1, cell_2, True):
+ cell_1.log.error("Phone was unable to initate a call and verify download")
+ return False
+
+
+ @test_tracker_info(uuid="c69ec37d-133f-42c5-babd-91f763dd5b21")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_volte_call_during_data_idle_and_transfer_mt(self):
+ """Test 5G NSA for VoLTE call during data idle and data transfer.
+
+ Steps:
+ (1) Provision both devices on 5G NSA.
+ (2) Initiate MT VoLTE call during data idle.
+ (3) End call.
+ (4) Initiate a MO VoLTE call and start a download.
+ (5) Start another download and initiate MT VoLTE call during data transferring.
+ (6) End call.
+ (7) Initiate a MO VoLTE call and start a download.
+
+ Returns:
+ True if pass; False if fail.
+ """
+ cell_1 = self.android_devices[0]
+ cell_2 = self.android_devices[1]
+
+ if not provision_device_for_5g(self.log, [cell_1, cell_2], nr_type='nsa'):
+ cell_1.log.error("Failed to setup on 5G NSA")
+ return False
+
+ # Initiate call during data idle and end call
+ if not initiate_call_verify_operation(self.log, cell_2, cell_1):
+ cell_2.log.error("Phone was unable to initate a call")
+ return False
+
+ # Initiate call and start a download
+ if not initiate_call_verify_operation(self.log, cell_1, cell_2, True):
+ cell_1.log.error("Phone was unable to initate a call and verify download")
+ return False
+
+ download_task = active_file_download_task(self.log, cell_2, "10MB")
+ call_task = (initiate_call_verify_operation, (self.log, cell_2, cell_1))
+
+ results = run_multithread_func(self.log, [download_task, call_task])
+
+ if ((results[0]) & (results[1])):
+ self.log.info("PASS - Validate MT VoLTE call during data transferring")
+ elif ((results[0] == False) & (results[1] == True)):
+ self.log.error("FAIL - Data Transfer failed")
+ elif ((results[0] == True) & (results[1] == False)):
+ self.log.error("FAIL - Call Initiation failed")
+ else:
+ self.log.error("FAILED - Validate MT VoLTE call during data transferring")
+
+ if not initiate_call_verify_operation(self.log, cell_1, cell_2, True):
+ cell_1.log.error("Phone was unable to initate a call and verify download")
+ return False
+
""" Tests End """
diff --git a/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwActivationTest.py b/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwActivationTest.py
new file mode 100644
index 0000000..fde9540
--- /dev/null
+++ b/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwActivationTest.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python3.4
+#
+# Copyright 2021 - Google
+#
+# 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.
+"""
+ Test Script for 5G MSA mmWave Activation scenarios
+"""
+
+import time
+
+from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.tel_test_utils import reboot_device
+from acts_contrib.test_utils.tel.tel_test_utils import cycle_airplane_mode
+from acts_contrib.test_utils.tel.tel_5g_test_utils import test_activation_by_condition
+from acts_contrib.test_utils.tel.tel_test_utils import set_phone_silent_mode
+
+
+class Nsa5gMmwActivationTest(TelephonyBaseTest):
+ def setup_class(self):
+ super().setup_class()
+ for ad in self.android_devices:
+ set_phone_silent_mode(self.log, ad, True)
+
+ def setup_test(self):
+ TelephonyBaseTest.setup_test(self)
+ self.number_of_devices = 1
+
+ def teardown_class(self):
+ TelephonyBaseTest.teardown_class(self)
+
+ """ Tests Begin """
+
+ @test_tracker_info(uuid="6831cf7f-349e-43ae-9a89-5e183a755671")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_activation_from_apm(self):
+ """ Verifies 5G NSA mmWave activation from Airplane Mode
+
+ Toggle Airplane mode on and off
+ Ensure phone attach, data on, LTE attach
+ Wait for 120 secs for ENDC attach
+ Verify is data network type is NR_NSA
+
+ Returns:
+ True if pass; False if fail.
+ """
+
+ return test_activation_by_condition(self.android_devices[0],
+ nr_type='mmwave',
+ precond_func=lambda: cycle_airplane_mode(self.android_devices[0]))
+
+ @test_tracker_info(uuid="21fb9b5c-40e8-4804-b05b-017395bb2e79")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_activation_from_reboot(self):
+ """ Verifies 5G NSA mmWave activation from Reboot
+
+ Reboot device
+ Ensure phone attach, data on, LTE attach
+ Wait for 120 secs for ENDC attach
+ Verify is data network type is NR_NSA
+
+ Returns:
+ True if pass; False if fail.
+ """
+
+ return test_activation_by_condition(self.android_devices[0],
+ nr_type='mmwave',
+ precond_func=lambda: reboot_device(self.android_devices[0]))
+
+ @test_tracker_info(uuid="2cef7ec0-ea74-458f-a98e-143d0be71f31")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_activation_from_3g(self):
+ """ Verifies 5G NSA mmWave activation from 3G Mode Pref
+
+ Change Mode to 3G and wait for 15 secs
+ Change Mode back to 5G
+ Ensure phone attach, data on, LTE attach
+ Wait for 120 secs for ENDC attach
+ Verify is data network type is NR_NSA
+
+ Returns:
+ True if pass; False if fail.
+ """
+
+ return test_activation_by_condition(self.android_devices[0],
+ from_3g=True,
+ nr_type='mmwave')
+
+ """ Tests End """
+
diff --git a/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwDataTest.py b/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwDataTest.py
new file mode 100755
index 0000000..5f54d59
--- /dev/null
+++ b/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwDataTest.py
@@ -0,0 +1,372 @@
+#!/usr/bin/env python3.4
+#
+# Copyright 2022 - Google
+#
+# 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.
+"""
+ Test Script for 5G NSA MMWAVE Data scenarios
+"""
+
+import time
+
+from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.tel_defines import GEN_5G
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_USER_PLANE_DATA
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_NR_LTE_GSM_WCDMA
+from acts_contrib.test_utils.tel.tel_defines import NetworkCallbackCapabilitiesChanged
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
+from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from acts_contrib.test_utils.tel.tel_5g_test_utils import set_preferred_mode_for_5g
+from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g
+from acts_contrib.test_utils.tel.tel_data_utils import airplane_mode_test
+from acts_contrib.test_utils.tel.tel_data_utils import browsing_test
+from acts_contrib.test_utils.tel.tel_data_utils import check_data_stall_detection
+from acts_contrib.test_utils.tel.tel_data_utils import check_data_stall_recovery
+from acts_contrib.test_utils.tel.tel_data_utils import check_network_validation_fail
+from acts_contrib.test_utils.tel.tel_data_utils import data_connectivity_single_bearer
+from acts_contrib.test_utils.tel.tel_data_utils import reboot_test
+from acts_contrib.test_utils.tel.tel_data_utils import test_wifi_connect_disconnect
+from acts_contrib.test_utils.tel.tel_data_utils import verify_for_network_callback
+from acts_contrib.test_utils.tel.tel_data_utils import wifi_cell_switching
+from acts_contrib.test_utils.tel.tel_test_utils import break_internet_except_sl4a_port
+from acts_contrib.test_utils.tel.tel_test_utils import get_current_override_network_type
+from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
+from acts_contrib.test_utils.tel.tel_test_utils import resume_internet_with_sl4a_port
+from acts_contrib.test_utils.tel.tel_test_utils import set_phone_silent_mode
+from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_failure_using_sl4a
+from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_success_using_sl4a
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_reset
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
+
+
+class Nsa5gMmwDataTest(TelephonyBaseTest):
+ def setup_class(self):
+ super().setup_class()
+ self.iperf_server_ip = self.user_params.get("iperf_server", '0.0.0.0')
+ self.iperf_tcp_port = self.user_params.get("iperf_tcp_port", 0)
+ self.iperf_udp_port = self.user_params.get("iperf_udp_port", 0)
+ self.iperf_duration = self.user_params.get("iperf_duration", 60)
+ for ad in self.android_devices:
+ set_phone_silent_mode(self.log, ad, True)
+
+ def setup_test(self):
+ TelephonyBaseTest.setup_test(self)
+ self.provider = self.android_devices[0]
+ self.clients = self.android_devices[1:]
+
+ def teardown_class(self):
+ TelephonyBaseTest.teardown_class(self)
+
+
+ """ Tests Begin """
+
+
+ @test_tracker_info(uuid="069d05c0-1fa0-4fd4-a4df-a0eff753b38d")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_data_browsing(self):
+ """ Verifying connectivity of internet and browsing websites on 5G NSA MMW network.
+
+ Ensure
+ 1. ping to IP of websites is successful.
+ 2. http ping to IP of websites is successful.
+ 3. browsing websites is successful.
+ Returns:
+ True if pass; False if fail.
+ """
+ ad = self.android_devices[0]
+ wifi_toggle_state(ad.log, ad, False)
+ sub_id = ad.droid.subscriptionGetDefaultSubId()
+ if not set_preferred_mode_for_5g(ad, sub_id,
+ NETWORK_MODE_NR_LTE_GSM_WCDMA):
+ ad.log.error("Failed to set network mode to NSA")
+ return False
+ ad.log.info("Set network mode to NSA successfully")
+ ad.log.info("Waiting for 5G NSA MMW attach for 60 secs")
+ if is_current_network_5g(ad, nr_type = 'mmwave', timeout=60):
+ ad.log.info("Success! attached on 5G NSA MMW")
+ else:
+ ad.log.error("Failure - expected NR_NSA MMW, current %s",
+ get_current_override_network_type(ad))
+ # Can't attach 5G NSA MMW, exit test!
+ return False
+ for iteration in range(3):
+ connectivity = False
+ browsing = False
+ ad.log.info("Attempt %d", iteration + 1)
+ if not verify_internet_connection(self.log, ad):
+ ad.log.error("Failed to connect to internet!")
+ else:
+ ad.log.info("Connect to internet successfully!")
+ connectivity = True
+ if not browsing_test(ad.log, ad):
+ ad.log.error("Failed to browse websites!")
+ else:
+ ad.log.info("Successful to browse websites!")
+ browsing = True
+ if connectivity and browsing:
+ return True
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+ ad.log.error("5G NSA MMW Connectivity and Data Browsing test FAIL for all 3 iterations")
+ return False
+
+
+ @test_tracker_info(uuid="f1638e11-c686-4431-8b6c-4dc7cbff6406")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_data_stall_recovery(self):
+ """ Verifies 5G NSA MMW data stall
+
+ Set Mode to 5G NSA MMW
+ Wait for 5G attached on NSA MMW
+ Browse websites for success
+ Trigger data stall and verify browsing fails
+ Resume data and verify browsing success
+
+ Returns:
+ True if pass; False if fail.
+ """
+ ad = self.android_devices[0]
+ result = True
+ wifi_toggle_state(ad.log, ad, False)
+ toggle_airplane_mode(ad.log, ad, False)
+
+ if not provision_device_for_5g(ad.log, ad, nr_type='mmwave'):
+ return False
+
+ cmd = ('ss -l -p -n | grep "tcp.*droid_script" | tr -s " " '
+ '| cut -d " " -f 5 | sed s/.*://g')
+ sl4a_port = ad.adb.shell(cmd)
+
+ if not test_data_browsing_success_using_sl4a(ad.log, ad):
+ ad.log.error("Browsing failed before the test, aborting!")
+ return False
+
+ begin_time = get_device_epoch_time(ad)
+ break_internet_except_sl4a_port(ad, sl4a_port)
+
+ if not test_data_browsing_failure_using_sl4a(ad.log, ad):
+ ad.log.error("Browsing after breaking the internet, aborting!")
+ result = False
+
+ if not check_data_stall_detection(ad):
+ ad.log.warning("NetworkMonitor unable to detect Data Stall")
+
+ if not check_network_validation_fail(ad, begin_time):
+ ad.log.warning("Unable to detect NW validation fail")
+
+ if not check_data_stall_recovery(ad, begin_time):
+ ad.log.error("Recovery was not triggered")
+ result = False
+
+ resume_internet_with_sl4a_port(ad, sl4a_port)
+ time.sleep(MAX_WAIT_TIME_USER_PLANE_DATA)
+ if not test_data_browsing_success_using_sl4a(ad.log, ad):
+ ad.log.error("Browsing failed after resuming internet")
+ result = False
+ if result:
+ ad.log.info("PASS - data stall over 5G NSA MMW")
+ else:
+ ad.log.error("FAIL - data stall over 5G NSA MMW")
+ return result
+
+
+ @test_tracker_info(uuid="38fd987d-2a9a-44d5-bea4-e524359390c6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_metered_cellular(self):
+ """ Verifies 5G NSA MMW Meteredness API
+
+ Set Mode to 5G NSA MMW
+ Wait for 5G attached on NSA NSA MMW
+ Register for Connectivity callback
+ Verify value of metered flag
+
+ Returns:
+ True if pass; False if fail.
+ """
+ ad = self.android_devices[0]
+ try:
+ wifi_toggle_state(ad.log, ad, False)
+ toggle_airplane_mode(ad.log, ad, False)
+ if not provision_device_for_5g(ad.log, ad, nr_type='mmwave'):
+ return False
+
+ return verify_for_network_callback(ad.log, ad,
+ NetworkCallbackCapabilitiesChanged, apm_mode=False)
+ except Exception as e:
+ ad.log.error(e)
+ return False
+
+
+ @test_tracker_info(uuid="8d4ce840-6261-4395-bf7b-e1f6cdf4d9a9")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_metered_wifi(self):
+ """ Verifies 5G NSA MMW Meteredness API
+
+ Set Mode to 5G NSA MMW, Wifi Connected
+ Register for Connectivity callback
+ Verify value of metered flag
+
+ Returns:
+ True if pass; False if fail.
+ """
+ ad = self.android_devices[0]
+ try:
+ toggle_airplane_mode(ad.log, ad, False)
+ if not provision_device_for_5g(ad.log, ad, nr_type='mmwave'):
+ return False
+ wifi_toggle_state(ad.log, ad, True)
+ if not ensure_wifi_connected(ad.log, ad,
+ self.wifi_network_ssid,
+ self.wifi_network_pass):
+ ad.log.error("WiFi connect fail.")
+ return False
+ return verify_for_network_callback(ad.log, ad,
+ NetworkCallbackCapabilitiesChanged)
+ except Exception as e:
+ ad.log.error(e)
+ return False
+ finally:
+ wifi_toggle_state(ad.log, ad, False)
+
+
+ @test_tracker_info(uuid="1661cd40-0eed-43f0-bd2a-8e02392af3b1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_switching(self):
+ """Test data connection network switching when phone camped on 5G NSA MMW.
+
+ Ensure phone is camped on 5G NSA MMW
+ Ensure WiFi can connect to live network,
+ Airplane mode is off, data connection is on, WiFi is on.
+ Turn off WiFi, verify data is on cell and browse to google.com is OK.
+ Turn on WiFi, verify data is on WiFi and browse to google.com is OK.
+ Turn off WiFi, verify data is on cell and browse to google.com is OK.
+
+ Returns:
+ True if pass.
+ """
+ ad = self.android_devices[0]
+ return wifi_cell_switching(ad.log, ad, GEN_5G, self.wifi_network_ssid,
+ self.wifi_network_pass, nr_type='mmwave')
+
+
+ @test_tracker_info(uuid="8033a359-1b92-45ff-b766-bb0010132eb7")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_data_connectivity(self):
+ """Test data connection in 5g NSA MMW.
+
+ Turn off airplane mode, disable WiFi, enable Cellular Data.
+ Ensure phone data generation is 5g NSA MMW.
+ Verify Internet.
+ Disable Cellular Data, verify Internet is inaccessible.
+ Enable Cellular Data, verify Internet.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ ad = self.android_devices[0]
+ wifi_reset(ad.log, ad)
+ wifi_toggle_state(ad.log, ad, False)
+ return data_connectivity_single_bearer(ad.log, ad, GEN_5G, nr_type='mmwave')
+
+
+ @test_tracker_info(uuid="633526fa-9e58-47a4-8957-bb0a95eef4ab")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_not_associated(self):
+ """Test data connection in 5g NSA MMW.
+
+ Turn off airplane mode, enable WiFi (but not connected), enable Cellular Data.
+ Ensure phone data generation is 5g MMW.
+ Verify Internet.
+ Disable Cellular Data, verify Internet is inaccessible.
+ Enable Cellular Data, verify Internet.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ ad = self.android_devices[0]
+ wifi_reset(ad.log, ad)
+ wifi_toggle_state(ad.log, ad, False)
+ wifi_toggle_state(ad.log, ad, True)
+ return data_connectivity_single_bearer(ad.log, ad, GEN_5G, nr_type='mmwave')
+
+
+ @test_tracker_info(uuid="c56324a2-5eda-4027-9068-7e120d2b178e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_connect_disconnect(self):
+ """Perform multiple connects and disconnects from WiFi and verify that
+ data switches between WiFi and Cell.
+
+ Steps:
+ 1. DUT Cellular Data is on 5G NSA MMW. Reset Wifi on DUT
+ 2. Connect DUT to a WiFi AP
+ 3. Repeat steps 1-2, alternately disconnecting and disabling wifi
+
+ Expected Results:
+ 1. Verify Data on Cell
+ 2. Verify Data on Wifi
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ if not provision_device_for_5g(self.log, self.provider, nr_type='mmwave'):
+ return False
+
+ return test_wifi_connect_disconnect(self.log, self.provider, self.wifi_network_ssid, self.wifi_network_pass)
+
+
+ @test_tracker_info(uuid="88cd3f68-08c3-4635-94ce-a1dffc3ffbf2")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_airplane_mode(self):
+ """Test airplane mode basic on Phone and Live SIM on 5G NSA MMW.
+
+ Ensure phone is on 5G NSA MMW.
+ Ensure phone attach, data on, WiFi off and verify Internet.
+ Turn on airplane mode to make sure detach.
+ Turn off airplane mode to make sure attach.
+ Verify Internet connection.
+
+ Returns:
+ True if pass; False if fail.
+ """
+ if not provision_device_for_5g(self.log, self.android_devices[0], nr_type='mmwave'):
+ return False
+ return airplane_mode_test(self.log, self.android_devices[0])
+
+
+ @test_tracker_info(uuid="b99967b9-96da-4f1b-90cb-6dbd6578236b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_reboot(self):
+ """Test 5G NSA MMWAVE service availability after reboot.
+
+ Ensure phone is on 5G NSA MMWAVE.
+ Ensure phone attach, data on, WiFi off and verify Internet.
+ Reboot Device.
+ Verify Network Connection.
+
+ Returns:
+ True if pass; False if fail.
+ """
+ if not provision_device_for_5g(self.log, self.android_devices[0], nr_type='mmwave'):
+ return False
+ if not verify_internet_connection(self.log, self.android_devices[0]):
+ return False
+ return reboot_test(self.log, self.android_devices[0])
+
+
+ """ Tests End """
diff --git a/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwMmsTest.py b/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwMmsTest.py
new file mode 100755
index 0000000..d865e8f
--- /dev/null
+++ b/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwMmsTest.py
@@ -0,0 +1,388 @@
+#!/usr/bin/env python3.4
+#
+# Copyright 2021 - Google
+#
+# 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.
+"""
+ Test Script for 5G NSA MMWAVE MMS scenarios
+"""
+
+import time
+
+from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
+from acts_contrib.test_utils.tel.tel_message_utils import message_test
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_test_utils import set_phone_silent_mode
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+
+
+class Nsa5gMmwMmsTest(TelephonyBaseTest):
+ def setup_class(self):
+ super().setup_class()
+ for ad in self.android_devices:
+ set_phone_silent_mode(self.log, ad, True)
+
+ def setup_test(self):
+ TelephonyBaseTest.setup_test(self)
+
+ def teardown_test(self):
+ ensure_phones_idle(self.log, self.android_devices)
+
+
+ """ Tests Begin """
+
+
+ @test_tracker_info(uuid="c6f7483f-6007-4a3b-a02d-5e6ab2b9a742")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_mo_mt(self):
+ """Test MMS between two phones in 5g NSA MMW
+
+ Provision devices in 5g NSA MMW
+ Send and Verify MMS from PhoneA to PhoneB
+ Verify both devices are still on 5g NSA MMW
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmwave',
+ mt_rat='5g_nsa_mmwave',
+ msg_type='mms')
+
+
+ @test_tracker_info(uuid="8e6ed681-d5b8-4503-8262-a16739c66bdb")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_mo_general(self):
+ """Test MO MMS for 1 phone in 5g NSA MMW. The other phone in any network
+
+ Provision PhoneA in 5g NSA MMW
+ Send and Verify MMS from PhoneA to PhoneB
+ Verify phoneA is still on 5g NSA MMW
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmwave',
+ mt_rat='default',
+ msg_type='mms')
+
+
+ @test_tracker_info(uuid="d22ea7fd-6c07-4eb2-a1bf-10b03cab3201")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_mt_general(self):
+ """Test MT MMS for 1 phone in 5g NSA MMW. The other phone in any network
+
+ Provision PhoneA in 5g NSA MMW
+ Send and Verify MMS from PhoneB to PhoneA
+ Verify phoneA is still on 5g NSA MMW
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_nsa_mmwave',
+ msg_type='mms')
+
+
+ @test_tracker_info(uuid="897eb961-236d-4b8f-8a84-42f2010c6621")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_mo_volte(self):
+ """Test MO MMS for 1 phone with VoLTE on 5G NSA MMW
+
+ Provision PhoneA on VoLTE
+ Provision PhoneA in 5g NSA MMW
+ Send and Verify MMS from PhoneA to PhoneB
+ Verify PhoneA is still on 5g NSA MMW
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmw_volte',
+ mt_rat='default',
+ msg_type='mms')
+
+
+ @test_tracker_info(uuid="6e185efe-b876-4dcf-9fc2-915039826dbe")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_mt_volte(self):
+ """Test MT MMS for 1 phone with VoLTE on 5G NSA MMW
+
+ Provision PhoneA on VoLTE
+ Provision PhoneA in 5g NSA MMW
+ Send and Verify MMS from PhoneB to PhoneA
+ Verify PhoneA is still on 5g NSA MMW
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_nsa_mmw_volte',
+ msg_type='mms')
+
+
+ @test_tracker_info(uuid="900d9913-b35d-4d75-859b-12bb28a35b73")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_mo_iwlan(self):
+ """ Test MO MMS text function for 1 phone in APM,
+ WiFi connected, WFC Cell Preferred mode.
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA MMW
+ Provision PhoneA for WFC Cell Pref with APM ON
+ Send and Verify MMS from PhoneA to PhoneB
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmw_wfc',
+ mt_rat='default',
+ msg_type='mms',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+
+ @test_tracker_info(uuid="939a1ec5-1004-4527-b11e-eacbcfe0f632")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_mt_iwlan(self):
+ """ Test MT MMS text function for 1 phone in APM,
+ WiFi connected, WFC Cell Preferred mode.
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA MMW
+ Provision PhoneA for WFC Cell Pref with APM ON
+ Send and Verify MMS from PhoneB to PhoneA
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_nsa_mmw_wfc',
+ msg_type='mms',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+
+ @test_tracker_info(uuid="253e4966-dd1c-487b-87fc-85b675140b24")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_mo_iwlan_apm_off(self):
+ """ Test MO MMS, Phone in APM off, WiFi connected, WFC WiFi Pref Mode
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA MMW
+ Provision PhoneA for WFC Wifi Pref with APM OFF
+ Send and Verify MMS from PhoneA to PhoneB
+ Verify 5g NSA MMW attach for PhoneA
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmw_wfc',
+ mt_rat='default',
+ msg_type='mms',
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+
+ @test_tracker_info(uuid="884435c5-47d8-4db9-b89e-087fc344a8b9")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_mt_iwlan_apm_off(self):
+ """ Test MT MMS, Phone in APM off, WiFi connected, WFC WiFi Pref Mode
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA MMW
+ Provision PhoneA for WFC Wifi Pref with APM OFF
+ Send and Verify MMS from PhoneB to PhoneA
+ Verify 5g NSA MMW attach for PhoneA
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_nsa_mmw_wfc',
+ msg_type='mms',
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+
+ @test_tracker_info(uuid="d0085f8f-bb18-4801-8bba-c5d2466922f2")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_long_message_mo_mt(self):
+ """Test MMS basic function between two phone. Phones in 5G NSA MMW network.
+
+ Airplane mode is off. Phone in 5G NSA MMW.
+ Send MMS from PhoneA to PhoneB.
+ Verify received message on PhoneB is correct.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmwave',
+ mt_rat='5g_nsa_mmwave',
+ msg_type='mms',
+ long_msg=True)
+
+
+ @test_tracker_info(uuid="f43760c6-b040-46ba-9613-fde4192bf2db")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_long_message_mo(self):
+ """Test MO long MMS basic function for 1 phone in 5G NSA MMW network.
+
+ Airplane mode is off. PhoneA in 5G NSA MMW.
+ Send long MMS from PhoneA to PhoneB.
+ Verify received message on PhoneB is correct.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmwave',
+ mt_rat='default',
+ msg_type='mms',
+ long_msg=True)
+
+
+ @test_tracker_info(uuid="dc17e5d2-e022-47af-9b21-cf4e11911e17")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_long_message_mt(self):
+ """Test MT long MMS basic function for 1 phone in 5G NSA MMW network.
+
+ Airplane mode is off. PhoneA in nsa 5G NSA MMW.
+ Send long MMS from PhoneB to PhoneA.
+ Verify received message on PhoneA is correct.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_nsa_mmwave',
+ msg_type='mms',
+ long_msg=True)
+
+
+ @test_tracker_info(uuid="2a73b511-988c-4a49-857c-5692f6d6cdd6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_mo_wifi(self):
+ """Test MMS basic function between two phone. Phones in nsa 5g network.
+
+ Airplane mode is off. Phone in 5G NSA MMW.
+ Connect to Wifi.
+ Send MMS from PhoneA to PhoneB.
+ Verify received message on PhoneB is correct.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmwave',
+ mt_rat='general',
+ msg_type='mms',
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+
+ @test_tracker_info(uuid="58414ce6-851a-4527-8243-502f5a8cfa7a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_mms_mt_wifi(self):
+ """Test MMS basic function between two phone. Phones in nsa 5g network.
+
+ Airplane mode is off. Phone in 5G NSA MMW.
+ Connect to Wifi.
+ Send MMS from PhoneB to PhoneA.
+ Verify received message on PhoneA is correct.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='5g_nsa_mmwave',
+ msg_type='mms',
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+ """ Tests End """
diff --git a/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwSmsTest.py b/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwSmsTest.py
new file mode 100755
index 0000000..aeaac3b
--- /dev/null
+++ b/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwSmsTest.py
@@ -0,0 +1,351 @@
+#!/usr/bin/env python3.4
+#
+# Copyright 2021 - Google
+#
+# 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.
+"""
+ Test Script for 5G NSA MMWAVE SMS scenarios
+"""
+
+import time
+from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
+from acts_contrib.test_utils.tel.tel_message_utils import message_test
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_test_utils import set_phone_silent_mode
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+
+
+class Nsa5gMmwSmsTest(TelephonyBaseTest):
+ def setup_class(self):
+ super().setup_class()
+ for ad in self.android_devices:
+ set_phone_silent_mode(self.log, ad, True)
+
+ def setup_test(self):
+ TelephonyBaseTest.setup_test(self)
+
+ def teardown_test(self):
+ ensure_phones_idle(self.log, self.android_devices)
+
+
+ """ Tests Begin """
+
+
+ @test_tracker_info(uuid="fb333cd5-2eaa-4d63-be26-fdf1e67d01b0")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_sms_mo_mt(self):
+ """Test SMS between two phones in 5g NSA MMW
+
+ Provision devices in 5g NSA MMW
+ Send and Verify SMS from PhoneA to PhoneB
+ Verify both devices are still on 5g NSA MMW
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmwave',
+ mt_rat='5g_nsa_mmwave')
+
+
+ @test_tracker_info(uuid="3afc92e8-69f7-4ead-a416-4df9753da27a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_sms_mo_general(self):
+ """Test MO SMS for 1 phone in 5g NSA MMW. The other phone in any network
+
+ Provision PhoneA in 5g NSA MMW
+ Send and Verify SMS from PhoneA to PhoneB
+ Verify phoneA is still on 5g NSA MMW
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmwave',
+ mt_rat='default')
+
+
+ @test_tracker_info(uuid="ee57da72-8e30-42ad-a7b3-d05bb4762724")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_sms_mt_general(self):
+ """Test MT SMS for 1 phone in 5g NSA MMW. The other phone in any network
+
+ Provision PhoneB in 5g NSA MMW
+ Send and Verify SMS from PhoneB to PhoneA
+ Verify phoneA is still on 5g NSA MMW
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_nsa_mmwave')
+
+
+ @test_tracker_info(uuid="1f75e117-f0f5-45fe-8896-91e0d2e61e9c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_sms_mo_mt_volte(self):
+ """Test SMS between two phones with VoLTE on 5g NSA MMW
+
+ Provision devices on VoLTE
+ Provision devices in 5g NSA MMW
+ Send and Verify SMS from PhoneA to PhoneB
+ Verify both devices are still on 5g NSA MMW
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmw_volte',
+ mt_rat='5g_nsa_mmw_volte')
+
+
+ @test_tracker_info(uuid="f58fe4ed-77e0-40ff-8599-27d95cb27e14")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_sms_mo_volte(self):
+ """Test MO SMS with VoLTE on 5g NSA MMW. The other phone in any network
+
+ Provision PhoneA on VoLTE
+ Provision PhoneA in 5g NSA MMW
+ Send and Verify SMS from PhoneA to PhoneB
+ Verify PhoneA is still on 5g NSA MMW
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmw_volte',
+ mt_rat='default')
+
+
+ @test_tracker_info(uuid="f60ac2b0-0feb-441e-9048-fe1b2878f8b6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_sms_mt_volte(self):
+ """Test MT SMS with VoLTE on 5g NSA MMW. The other phone in any network
+
+ Provision PhoneA on VoLTE
+ Provision PhoneA in 5g NSA MMW
+ Send and Verify SMS from PhoneB to PhoneA
+ Verify phoneA is still on 5g NSA MMW
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_nsa_mmw_volte')
+
+
+ @test_tracker_info(uuid="6b27d804-abcd-4558-894d-545428a5dff4")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_sms_mo_iwlan(self):
+ """ Test MO SMS for 1 phone in APM,
+ WiFi connected, WFC Cell Preferred mode.
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA MMW
+ Provision PhoneA for WFC Cell Pref with APM ON
+ Send and Verify SMS from PhoneA to PhoneB
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmw_wfc',
+ mt_rat='general',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+
+ @test_tracker_info(uuid="0b848508-a1e8-4652-9e13-74749a7ccd2e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_sms_mt_iwlan(self):
+ """ Test MT SMS for 1 phone in APM,
+ WiFi connected, WFC Cell Preferred mode.
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA MMW
+ Provision PhoneA for WFC Cell Pref with APM ON
+ Send and Verify SMS from PhoneB to PhoneA
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='5g_nsa_mmw_wfc',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+
+ @test_tracker_info(uuid="9fc07594-6dbf-4b7a-b5a5-f4c06032fa35")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_sms_mo_iwlan_apm_off(self):
+ """ Test MO SMS for 1 Phone in APM off, WiFi connected,
+ WFC WiFi Preferred mode.
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA MMW
+ Provision PhoneA for WFC Wifi Pref with APM OFF
+ Send and Verify SMS from PhoneA to PhoneB
+ Verify 5g NSA MMW attach for PhoneA
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmw_wfc',
+ mt_rat='general',
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+
+ @test_tracker_info(uuid="b76c0eaf-6e6b-4da7-87a0-26895f93a554")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_sms_mt_iwlan_apm_off(self):
+ """ Test MT SMS for 1 Phone in APM off, WiFi connected,
+ WFC WiFi Preferred mode.
+
+ Disable APM on both devices
+ Provision PhoneA in 5g NSA MMW
+ Provision PhoneA for WFC Wifi Pref with APM OFF
+ Send and Verify SMS from PhoneB to PhoneA
+ Verify 5g NSA MMW attach for PhoneA
+
+ Returns:
+ True if pass; False if fail.
+ """
+ apm_mode = [toggle_airplane_mode(self.log, ad, False) for ad in self.android_devices]
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='5g_nsa_mmw_wfc',
+ wfc_mode=WFC_MODE_WIFI_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
+
+
+ @test_tracker_info(uuid="43694343-e6f0-4430-972f-53f61c7b51b0")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_sms_long_message_mo_mt(self):
+ """Test SMS basic function between two phone. Phones in 5G NSA MMW network.
+
+ Airplane mode is off.
+ Send SMS from PhoneA to PhoneB.
+ Verify received message on PhoneB is correct.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmwave',
+ mt_rat='5g_nsa_mmwave',
+ long_msg=True)
+
+
+ @test_tracker_info(uuid="846dcf2d-911f-46a0-adb1-e32667b8ebd3")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_sms_long_message_mo(self):
+ """Test MO long SMS function for 1 phone in 5G NSA MMW network.
+
+ Disable APM on PhoneA
+ Provision PhoneA in 5g NSA MMW
+ Send SMS from PhoneA to PhoneB
+ Verify received message on PhoneB is correct
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='5g_nsa_mmwave',
+ mt_rat='default',
+ long_msg=True)
+
+
+ @test_tracker_info(uuid="4d2951c3-d80c-4860-8dd9-9709cb7dfaa8")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_sms_long_message_mt(self):
+ """Test MT long SMS function for 1 phone in 5G NSA MMW network.
+
+ Disable APM on PhoneA
+ Provision PhoneA in 5g NSA MMW
+ Send SMS from PhoneB to PhoneA
+ Verify received message on PhoneA is correct
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='5g_nsa_mmwave',
+ long_msg=True)
+
+ """ Tests End """
diff --git a/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwTetheringTest.py b/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwTetheringTest.py
new file mode 100755
index 0000000..4f94bb1
--- /dev/null
+++ b/acts_tests/tests/google/nr/nsa5gmmw/Nsa5gMmwTetheringTest.py
@@ -0,0 +1,657 @@
+#!/usr/bin/env python3.4
+#
+# Copyright 2021 - Google
+#
+# 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.
+"""
+ Test Script for 5G NSA MMWAVE Tethering scenarios
+"""
+
+import time
+
+from acts.utils import rand_ascii_str
+from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
+from acts_contrib.test_utils.tel.tel_defines import RAT_3G
+from acts_contrib.test_utils.tel.tel_defines import RAT_4G
+from acts_contrib.test_utils.tel.tel_defines import RAT_5G
+from acts_contrib.test_utils.tel.tel_defines import TETHERING_PASSWORD_HAS_ESCAPE
+from acts_contrib.test_utils.tel.tel_defines import TETHERING_SPECIAL_SSID_LIST
+from acts_contrib.test_utils.tel.tel_defines import TETHERING_SPECIAL_PASSWORD_LIST
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING
+from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from acts_contrib.test_utils.tel.tel_data_utils import test_wifi_tethering
+from acts_contrib.test_utils.tel.tel_data_utils import test_setup_tethering
+from acts_contrib.test_utils.tel.tel_data_utils import test_start_wifi_tethering_connect_teardown
+from acts_contrib.test_utils.tel.tel_data_utils import tethering_check_internet_connection
+from acts_contrib.test_utils.tel.tel_data_utils import verify_toggle_apm_tethering_internet_connection
+from acts_contrib.test_utils.tel.tel_data_utils import verify_tethering_entitlement_check
+from acts_contrib.test_utils.tel.tel_data_utils import wifi_tethering_cleanup
+from acts_contrib.test_utils.tel.tel_data_utils import wifi_tethering_setup_teardown
+from acts_contrib.test_utils.tel.tel_data_utils import wait_and_verify_device_internet_connection
+from acts_contrib.test_utils.tel.tel_data_utils import setup_device_internet_connection
+from acts_contrib.test_utils.tel.tel_data_utils import verify_toggle_data_during_wifi_tethering
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation
+from acts_contrib.test_utils.tel.tel_test_utils import set_phone_silent_mode
+from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_reset
+
+
+class Nsa5gMmwTetheringTest(TelephonyBaseTest):
+ def setup_class(self):
+ super().setup_class()
+ self.stress_test_number = self.get_stress_test_number()
+ self.provider = self.android_devices[0]
+ self.clients = self.android_devices[1:]
+ for ad in self.android_devices:
+ set_phone_silent_mode(self.log, ad, True)
+
+ def setup_test(self):
+ TelephonyBaseTest.setup_test(self)
+ self.number_of_devices = 1
+
+ def teardown_class(self):
+ TelephonyBaseTest.teardown_class(self)
+
+
+ """ Tests Begin """
+
+
+ @test_tracker_info(uuid="ae6c4a14-0474-448c-ad18-dcedfee7fa5a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_to_5gwifi(self):
+ """WiFi Tethering test: 5G NSA MMW to WiFI 5G Tethering
+
+ 1. DUT in 5G NSA MMW mode, attached.
+ 2. DUT start 5G WiFi Tethering
+ 3. PhoneB disable data, connect to DUT's softAP
+ 4. Verify Internet access on DUT and PhoneB
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return test_wifi_tethering(self.log,
+ self.provider,
+ self.clients,
+ self.clients,
+ RAT_5G,
+ WIFI_CONFIG_APBAND_5G,
+ check_interval=10,
+ check_iteration=10,
+ nr_type= 'mmwave')
+
+
+ @test_tracker_info(uuid="bf6ed593-4fe3-417c-9d04-ad71a8d3095e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_to_2gwifi(self):
+ """WiFi Tethering test: 5G NSA MMW to WiFI 2G Tethering
+
+ 1. DUT in 5G NSA MMW mode, attached.
+ 2. DUT start 2.4G WiFi Tethering
+ 3. PhoneB disable data, connect to DUT's softAP
+ 4. Verify Internet access on DUT and PhoneB
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return test_wifi_tethering(self.log,
+ self.provider,
+ self.clients,
+ self.clients,
+ RAT_5G,
+ WIFI_CONFIG_APBAND_2G,
+ check_interval=10,
+ check_iteration=10,
+ nr_type= 'mmwave')
+
+
+ @test_tracker_info(uuid="96c4bc30-6dd1-4f14-bdbd-bf40b8b24701")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_toggle_apm(self):
+ """WiFi Tethering test: Toggle APM during active WiFi 2.4G Tethering from 5G NSA MMW
+
+ 1. DUT in 5G NSA MMW mode, idle.
+ 2. DUT start 2.4G WiFi Tethering
+ 3. PhoneB disable data, connect to DUT's softAP
+ 4. Verify Internet access on DUT and PhoneB
+ 5. DUT toggle APM on, verify WiFi tethering stopped, PhoneB lost WiFi connection.
+ 6. DUT toggle APM off, verify PhoneA have cellular data and Internet connection.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ try:
+ ssid = rand_ascii_str(10)
+ if not test_wifi_tethering(self.log,
+ self.provider,
+ self.clients,
+ [self.clients[0]],
+ RAT_5G,
+ WIFI_CONFIG_APBAND_2G,
+ check_interval=10,
+ check_iteration=2,
+ do_cleanup=False,
+ ssid=ssid,
+ nr_type= 'mmwave'):
+ self.log.error("WiFi Tethering failed.")
+ return False
+
+ if not verify_toggle_apm_tethering_internet_connection(self.log,
+ self.provider,
+ self.clients,
+ ssid):
+ return False
+ finally:
+ self.clients[0].droid.telephonyToggleDataConnection(True)
+ wifi_reset(self.log, self.clients[0])
+ return True
+
+
+ @test_tracker_info(uuid="e4f7deaa-a2be-4543-9364-17d704b2bf44")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_toggle_data(self):
+ """WiFi Tethering test: Toggle Data during active WiFi Tethering from 5G NSA MMW
+
+ 1. DUT is on 5G NSA MMW, DUT data connection is on and idle.
+ 2. DUT start 2.4G WiFi Tethering
+ 3. PhoneB disable data, connect to DUT's softAP
+ 4. Verify Internet access on DUT and PhoneB
+ 5. Disable Data on DUT, verify PhoneB still connected to WiFi, but no Internet access.
+ 6. Enable Data on DUT, verify PhoneB still connected to WiFi and have Internet access.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ if not verify_toggle_data_during_wifi_tethering(self.log,
+ self.provider,
+ self.clients,
+ new_gen=RAT_5G,
+ nr_type= 'mmwave'):
+ return False
+ return True
+
+
+ @test_tracker_info(uuid="e6c30776-c245-42aa-a211-77dbd76c5217")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_entitlement_check(self):
+ """5G NSA MMW Tethering Entitlement Check Test
+
+ Get tethering entitlement check result.
+
+ Returns:
+ True if entitlement check returns True.
+ """
+
+ if not provision_device_for_5g(self.log, self.provider, nr_type= 'mmwave'):
+ return False
+ return verify_tethering_entitlement_check(self.log,
+ self.provider)
+
+
+ @test_tracker_info(uuid="a73ca034-c90c-4579-96dd-9518d74c2a6c")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_ssid_quotes(self):
+ """WiFi Tethering test: 5G NSA MMW wifi tethering SSID name have quotes.
+ 1. Set SSID name have double quotes.
+ 2. Start LTE to WiFi (2.4G) tethering.
+ 3. Verify tethering.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ ssid = "\"" + rand_ascii_str(10) + "\""
+ self.log.info(
+ "Starting WiFi Tethering test with ssid: {}".format(ssid))
+
+ return test_wifi_tethering(self.log,
+ self.provider,
+ self.clients,
+ self.clients,
+ RAT_5G,
+ WIFI_CONFIG_APBAND_2G,
+ check_interval=10,
+ check_iteration=10,
+ ssid=ssid,
+ nr_type= 'mmwave')
+
+
+ @test_tracker_info(uuid="6702831b-f656-4410-a922-d47fae138d68")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_password_escaping_characters(self):
+ """WiFi Tethering test: 5G NSA MMW wifi tethering password have escaping characters.
+ 1. Set password have escaping characters.
+ e.g.: '"DQ=/{Yqq;M=(^_3HzRvhOiL8S%`]w&l<Qp8qH)bs<4E9v_q=HLr^)}w$blA0Kg'
+ 2. Start LTE to WiFi (2.4G) tethering.
+ 3. Verify tethering.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+
+ password = TETHERING_PASSWORD_HAS_ESCAPE
+ self.log.info(
+ "Starting WiFi Tethering test with password: {}".format(password))
+
+ return test_wifi_tethering(self.log,
+ self.provider,
+ self.clients,
+ self.clients,
+ RAT_5G,
+ WIFI_CONFIG_APBAND_2G,
+ check_interval=10,
+ check_iteration=10,
+ password=password,
+ nr_type= 'mmwave')
+
+
+ @test_tracker_info(uuid="93cf9aa2-740f-42a4-92a8-c506ceb5d448")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_ssid(self):
+ """WiFi Tethering test: start 5G NSA MMW WiFi tethering with all kinds of SSIDs.
+
+ For each listed SSID, start WiFi tethering on DUT, client connect WiFi,
+ then tear down WiFi tethering.
+
+ Returns:
+ True if WiFi tethering succeed on all SSIDs.
+ False if failed.
+ """
+ if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G, nr_type= 'mmwave'):
+ self.log.error("Setup Failed.")
+ return False
+ ssid_list = TETHERING_SPECIAL_SSID_LIST
+ fail_list = {}
+ self.number_of_devices = 2
+ for ssid in ssid_list:
+ password = rand_ascii_str(8)
+ self.log.info("SSID: <{}>, Password: <{}>".format(ssid, password))
+ if not test_start_wifi_tethering_connect_teardown(self.log,
+ self.provider,
+ self.clients[0],
+ ssid,
+ password):
+ fail_list[ssid] = password
+
+ if len(fail_list) > 0:
+ self.log.error("Failed cases: {}".format(fail_list))
+ return False
+ else:
+ return True
+
+
+ @test_tracker_info(uuid="ed73ed58-781b-4fe4-991e-fa0cc2726b0d")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_password(self):
+ """WiFi Tethering test: start 5G NSA MMW WiFi tethering with all kinds of passwords.
+
+ For each listed password, start WiFi tethering on DUT, client connect WiFi,
+ then tear down WiFi tethering.
+
+ Returns:
+ True if WiFi tethering succeed on all passwords.
+ False if failed.
+ """
+ if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G, nr_type= 'mmwave'):
+ self.log.error("Setup Failed.")
+ return False
+ password_list = TETHERING_SPECIAL_PASSWORD_LIST
+ fail_list = {}
+ self.number_of_devices = 2
+ for password in password_list:
+ ssid = rand_ascii_str(8)
+ self.log.info("SSID: <{}>, Password: <{}>".format(ssid, password))
+ if not test_start_wifi_tethering_connect_teardown(self.log,
+ self.provider,
+ self.clients[0],
+ ssid,
+ password):
+ fail_list[ssid] = password
+
+ if len(fail_list) > 0:
+ self.log.error("Failed cases: {}".format(fail_list))
+ return False
+ else:
+ return True
+
+
+ # Invalid Live Test. Can't rely on the result of this test with live network.
+ # Network may decide not to change the RAT when data connection is active.
+ @test_tracker_info(uuid="ac18159b-ebfb-42d1-b97b-ff25c5cb7b9e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_from_5g_nsa_mmw_to_3g(self):
+ """WiFi Tethering test: Change Cellular Data RAT generation from 5G NSA MMW to 3G,
+ during active WiFi Tethering.
+
+ 1. DUT in 5G NSA MMW mode, idle.
+ 2. DUT start 2.4G WiFi Tethering
+ 3. PhoneB disable data, connect to DUT's softAP
+ 4. Verily Internet access on DUT and PhoneB
+ 5. Change DUT Cellular Data RAT generation from 5G NSA MMW to 3G.
+ 6. Verify both DUT and PhoneB have Internet access.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G, nr_type= 'mmwave'):
+ self.log.error("Verify 5G Internet access failed.")
+ return False
+ try:
+ if not wifi_tethering_setup_teardown(
+ self.log,
+ self.provider, [self.clients[0]],
+ ap_band=WIFI_CONFIG_APBAND_2G,
+ check_interval=10,
+ check_iteration=2,
+ do_cleanup=False):
+ self.log.error("WiFi Tethering failed.")
+ return False
+
+ if not self.provider.droid.wifiIsApEnabled():
+ self.provider.log.error("Provider WiFi tethering stopped.")
+ return False
+
+ self.log.info("Provider change RAT from 5G NSA MMW to 3G.")
+ if not ensure_network_generation(
+ self.log,
+ self.provider,
+ RAT_3G,
+ voice_or_data=NETWORK_SERVICE_DATA,
+ toggle_apm_after_setting=False):
+ self.provider.log.error("Provider failed to reselect to 3G.")
+ return False
+ time.sleep(WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING)
+ if not verify_internet_connection(self.log, self.provider):
+ self.provider.log.error("Data not available on Provider.")
+ return False
+ if not self.provider.droid.wifiIsApEnabled():
+ self.provider.log.error("Provider WiFi tethering stopped.")
+ return False
+ if not tethering_check_internet_connection(
+ self.log, self.provider, [self.clients[0]], 10, 5):
+ return False
+ finally:
+ if not wifi_tethering_cleanup(self.log, self.provider,
+ self.clients):
+ return False
+ return True
+
+
+ # Invalid Live Test. Can't rely on the result of this test with live network.
+ # Network may decide not to change the RAT when data connection is active.
+ @test_tracker_info(uuid="5a2dc4f4-f6ea-4162-b034-4919997161ac")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_from_3g_to_5g_nsa_mmw(self):
+ """WiFi Tethering test: Change Cellular Data RAT generation from 3G to 5G NSA MMW,
+ during active WiFi Tethering.
+
+ 1. DUT in 3G mode, idle.
+ 2. DUT start 2.4G WiFi Tethering
+ 3. PhoneB disable data, connect to DUT's softAP
+ 4. Verily Internet access on DUT and PhoneB
+ 5. Change DUT Cellular Data RAT generation from 3G to nsa5G.
+ 6. Verify both DUT and PhoneB have Internet access.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ if not test_setup_tethering(self.log, self.provider, self.clients, RAT_3G):
+ self.log.error("Verify 3G Internet access failed.")
+ return False
+ try:
+ if not wifi_tethering_setup_teardown(
+ self.log,
+ self.provider, [self.clients[0]],
+ ap_band=WIFI_CONFIG_APBAND_2G,
+ check_interval=10,
+ check_iteration=2,
+ do_cleanup=False):
+ self.log.error("WiFi Tethering failed.")
+ return False
+
+ if not self.provider.droid.wifiIsApEnabled():
+ self.log.error("Provider WiFi tethering stopped.")
+ return False
+
+ self.log.info("Provider change RAT from 3G to 5G NSA MMW.")
+ if not ensure_network_generation(
+ self.log,
+ self.provider,
+ RAT_5G,
+ voice_or_data=NETWORK_SERVICE_DATA,
+ toggle_apm_after_setting=False,
+ nr_type= 'mmwave'):
+ self.log.error("Provider failed to reselect to 5G NSA MMW")
+ return False
+
+ time.sleep(WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING)
+ if not verify_internet_connection(self.log, self.provider):
+ self.provider.log.error("Data not available on Provider.")
+ return False
+ if not self.provider.droid.wifiIsApEnabled():
+ self.provider.log.error("Provider WiFi tethering stopped.")
+ return False
+ if not tethering_check_internet_connection(
+ self.log, self.provider, [self.clients[0]], 10, 5):
+ return False
+ finally:
+ if not wifi_tethering_cleanup(self.log, self.provider, [self.clients[0]]):
+ return False
+ return True
+
+
+ # Invalid Live Test. Can't rely on the result of this test with live network.
+ # Network may decide not to change the RAT when data connection is active.
+ @test_tracker_info(uuid="ac0a5f75-3f08-40fb-83ca-3312019680b9")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_from_5g_nsa_mmw_to_4g(self):
+ """WiFi Tethering test: Change Cellular Data RAT generation from 5G NSA MMW to 4G,
+ during active WiFi Tethering.
+
+ 1. DUT in 5G NSA MMW mode, idle.
+ 2. DUT start 2.4G WiFi Tethering
+ 3. PhoneB disable data, connect to DUT's softAP
+ 4. Verily Internet access on DUT and PhoneB
+ 5. Change DUT Cellular Data RAT generation from 5G NSA MMW to LTE.
+ 6. Verify both DUT and PhoneB have Internet access.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ if not test_setup_tethering(self.log, self.provider, self.clients, RAT_5G, nr_type= 'mmwave'):
+ self.log.error("Verify 5G Internet access failed.")
+ return False
+ try:
+ if not wifi_tethering_setup_teardown(
+ self.log,
+ self.provider, [self.clients[0]],
+ ap_band=WIFI_CONFIG_APBAND_2G,
+ check_interval=10,
+ check_iteration=2,
+ do_cleanup=False):
+ self.log.error("WiFi Tethering failed.")
+ return False
+
+ if not self.provider.droid.wifiIsApEnabled():
+ self.provider.log.error("Provider WiFi tethering stopped.")
+ return False
+
+ self.log.info("Provider change RAT from 5G to LTE.")
+ if not ensure_network_generation(
+ self.log,
+ self.provider,
+ RAT_4G,
+ voice_or_data=NETWORK_SERVICE_DATA,
+ toggle_apm_after_setting=False):
+ self.provider.log.error("Provider failed to reselect to 4G.")
+ return False
+ time.sleep(WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING)
+ if not verify_internet_connection(self.log, self.provider):
+ self.provider.log.error("Data not available on Provider.")
+ return False
+ if not self.provider.droid.wifiIsApEnabled():
+ self.provider.log.error("Provider WiFi tethering stopped.")
+ return False
+ if not tethering_check_internet_connection(
+ self.log, self.provider, [self.clients[0]], 10, 5):
+ return False
+ finally:
+ if not wifi_tethering_cleanup(self.log, self.provider,
+ self.clients):
+ return False
+ return True
+
+
+ # Invalid Live Test. Can't rely on the result of this test with live network.
+ # Network may decide not to change the RAT when data connection is active.
+ @test_tracker_info(uuid="9335bfdc-d0df-4c5e-99fd-6492a2ce2947")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_from_4g_to_5g_nsa_mmw(self):
+ """WiFi Tethering test: Change Cellular Data RAT generation from 4G to 5G NSA MMW,
+ during active WiFi Tethering.
+
+ 1. DUT in 4G mode, idle.
+ 2. DUT start 2.4G WiFi Tethering
+ 3. PhoneB disable data, connect to DUT's softAP
+ 4. Verily Internet access on DUT and PhoneB
+ 5. Change DUT Cellular Data RAT generation from 4G to 5G NSA MMW.
+ 6. Verify both DUT and PhoneB have Internet access.
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ if not test_setup_tethering(self.log, self.provider, self.clients, RAT_4G):
+ self.log.error("Verify 4G Internet access failed.")
+ return False
+ try:
+ if not wifi_tethering_setup_teardown(
+ self.log,
+ self.provider, [self.clients[0]],
+ ap_band=WIFI_CONFIG_APBAND_2G,
+ check_interval=10,
+ check_iteration=2,
+ do_cleanup=False):
+ self.log.error("WiFi Tethering failed.")
+ return False
+
+ if not self.provider.droid.wifiIsApEnabled():
+ self.log.error("Provider WiFi tethering stopped.")
+ return False
+
+ self.log.info("Provider change RAT from 4G to 5G.")
+ if not ensure_network_generation(
+ self.log,
+ self.provider,
+ RAT_5G,
+ voice_or_data=NETWORK_SERVICE_DATA,
+ toggle_apm_after_setting=False,
+ nr_type= 'mmwave'):
+ self.log.error("Provider failed to reselect to 5G NSA MMW")
+ return False
+
+ time.sleep(WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING)
+ if not verify_internet_connection(self.log, self.provider):
+ self.provider.log.error("Data not available on Provider.")
+ return False
+ if not self.provider.droid.wifiIsApEnabled():
+ self.provider.log.error("Provider WiFi tethering stopped.")
+ return False
+ if not tethering_check_internet_connection(
+ self.log, self.provider, [self.clients[0]], 10, 5):
+ return False
+ finally:
+ if not wifi_tethering_cleanup(self.log, self.provider, [self.clients[0]]):
+ return False
+ return True
+
+
+ @test_tracker_info(uuid="7956472e-962c-4bbe-a08d-37901935c9ac")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_no_password(self):
+ """WiFi Tethering test: Start 5G NSA MMW WiFi tethering with no password
+
+ 1. DUT is idle.
+ 2. DUT start 2.4G WiFi Tethering, with no WiFi password.
+ 3. PhoneB disable data, connect to DUT's softAP
+ 4. Verify Internet access on DUT and PhoneB
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ return test_wifi_tethering(self.log,
+ self.provider,
+ self.clients,
+ [self.clients[0]],
+ RAT_5G,
+ WIFI_CONFIG_APBAND_2G,
+ check_interval=10,
+ check_iteration=10,
+ password="",
+ nr_type= 'mmwave')
+
+
+ @test_tracker_info(uuid="39e73f91-79c7-4cc0-9fa0-a737f88889e8")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_nsa_mmw_wifi_tethering_disable_resume_wifi(self):
+ """WiFi Tethering test: WiFI connected to 2.4G network,
+ start (LTE) 2.4G WiFi tethering, then stop tethering over 5G NSA MMW
+
+ 1. DUT in data connected, idle. WiFi connected to 2.4G Network
+ 2. DUT start 2.4G WiFi Tethering
+ 3. PhoneB disable data, connect to DUT's softAP
+ 4. Verify Internet access on DUT and PhoneB
+ 5. Disable WiFi Tethering on DUT.
+ 6. Verify DUT automatically connect to previous WiFI network
+
+ Returns:
+ True if success.
+ False if failed.
+ """
+ # Ensure provider connecting to wifi network.
+ def setup_provider_internet_connection():
+ return setup_device_internet_connection(self.log,
+ self.provider,
+ self.wifi_network_ssid,
+ self.wifi_network_pass)
+
+ if not test_wifi_tethering(self.log,
+ self.provider,
+ self.clients,
+ [self.clients[0]],
+ RAT_5G,
+ WIFI_CONFIG_APBAND_2G,
+ check_interval=10,
+ check_iteration=2,
+ pre_teardown_func=setup_provider_internet_connection,
+ nr_type= 'mmwave'):
+ return False
+
+ if not wait_and_verify_device_internet_connection(self.log, self.provider):
+ return False
+ return True
+
+
+ """ Tests End """
diff --git a/acts_tests/tests/google/nr/sa5g/Sa5gDataTest.py b/acts_tests/tests/google/nr/sa5g/Sa5gDataTest.py
index 80fe585..9212968 100755
--- a/acts_tests/tests/google/nr/sa5g/Sa5gDataTest.py
+++ b/acts_tests/tests/google/nr/sa5g/Sa5gDataTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3.4
#
-# Copyright 2021 - Google
+# Copyright 2022 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -25,10 +25,17 @@
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_USER_PLANE_DATA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_NR_ONLY
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
+from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g
+from acts_contrib.test_utils.tel.tel_data_utils import browsing_test
+from acts_contrib.test_utils.tel.tel_data_utils import check_data_stall_detection
+from acts_contrib.test_utils.tel.tel_data_utils import check_data_stall_recovery
+from acts_contrib.test_utils.tel.tel_data_utils import check_network_validation_fail
+from acts_contrib.test_utils.tel.tel_data_utils import data_connectivity_single_bearer
+from acts_contrib.test_utils.tel.tel_data_utils import reboot_test
+from acts_contrib.test_utils.tel.tel_data_utils import test_wifi_connect_disconnect
+from acts_contrib.test_utils.tel.tel_data_utils import wifi_cell_switching
from acts_contrib.test_utils.tel.tel_test_utils import break_internet_except_sl4a_port
-from acts_contrib.test_utils.tel.tel_test_utils import check_data_stall_detection
-from acts_contrib.test_utils.tel.tel_test_utils import check_data_stall_recovery
-from acts_contrib.test_utils.tel.tel_test_utils import check_network_validation_fail
from acts_contrib.test_utils.tel.tel_test_utils import get_current_override_network_type
from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
from acts_contrib.test_utils.tel.tel_test_utils import resume_internet_with_sl4a_port
@@ -37,14 +44,8 @@
from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_success_using_sl4a
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_reset
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_toggle_state
-from acts_contrib.test_utils.tel.tel_data_utils import browsing_test
-from acts_contrib.test_utils.tel.tel_data_utils import data_connectivity_single_bearer
-from acts_contrib.test_utils.tel.tel_data_utils import test_wifi_connect_disconnect
-from acts_contrib.test_utils.tel.tel_data_utils import wifi_cell_switching
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_sa
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_reset
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
class Sa5gDataTest(TelephonyBaseTest):
@@ -83,7 +84,7 @@
return False
ad.log.info("Set network mode to SA successfully")
ad.log.info("Waiting for 5g SA attach for 60 secs")
- if is_current_network_5g_sa(ad):
+ if is_current_network_5g(ad, nr_type = 'sa'):
ad.log.info("Success! attached on 5g SA")
else:
ad.log.error("Failure - expected NR, current %s",
@@ -129,7 +130,7 @@
wifi_toggle_state(ad.log, ad, False)
toggle_airplane_mode(ad.log, ad, False)
- if not provision_device_for_5g(ad.log, ad, sa_5g=True):
+ if not provision_device_for_5g(ad.log, ad, nr_type= 'sa'):
return False
cmd = ('ss -l -p -n | grep "tcp.*droid_script" | tr -s " " '
@@ -188,7 +189,7 @@
True if success.
False if failed.
"""
- if not provision_device_for_5g(self.log, self.provider, sa_5g=True):
+ if not provision_device_for_5g(self.log, self.provider, nr_type= 'sa'):
return False
return test_wifi_connect_disconnect(self.log, self.provider, self.wifi_network_ssid, self.wifi_network_pass)
@@ -211,7 +212,7 @@
"""
ad = self.android_devices[0]
return wifi_cell_switching(ad.log, ad, GEN_5G, self.wifi_network_ssid,
- self.wifi_network_pass, sa_5g=True)
+ self.wifi_network_pass, nr_type= 'sa')
@test_tracker_info(uuid="8df1b65c-197e-40b3-83a4-6da1f0a51b97")
@@ -233,6 +234,26 @@
wifi_reset(ad.log, ad)
wifi_toggle_state(ad.log, ad, False)
wifi_toggle_state(ad.log, ad, True)
- return data_connectivity_single_bearer(ad.log, ad, GEN_5G, sa_5g=True)
+ return data_connectivity_single_bearer(ad.log, ad, GEN_5G, nr_type= 'sa')
+
+
+ @test_tracker_info(uuid="6c1ec0a6-223e-4bcd-b958-b85f5eb03943")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_5g_sa_reboot(self):
+ """Test 5G SA service availability after reboot.
+
+ Ensure phone is on 5G SA.
+ Ensure phone attach, data on, WiFi off and verify Internet.
+ Reboot Device.
+ Verify Network Connection.
+
+ Returns:
+ True if pass; False if fail.
+ """
+ if not provision_device_for_5g(self.log, self.android_devices[0], nr_type='sa'):
+ return False
+ if not verify_internet_connection(self.log, self.android_devices[0]):
+ return False
+ return reboot_test(self.log, self.android_devices[0])
""" Tests End """
diff --git a/acts_tests/tests/google/nr/sa5g/Sa5gMmsTest.py b/acts_tests/tests/google/nr/sa5g/Sa5gMmsTest.py
index 43d5028..b3be0b4 100755
--- a/acts_tests/tests/google/nr/sa5g/Sa5gMmsTest.py
+++ b/acts_tests/tests/google/nr/sa5g/Sa5gMmsTest.py
@@ -21,13 +21,13 @@
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.tel_5g_test_utils import disable_apm_mode_both_devices
from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
from acts_contrib.test_utils.tel.tel_5g_test_utils import verify_5g_attach_for_both_devices
from acts_contrib.test_utils.tel.tel_mms_utils import _mms_test_mo
from acts_contrib.test_utils.tel.tel_mms_utils import _long_mms_test_mo
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
class Sa5gMmsTest(TelephonyBaseTest):
@@ -59,13 +59,13 @@
False if failed.
"""
ads = self.android_devices
- if not provision_device_for_5g(self.log, ads, sa_5g=True):
+ if not provision_device_for_5g(self.log, ads, nr_type='sa'):
return False
if not _mms_test_mo(self.log, ads):
return False
- if not verify_5g_attach_for_both_devices(self.log, ads, True):
+ if not verify_5g_attach_for_both_devices(self.log, ads, nr_type='sa'):
return False
self.log.info("PASS - mms test over 5g sa validated")
@@ -91,7 +91,7 @@
if not disable_apm_mode_both_devices(self.log, ads):
return False
- if not provision_device_for_5g(self.log, ads, sa_5g=True):
+ if not provision_device_for_5g(self.log, ads, nr_type='sa'):
return False
return _long_mms_test_mo(self.log, ads)
@@ -117,7 +117,7 @@
if not disable_apm_mode_both_devices(self.log, ads):
return False
- if not provision_device_for_5g(self.log, ads, sa_5g=True):
+ if not provision_device_for_5g(self.log, ads, nr_type='sa'):
return False
ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
diff --git a/acts_tests/tests/google/nr/sa5g/Sa5gSmsTest.py b/acts_tests/tests/google/nr/sa5g/Sa5gSmsTest.py
index 011062f..fd84637 100755
--- a/acts_tests/tests/google/nr/sa5g/Sa5gSmsTest.py
+++ b/acts_tests/tests/google/nr/sa5g/Sa5gSmsTest.py
@@ -20,7 +20,7 @@
import time
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.tel_5g_test_utils import disable_apm_mode_both_devices
from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_both_devices_for_volte
@@ -57,13 +57,13 @@
False if failed.
"""
ads = self.android_devices
- if not provision_device_for_5g(self.log, ads, sa_5g=True):
+ if not provision_device_for_5g(self.log, ads, nr_type='sa'):
return False
if not _sms_test_mo(self.log, ads):
return False
- if not verify_5g_attach_for_both_devices(self.log, ads, True):
+ if not verify_5g_attach_for_both_devices(self.log, ads, nr_type='sa'):
return False
self.log.info("PASS - SMS test over 5G SA validated")
@@ -90,7 +90,7 @@
if not disable_apm_mode_both_devices(self.log, ads):
return False
- if not provision_device_for_5g(self.log, ads, sa_5g=True):
+ if not provision_device_for_5g(self.log, ads, nr_type='sa'):
return False
return _long_sms_test_mo(self.log, ads)
diff --git a/acts_tests/tests/google/power/tel/PowerTelMac_McsSweep_Test.py b/acts_tests/tests/google/power/tel/PowerTelMac_McsSweep_Test.py
new file mode 100644
index 0000000..d787234
--- /dev/null
+++ b/acts_tests/tests/google/power/tel/PowerTelMac_McsSweep_Test.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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_contrib.test_utils.power.cellular.cellular_pdcch_power_test as cppt
+
+
+class PowerTelMac_McsSweep_Test(cppt.PowerTelPDCCHTest):
+
+ def test_lte_mac_dl_4_ul_4(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_11_ul_4(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_21_ul_4(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_28_ul_4(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_4_ul_11(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_4_ul_21(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_4_ul_28(self):
+ self.power_pdcch_test()
\ No newline at end of file
diff --git a/acts_tests/tests/google/power/tel/PowerTelMac_MimoSweep_Test.py b/acts_tests/tests/google/power/tel/PowerTelMac_MimoSweep_Test.py
new file mode 100644
index 0000000..9e84867
--- /dev/null
+++ b/acts_tests/tests/google/power/tel/PowerTelMac_MimoSweep_Test.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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_contrib.test_utils.power.cellular.cellular_pdcch_power_test as cppt
+
+
+class PowerTelMac_MimoSweep_Test(cppt.PowerTelPDCCHTest):
+
+ def test_lte_mac_1x1(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_2x2(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_4x4(self):
+ self.power_pdcch_test()
diff --git a/acts_tests/tests/google/power/tel/PowerTelMac_RbSweep_Test.py b/acts_tests/tests/google/power/tel/PowerTelMac_RbSweep_Test.py
new file mode 100644
index 0000000..154d07d
--- /dev/null
+++ b/acts_tests/tests/google/power/tel/PowerTelMac_RbSweep_Test.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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_contrib.test_utils.power.cellular.cellular_pdcch_power_test as cppt
+
+
+class PowerTelMac_RbSweep_Test(cppt.PowerTelPDCCHTest):
+
+ def test_lte_mac_dl_4_ul_1(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_24_ul_1(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_52_ul_1(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_76_ul_1(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_100_ul_1(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_4_ul_25(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_4_ul_50(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_4_ul_75(self):
+ self.power_pdcch_test()
+
+ def test_lte_mac_dl_4_ul_100(self):
+ self.power_pdcch_test()
\ No newline at end of file
diff --git a/acts_tests/tests/google/power/tel/PowerTelTraffic_RbSweep_Test.py b/acts_tests/tests/google/power/tel/PowerTelTraffic_RbSweep_Test.py
new file mode 100644
index 0000000..a081b87
--- /dev/null
+++ b/acts_tests/tests/google/power/tel/PowerTelTraffic_RbSweep_Test.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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_contrib.test_utils.power.cellular.cellular_traffic_power_test as ctpt
+
+
+class PowerTelTraffic_RbSweep_Test(ctpt.PowerTelTrafficTest):
+
+ def test_lte_direction_dl_8(self):
+ self.power_tel_traffic_test()
+
+ def test_lte_direction_dl_24(self):
+ self.power_tel_traffic_test()
+
+ def test_lte_direction_dl_52(self):
+ self.power_tel_traffic_test()
+
+ def test_lte_direction_dl_76(self):
+ self.power_tel_traffic_test()
+
+ def test_lte_direction_dl_100(self):
+ self.power_tel_traffic_test()
+
+ def test_lte_direction_ul_8(self):
+ self.power_tel_traffic_test()
+
+ def test_lte_direction_ul_25(self):
+ self.power_tel_traffic_test()
+
+ def test_lte_direction_ul_50(self):
+ self.power_tel_traffic_test()
+
+ def test_lte_direction_ul_75(self):
+ self.power_tel_traffic_test()
+
+ def test_lte_direction_ul_100(self):
+ self.power_tel_traffic_test()
diff --git a/acts_tests/tests/google/power/tel/PowerTestPdcch_BandwidthSweep_Test.py b/acts_tests/tests/google/power/tel/PowerTestPdcch_BandwidthSweep_Test.py
new file mode 100644
index 0000000..41086f1
--- /dev/null
+++ b/acts_tests/tests/google/power/tel/PowerTestPdcch_BandwidthSweep_Test.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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_contrib.test_utils.power.cellular.cellular_pdcch_power_test as cppt
+
+
+class PowerTelPdcch_BandwidthSweep_Test(cppt.PowerTelPDCCHTest):
+
+ def test_lte_pdcch_b4_20(self):
+ self.power_pdcch_test()
+
+ def test_lte_pdcch_b4_15(self):
+ self.power_pdcch_test()
+
+ def test_lte_pdcch_b4_10(self):
+ self.power_pdcch_test()
+
+ def test_lte_pdcch_b4_5(self):
+ self.power_pdcch_test()
diff --git a/acts_tests/tests/google/power/tel/PowerTestPdcch_FddBandSweep_Test.py b/acts_tests/tests/google/power/tel/PowerTestPdcch_FddBandSweep_Test.py
new file mode 100644
index 0000000..4d6353b
--- /dev/null
+++ b/acts_tests/tests/google/power/tel/PowerTestPdcch_FddBandSweep_Test.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - 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_contrib.test_utils.power.cellular.cellular_pdcch_power_test as cppt
+
+
+class PowerTelPdcch_FddBandSweep_Test(cppt.PowerTelPDCCHTest):
+
+ def test_lte_pdcch_b1(self):
+ self.power_pdcch_test()
+
+ def test_lte_pdcch_b2(self):
+ self.power_pdcch_test()
+
+ def test_lte_pdcch_b3(self):
+ self.power_pdcch_test()
+
+ def test_lte_pdcch_b4(self):
+ self.power_pdcch_test()
+
+ def test_lte_pdcch_b5(self):
+ self.power_pdcch_test()
+
+ def test_lte_pdcch_b7(self):
+ self.power_pdcch_test()
+
+ def test_lte_pdcch_b8(self):
+ self.power_pdcch_test()
+
+ def test_lte_pdcch_b11(self):
+ self.power_pdcch_test()
+
+ def test_lte_pdcch_b12(self):
+ self.power_pdcch_test()
+
+ def test_lte_pdcch_b13(self):
+ self.power_pdcch_test()
diff --git a/acts_tests/tests/google/power/wifi/PowerWiFiHotspotTest.py b/acts_tests/tests/google/power/wifi/PowerWiFiHotspotTest.py
index 74106c9..7e7c3b8 100644
--- a/acts_tests/tests/google/power/wifi/PowerWiFiHotspotTest.py
+++ b/acts_tests/tests/google/power/wifi/PowerWiFiHotspotTest.py
@@ -17,8 +17,8 @@
import time
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.power import PowerWiFiBaseTest as PWBT
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
from acts_contrib.test_utils.wifi import wifi_power_test_utils as wputils
from acts_contrib.test_utils.power.IperfHelper import IperfHelper
diff --git a/acts_tests/tests/google/tel/etc/manage_sim.py b/acts_tests/tests/google/tel/etc/manage_sim.py
index 91a3887..d848350 100755
--- a/acts_tests/tests/google/tel/etc/manage_sim.py
+++ b/acts_tests/tests/google/tel/etc/manage_sim.py
@@ -67,9 +67,9 @@
'operator'] = tel_lookup_tables.operator_name_from_plmn_id(
plmn_id)
except KeyError:
- if vebose_warnings:
+ if verbose_warnings:
print('Unknown Operator {}'.format(
- droid.telephonyGetSimOperator()))
+ droid.telephonyGetSimOperatorForSubscription(sub_id)))
current['operator'] = ''
# TODO: add actual capability determination to replace the defaults
@@ -83,8 +83,17 @@
iccid))
current['phone_num'] = ''
else:
- current['phone_num'] = tel_test_utils.phone_number_formatter(
- phone_num, tel_defines.PHONE_NUMBER_STRING_FORMAT_11_DIGIT)
+ # No need to set phone number formatter for South Korea carriers
+ if (current['operator'] == tel_defines.CARRIER_SKT or
+ current['operator'] == tel_defines.CARRIER_KT or
+ current['operator'] == tel_defines.CARRIER_LG_UPLUS):
+ current['phone_num'] = \
+ tel_test_utils.phone_number_formatter(phone_num)
+ else:
+ current['phone_num'] = \
+ tel_test_utils.phone_number_formatter(
+ phone_num,
+ tel_defines.PHONE_NUMBER_STRING_FORMAT_11_DIGIT)
return active_list
diff --git a/acts_tests/tests/google/tel/lab/TelLabCmasTest.py b/acts_tests/tests/google/tel/lab/TelLabCmasTest.py
index 4292c87..052adb8 100644
--- a/acts_tests/tests/google/tel/lab/TelLabCmasTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabCmasTest.py
@@ -57,10 +57,10 @@
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_UMTS
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_rat
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts.test_decorators import test_tracker_info
diff --git a/acts_tests/tests/google/tel/lab/TelLabDataRoamingTest.py b/acts_tests/tests/google/tel/lab/TelLabDataRoamingTest.py
index af4ca6c..73e610c 100644
--- a/acts_tests/tests/google/tel/lab/TelLabDataRoamingTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabDataRoamingTest.py
@@ -29,12 +29,12 @@
from acts_contrib.test_utils.tel.anritsu_utils import set_post_sim_params
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_GSM_WCDMA
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_rat
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
from acts_contrib.test_utils.tel.tel_test_utils import toggle_cell_data_roaming
from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_apn_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
from acts.utils import adb_shell_ping
PING_DURATION = 5 # Number of packets to ping
diff --git a/acts_tests/tests/google/tel/lab/TelLabDataTest.py b/acts_tests/tests/google/tel/lab/TelLabDataTest.py
index 9a1355d..7481799 100644
--- a/acts_tests/tests/google/tel/lab/TelLabDataTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabDataTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2016 - The Android Open Source Project
+# Copyright 2022 - 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.
@@ -18,7 +18,6 @@
"""
import time
-import json
import logging
import os
@@ -26,23 +25,13 @@
from acts.controllers.anritsu_lib._anritsu_utils import AnritsuError
from acts.controllers.anritsu_lib.md8475a import MD8475A
from acts.controllers.anritsu_lib.md8475a import BtsBandwidth
-from acts.controllers.anritsu_lib.md8475a import VirtualPhoneStatus
from acts_contrib.test_utils.tel.anritsu_utils import cb_serial_number
-from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_1x
-from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_gsm
from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_lte
-from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_lte_wcdma
-from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_wcdma
-from acts_contrib.test_utils.tel.anritsu_utils import sms_mo_send
-from acts_contrib.test_utils.tel.anritsu_utils import sms_mt_receive_verify
from acts_contrib.test_utils.tel.anritsu_utils import set_usim_parameters
from acts_contrib.test_utils.tel.anritsu_utils import set_post_sim_params
-from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED
-from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_TERMINATED
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_CDMA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GSM_ONLY
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GSM_UMTS
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_GSM_WCDMA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_CDMA_EVDO
from acts_contrib.test_utils.tel.tel_defines import RAT_1XRTT
from acts_contrib.test_utils.tel.tel_defines import RAT_GSM
@@ -52,33 +41,24 @@
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_UMTS
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
-from acts_contrib.test_utils.tel.tel_defines import GEN_4G
from acts_contrib.test_utils.tel.tel_defines import POWER_LEVEL_OUT_OF_SERVICE
from acts_contrib.test_utils.tel.tel_defines import POWER_LEVEL_FULL_SERVICE
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_generation
+from acts_contrib.test_utils.tel.tel_data_utils import check_data_stall_detection
+from acts_contrib.test_utils.tel.tel_data_utils import check_network_validation_fail
+from acts_contrib.test_utils.tel.tel_data_utils import check_data_stall_recovery
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_rat
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.tel_test_utils import get_host_ip_address
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
from acts_contrib.test_utils.tel.tel_test_utils import iperf_test_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
-from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.tel.tel_test_utils import check_data_stall_detection
-from acts_contrib.test_utils.tel.tel_test_utils import check_network_validation_fail
-from acts_contrib.test_utils.tel.tel_test_utils import check_data_stall_recovery
from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
from acts_contrib.test_utils.tel.tel_test_utils import break_internet_except_sl4a_port
from acts_contrib.test_utils.tel.tel_test_utils import resume_internet_with_sl4a_port
-from acts_contrib.test_utils.tel.tel_test_utils import \
- test_data_browsing_success_using_sl4a
-from acts_contrib.test_utils.tel.tel_test_utils import \
- test_data_browsing_failure_using_sl4a
+from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_success_using_sl4a
+from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_failure_using_sl4a
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts.utils import adb_shell_ping
-from acts.utils import rand_ascii_str
-from acts.controllers import iperf_server
-from acts.utils import exe_cmd
DEFAULT_PING_DURATION = 30
diff --git a/acts_tests/tests/google/tel/lab/TelLabEmergencyCallTest.py b/acts_tests/tests/google/tel/lab/TelLabEmergencyCallTest.py
index d83faa3..9042aeb 100644
--- a/acts_tests/tests/google/tel/lab/TelLabEmergencyCallTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabEmergencyCallTest.py
@@ -22,7 +22,6 @@
from acts.controllers.anritsu_lib.md8475a import CsfbType
from acts.controllers.anritsu_lib.md8475a import MD8475A
from acts.controllers.anritsu_lib.md8475a import VirtualPhoneAutoAnswer
-from acts.controllers.anritsu_lib.md8475a import VirtualPhoneStatus
from acts_contrib.test_utils.tel.anritsu_utils import WAIT_TIME_ANRITSU_REG_AND_CALL
from acts_contrib.test_utils.tel.anritsu_utils import call_mo_setup_teardown
from acts_contrib.test_utils.tel.anritsu_utils import ims_call_cs_teardown
@@ -53,16 +52,15 @@
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_GSM_WCDMA
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL_FOR_IMS
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_default_state
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_rat
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_default_state
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_volte
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte
from acts_contrib.test_utils.tel.tel_test_utils import check_apm_mode_on_by_serial
from acts_contrib.test_utils.tel.tel_test_utils import set_apm_mode_on_by_serial
from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_apn_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_volte
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts.test_decorators import test_tracker_info
from acts.utils import exe_cmd
diff --git a/acts_tests/tests/google/tel/lab/TelLabEtwsTest.py b/acts_tests/tests/google/tel/lab/TelLabEtwsTest.py
index 3683173..b3a566c 100644
--- a/acts_tests/tests/google/tel/lab/TelLabEtwsTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabEtwsTest.py
@@ -43,10 +43,10 @@
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_UMTS
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_rat
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts.test_decorators import test_tracker_info
diff --git a/acts_tests/tests/google/tel/lab/TelLabGFTAirplaneModeTest.py b/acts_tests/tests/google/tel/lab/TelLabGFTAirplaneModeTest.py
new file mode 100644
index 0000000..4dcf75c
--- /dev/null
+++ b/acts_tests/tests/google/tel/lab/TelLabGFTAirplaneModeTest.py
@@ -0,0 +1,422 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - 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 signals
+from acts.test_decorators import test_tracker_info
+from acts.libs.utils.multithread import multithread_func
+
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.GFTInOutBaseTest import GFTInOutBaseTest
+from acts_contrib.test_utils.tel.gft_inout_defines import VOICE_CALL
+from acts_contrib.test_utils.tel.gft_inout_utils import check_no_service_time
+from acts_contrib.test_utils.tel.gft_inout_utils import check_back_to_service_time
+from acts_contrib.test_utils.tel.gft_inout_utils import mo_voice_call
+from acts_contrib.test_utils.tel.tel_defines import RAT_3G
+from acts_contrib.test_utils.tel.tel_defines import RAT_4G
+from acts_contrib.test_utils.tel.tel_defines import RAT_5G
+from acts_contrib.test_utils.tel.tel_defines import GEN_3G
+from acts_contrib.test_utils.tel.tel_defines import GEN_4G
+from acts_contrib.test_utils.tel.tel_defines import GEN_5G
+from acts_contrib.test_utils.tel.tel_defines import YOUTUBE_PACKAGE_NAME
+from acts_contrib.test_utils.tel.tel_data_utils import start_youtube_video
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_default_state
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_network_mode_pref
+
+AIRPLANE_MODE_ON_TIME = 60
+AIRPLANE_MODE_OFF_TIME = 60
+MOBILE_DATA_ON_OFF_CASE = 1
+DATA_TRANSFER_CASE = 2
+WIFI_HOTSPOT_CASE = 3
+IN_CALL_CASE = 4
+
+class TelLabGFTAirplaneModeTest(GFTInOutBaseTest):
+ def __init__(self, controllers):
+ GFTInOutBaseTest.__init__(self, controllers)
+
+
+ def setup_test(self):
+ for ad in self.android_devices:
+ ensure_phone_default_state(self.log, ad)
+ GFTInOutBaseTest.setup_test(self)
+ self.my_error_msg = ""
+
+ def teardown_test(self):
+ for ad in self.android_devices:
+ ad.force_stop_apk(YOUTUBE_PACKAGE_NAME)
+ ensure_phones_idle(self.log, self.android_devices)
+
+ @test_tracker_info(uuid="c5d2e9b3-478c-4f86-86e5-c8341944d222")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_airplane_mode_mobile_data_off_3g(self):
+ '''
+ 1.9.5 - 3G Airplane mode on/off - Mobile data off
+
+ Returns:
+ True if pass; False if fail
+ '''
+ tasks = [(self._airplane_mode_helper, (ad, MOBILE_DATA_ON_OFF_CASE, RAT_3G))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("_airplane_mode_data_on_off failure: %s"
+ %(self.my_error_msg))
+ return True
+
+ @test_tracker_info(uuid="22956c54-ab2a-4031-8dfc-95fdb69fb3a6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_airplane_mode_mobile_data_off_4g(self):
+ '''
+ 1.13.5 - 4G Airplane mode on/off - Mobile data off
+
+ Returns:
+ True if pass; False if fail
+ '''
+ tasks = [(self._airplane_mode_helper, (ad, MOBILE_DATA_ON_OFF_CASE, RAT_4G))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("_airplane_mode_data_on_off failure: %s"
+ %(self.my_error_msg))
+ return True
+
+
+ @test_tracker_info(uuid="9ab8e183-6864-4543-855e-4d9a6cb74e42")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_airplane_mode_mobile_data_off_5g(self):
+ '''
+ 1.14.5 - 5G [NSA/SA] Airplane mode on/off - Mobile data off
+
+ Returns:
+ True if pass; False if fail
+ '''
+ tasks = [(self._airplane_mode_helper, (ad, MOBILE_DATA_ON_OFF_CASE, RAT_5G))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("_airplane_mode_data_on_off failure: %s"
+ %(self.my_error_msg))
+ return True
+
+
+ @test_tracker_info(uuid="114afeb6-4c60-4da3-957f-b4b0005223be")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_airplane_mode_voice_call_3g(self):
+ '''
+ 3G 1.9.2 - Airplane mode on/off - Active call
+
+ Returns:
+ True if pass; False if fail
+ '''
+ tasks = [(self._airplane_mode_helper, (ad, IN_CALL_CASE, GEN_3G))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("_airplane_mode_voice_call failure: %s"
+ %(self.my_error_msg))
+ return True
+
+
+ @test_tracker_info(uuid="0e00ca1a-f896-4a18-a3c8-05514975ecd6")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_airplane_mode_voice_call_4g(self):
+ '''
+ 4G 1.13.2 - Airplane mode on/off - Active call
+
+ Returns:
+ True if pass; False if fail
+ '''
+ tasks = [(self._airplane_mode_helper, (ad, IN_CALL_CASE, GEN_4G))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("_airplane_mode_voice_call failure: %s"
+ %(self.my_error_msg))
+ return True
+
+ @test_tracker_info(uuid="cb228d48-78b4-48b4-9996-26ac252a9486")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_airplane_mode_voice_call_5g(self):
+ '''
+ 5G 1.14.2 - [NSA/SA] Airplane mode on/off - Active call
+ For NSA, call goes through IMS over LTE (VoLTE).
+ For SA, call goes through IMS over LTE/NR (EPSFB or VoNR)
+ depends on carrier's implementation.
+
+ Returns:
+ True if pass; False if fail
+ '''
+ tasks = [(self._airplane_mode_helper, (ad, IN_CALL_CASE, GEN_5G))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("_airplane_mode_voice_call failure: %s"
+ %(self.my_error_msg))
+ return True
+
+ def _airplane_mode_mobile_data_off(self, ad):
+ """ Mobile data on/off and airplane mode on/off.
+
+ Args:
+ ad: android_device object.
+
+ Returns:
+ result: True if operation succeed. False if error happens.
+ """
+ # Repeat for 3 cycles.
+ for x in range (3):
+ ad.log.info("Turn off mobile data")
+ ad.droid.telephonyToggleDataConnection(False)
+ if not wait_for_cell_data_connection(self.log, ad, False):
+ self.my_error_msg += "fail to turn off mobile data"
+ return False
+ if not self._airplane_mode_on_off(ad):
+ return False
+ ad.log.info("Turn on mobile data")
+ ad.droid.telephonyToggleDataConnection(True)
+ #If True, it will wait for status to be DATA_STATE_CONNECTED
+ if not wait_for_cell_data_connection(self.log, ad, True):
+ self.my_error_msg += "fail to turn on mobile data"
+ return False
+ # UE turn airplane mode on then off.
+ if not self._airplane_mode_on_off(ad):
+ return False
+ return True
+
+
+ def _airplane_mode_on_off(self, ad):
+ """ Toggle airplane mode on/off.
+
+ Args:
+ ad: android_device object.
+
+ Returns:
+ result: True if operation succeed. False if error happens.
+ """
+ ad.log.info("Turn on airplane mode")
+ if not toggle_airplane_mode(self.log, ad, True):
+ self.my_error_msg += "Fail to enable airplane mode on. "
+ return False
+ time.sleep(AIRPLANE_MODE_ON_TIME)
+ ad.log.info("Turn off airplane mode")
+ if not toggle_airplane_mode(self.log, ad, False):
+ self.my_error_msg += "Fail to enable airplane mode off. "
+ return False
+ time.sleep(AIRPLANE_MODE_OFF_TIME)
+ return True
+
+
+ def _airplane_mode_voice_call(self, ad):
+ """ Airplane mode on/off while in-call.
+
+ Args:
+ ad: android_device object.
+
+ Returns:
+ result: True if operation succeed. False if error happens.
+ """
+ # Repeat for 3 cycles.
+ for x in range (3):
+ ad.log.info("Make a MO call.")
+ if not mo_voice_call(self.log, ad, VOICE_CALL, False):
+ return False
+ self.log.info("turn airplane mode on then off during in call")
+ if not self._airplane_mode_on_off(ad):
+ return False
+ return True
+
+ def _airplane_mode_data_transfer(self, ad):
+ """ Airplane mode on/off while data transfer.
+
+ Args:
+ ad: android_device object.
+
+ Returns:
+ result: True if operation succeed. False if error happens.
+ """
+ # Repeat for 3 cycles.
+ for x in range (3):
+ ad.log.info("Perform a data transferring. Start streaming")
+ if not start_youtube_video(ad):
+ ad.log.warning("Fail to bring up youtube video")
+ self.my_error_msg += "Fail to bring up youtube video. "
+ return False
+ self.log.info("turn airplane mode on then off during data transferring")
+ if not self._airplane_mode_on_off(ad):
+ return False
+ return True
+
+
+ def _airplane_mode_wifi_hotspot(self, ad):
+ """ Airplane mode on/off Wi-Fi hotspot enabled
+
+ Args:
+ ad: android_device object.
+
+ Returns:
+ result: True if operation succeed. False if error happens.
+ """
+ # Repeat for 3 cycles.
+ for x in range (3):
+ ad.log.info("Enable Wi-Fi Hotspot on UE")
+ #if not start_youtube_video(ad):
+ # return False
+ self.log.info("turn airplane mode on then off")
+ if not self._airplane_mode_on_off(ad):
+ return False
+ return True
+
+ def _airplane_mode_helper(self, ad, case= MOBILE_DATA_ON_OFF_CASE, rat=GEN_4G, loop=1):
+ self.log.info("Lock network mode to %s." , rat)
+ if not ensure_network_generation(self.log, ad, rat):
+ raise signals.TestFailure("device fail to register at %s"
+ %(rat))
+
+ for x in range(self.user_params.get("apm_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name,x+1, loop))
+ if case == MOBILE_DATA_ON_OFF_CASE:
+ if not self._airplane_mode_mobile_data_off(ad):
+ return False
+ elif case == DATA_TRANSFER_CASE:
+ if not self._airplane_mode_data_transfer(ad):
+ return False
+ elif case == WIFI_HOTSPOT_CASE:
+ if not self._airplane_mode_wifi_hotspot(ad):
+ return False
+ elif case == IN_CALL_CASE:
+ if not self._airplane_mode_voice_call(ad):
+ return False
+ #check radio function
+ tasks = [(self.verify_device_status, (ad, VOICE_CALL))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("verify_device_status failure: %s"
+ %(self.my_error_msg))
+ return True
+
+ @test_tracker_info(uuid="0205ec77-36c1-478f-9d05-c8a72fffdd03")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_airplane_mode_data_transfer_5g(self):
+ '''
+ 5G - [NSA/SA] Airplane mode on/off - transfer
+ For NSA, call goes through IMS over LTE (VoLTE).
+ For SA, call goes through IMS over LTE/NR (EPSFB or VoNR)
+ depends on carrier's implementation.
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ tasks = [(self._airplane_mode_helper, (ad, DATA_TRANSFER_CASE, GEN_5G))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("_airplane_mode_data_transfer failure: %s"
+ %(self.my_error_msg))
+ return True
+
+ @test_tracker_info(uuid="c76a1154-29c0-4259-bd4c-05279d80537b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_airplane_mode_data_transfer_4g(self):
+ '''
+ 4G - Airplane mode on/off - Data transferring
+
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ tasks = [(self._airplane_mode_helper, (ad, DATA_TRANSFER_CASE, GEN_4G))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("_airplane_mode_data_transfer failure: %s"
+ %(self.my_error_msg))
+ return True
+
+ @test_tracker_info(uuid="c16ea0bb-0155-4f5f-97a8-22c7e0e6e2f5")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_airplane_mode_data_transfer_3g(self):
+ '''
+ 3G - Airplane mode on/off - Data transferring
+
+ Raises:
+ TestFailure if not success.
+
+ Returns:
+ True if pass; False if fail
+ '''
+ tasks = [(self._airplane_mode_helper, (ad, DATA_TRANSFER_CASE, GEN_3G))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("_airplane_mode_data_transfer failure: %s"
+ %(self.my_error_msg))
+ return True
+
+ @test_tracker_info(uuid="b1db4e3b-ea0b-4b61-9f2c-4b8fc251c71a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_airplane_mode_wifi_hotspot_5g(self):
+ '''
+ 5G -[NSA/SA] Airplane mode off/on - Wi-Fi Hotspot enabled
+ For NSA, call goes through IMS over LTE (VoLTE).
+ For SA, call goes through IMS over LTE/NR (EPSFB or VoNR)
+ depends on carrier's implementation.
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ tasks = [(self._airplane_mode_helper, (ad, WIFI_HOTSPOT_CASE, GEN_5G))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("_airplane_mode_wifi_hotspot failure: %s"
+ %(self.my_error_msg))
+ return True
+
+ @test_tracker_info(uuid="f21f4554-7755-4019-b8a2-6f86d1ebd57a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_airplane_mode_wifi_hotspot_4g(self):
+ '''
+ 4G - Airplane mode off/on - Wi-Fi Hotspot enabled
+
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ tasks = [(self._airplane_mode_helper, (ad, WIFI_HOTSPOT_CASE, GEN_4G))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("_airplane_mode_wifi_hotspot failure: %s"
+ %(self.my_error_msg))
+ return True
+
+ @test_tracker_info(uuid="8cf3c617-4534-4b08-b31f-f702c5f8bb8b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_airplane_mode_wifi_hotspot_3g(self):
+ '''
+ 3G - Airplane mode off/on - Wi-Fi Hotspot enabled
+
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ tasks = [(self._airplane_mode_helper, (ad, WIFI_HOTSPOT_CASE, GEN_3G))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("_airplane_mode_wifi_hotspot failure: %s"
+ %(self.my_error_msg))
+ return True
\ No newline at end of file
diff --git a/acts_tests/tests/google/tel/lab/TelLabGFTDSDSInOutServiceTest.py b/acts_tests/tests/google/tel/lab/TelLabGFTDSDSInOutServiceTest.py
new file mode 100644
index 0000000..a4529eb
--- /dev/null
+++ b/acts_tests/tests/google/tel/lab/TelLabGFTDSDSInOutServiceTest.py
@@ -0,0 +1,907 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - 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 datetime
+from acts import asserts
+from acts.test_decorators import test_tracker_info
+from acts.libs.utils.multithread import multithread_func
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.GFTInOutBaseTest import GFTInOutBaseTest
+from acts_contrib.test_utils.tel.gft_inout_utils import mo_voice_call
+from acts_contrib.test_utils.tel.tel_test_utils import wait_for_ims_registered
+from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_test
+from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
+
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_message_subid
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_voice_sub_id
+
+from acts_contrib.test_utils.tel.gft_inout_defines import VOICE_CALL
+from acts_contrib.test_utils.tel.gft_inout_defines import VOLTE_CALL
+from acts_contrib.test_utils.tel.gft_inout_defines import CSFB_CALL
+from acts_contrib.test_utils.tel.gft_inout_defines import WFC_CALL
+from acts_contrib.test_utils.tel.gft_inout_defines import NO_SERVICE_POWER_LEVEL
+from acts_contrib.test_utils.tel.gft_inout_defines import IN_SERVICE_POWER_LEVEL
+from acts_contrib.test_utils.tel.gft_inout_utils import check_ims_state
+from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_service
+
+IDLE_CASE = 1
+DATA_TRANSFER_CASE = 2
+DATA_OFF_CASE = 3
+IN_CALL_CASE = 4
+CALL_DATA_CASE = 5
+_VOLTE = "volte"
+
+class TelLabGFTDSDSInOutServiceTest(GFTInOutBaseTest):
+ def __init__(self, controllers):
+ GFTInOutBaseTest.__init__(self, controllers)
+ self.my_error_msg = ""
+
+ def teardown_test(self):
+ GFTInOutBaseTest.teardown_class(self)
+ ensure_phones_idle(self.log, self.android_devices)
+
+ def _dsds_in_out_service_test(self, case=IDLE_CASE, loop=1, idle_time=60, dds_slot=0,
+ voice_slot=0, sms_slot=0, psim_rat=_VOLTE , esim_rat=_VOLTE):
+ '''
+ b/201599180
+ Move UE from coverage area to no service area and UE shows no service
+ Wait for a period of time, then re-enter coverage area
+
+ Args:
+ case: include IDLE_CAS, DATA_TRANSFER_CASE, DATA_OFF_CASE,
+ IN_CALL_CASE, CALL_DATA_CASE
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ dds_slot: Preferred data slot
+ voice_slot: Preferred voice slot
+ sms_slot: Preferred SMS slot
+ psim_rat: RAT on psim
+ esim_rat: RAT on esim
+ Returns:
+ True if pass; False if fail
+ Raises:
+ TestFailure if not success.
+ '''
+ tasks = [(set_dds_on_slot, (ad, dds_slot )) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ asserts.skip("Fail to to set up DDS")
+ for ad in self.android_devices:
+ voice_sub_id = get_subid_from_slot_index(self.log, ad, voice_slot)
+ if voice_sub_id == INVALID_SUB_ID:
+ asserts.skip("Failed to get sub ID ar slot %s.", voice_slot)
+ else:
+ ad.log.info("get_subid_from_slot_index voice_slot=%s. voice_sub_id=%s"
+ , voice_slot, voice_sub_id)
+ if not set_voice_sub_id(ad, voice_sub_id):
+ ad.log.info("Fail to to set voice to slot %s" , voice_sub_id)
+ else:
+ ad.log.info("set voice to slot %s" , voice_sub_id)
+ tasks = [(set_message_subid, (ad, sms_slot )) for ad in self.android_devices]
+ if multithread_func(self.log, tasks):
+ asserts.skip("Fail to to set up sms to slot %s" , sms_slot)
+ else:
+ ad.log.info("set up sms to slot %s" , sms_slot)
+
+ for x in range (loop):
+ self.log.info("%s loop: %s/%s" , self.current_test_name, x+1, loop))
+ if case == IDLE_CASE:
+ asserts.assert_true(self._dsds_in_out_service_idle_test(idle_time),
+ "Fail: %s." %("_dsds_in_out_service_idle_test failure"),
+ extras={"failure_cause": self.my_error_msg})
+ elif case == DATA_TRANSFER_CASE:
+ asserts.assert_true(self._dsds_in_out_service_data_transfer_test(idle_time),
+ "Fail: %s." %("_dsds_in_out_service_data_transfer_test failure"),
+ extras={"failure_cause": self.my_error_msg})
+ elif case == DATA_OFF_CASE:
+ asserts.assert_true(self._dsds_in_out_service_data_off_test(idle_time),
+ "Fail: %s." %("_dsds_in_out_service_data_off_test failure"),
+ extras={"failure_cause": self.my_error_msg})
+ elif case == IN_CALL_CASE:
+ asserts.assert_true(self._dsds_in_out_service_in_call_test(idle_time),
+ "Fail: %s." %("_dsds_in_out_service_in_call_test failure"),
+ extras={"failure_cause": self.my_error_msg})
+ elif case == CALL_DATA_CASE:
+ asserts.assert_true(self._dsds_in_out_service_in_call_transfer_test(idle_time),
+ "Fail: %s." %("_dsds_in_out_service_in_call_transfer_test failure"),
+ extras={"failure_cause": self.my_error_msg})
+
+ tasks = [(wait_for_network_service, (self.log, ad, ))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ asserts.assert_true(False, "Fail: %s." %("wait_for_network_service failure"),
+ extras={"failure_cause": self.my_error_msg})
+ tasks = [(self.verify_device_status, (ad, VOICE_CALL))
+ for ad in self.android_devices]
+ asserts.assert_true(multithread_func(self.log, tasks),
+ "Fail: %s." %("verify_device_status failure"),
+ extras={"failure_cause": self.my_error_msg})
+ return True
+
+ def _dsds_in_out_service_idle_test(self, idle_time=60):
+ '''
+ (1) UE is in idle
+ (2) Move UE from coverage area to no service area and UE shows no service
+ (3) Wait for a period of time, then re-enter coverage area
+
+ Args:
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ return self._in_out_service_idle(idle_time)
+
+
+ def _dsds_in_out_service_in_call_transfer_test(self, idle_time=60):
+ '''
+ (1) UE is performing data transfer (E.g. Use FTP or browse tools)
+ (2) UE makes a MO call
+ (3) Move UE from coverage area to no service area and UE shows no service
+ (4) Wait for a period of time, then re-enter coverage area
+
+ Args:
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ error_msg = ""
+ tasks_a = [(active_file_download_test, (self.log, ad, )) for ad in self.android_devices]
+ tasks_b= [(mo_voice_call, (self.log, ad, VOICE_CALL, False)) for ad in self.android_devices]
+ tasks_b.extend(tasks_a)
+ if not multithread_func(self.log, tasks_b):
+ error_msg = "fail to perfrom data transfer/voice call"
+ self.my_error_msg += error_msg
+ return False
+ self._in_out_service_idle(idle_time)
+ return True
+
+ def _dsds_in_out_service_in_call_test(self, idle_time=60):
+ '''
+ (1) UE is in call
+ (2) Move UE from coverage area to no service area and UE shows no service
+ (3) Wait for a period of time, then re-enter coverage area
+
+ Args:
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ error_msg = ""
+ tasks = [(mo_voice_call, (self.log, ad, VOICE_CALL, False)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ error_msg = "MO voice call fail"
+ self.my_error_msg += error_msg
+ self.log.error(error_msg)
+ return False
+ return self._in_out_service_idle(idle_time)
+
+ def _dsds_in_out_service_data_off_test(self, idle_time=60):
+ '''
+ (1) Disable UE mobile data
+ (2) Move UE from coverage area to no service area and UE shows no service
+ (3) Wait for a period of time, then re-enter coverage area
+
+ Args:
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ for ad in self.android_devices:
+ ad.log.info("Turn off mobile data")
+ ad.droid.telephonyToggleDataConnection(False)
+ if not wait_for_cell_data_connection(self.log, ad, False):
+ self.my_error_msg += "fail to turn off mobile data"
+ return False
+ self._in_out_service_idle(idle_time)
+ for ad in self.android_devices:
+ ad.log.info("Turn on mobile data")
+ ad.droid.telephonyToggleDataConnection(True)
+ #If True, it will wait for status to be DATA_STATE_CONNECTED
+ if not wait_for_cell_data_connection(self.log, ad, True):
+ self.my_error_msg += "fail to turn on mobile data"
+ return False
+ return True
+
+ def _dsds_in_out_service_data_transfer_test(self, idle_time=60, file_name="10MB"):
+ '''
+ (1) UE is performing data transfer (E.g. Use FTP or browse tools)
+ (2) Move UE from coverage area to no service area and UE shows no service
+ (3) Wait for 1 min, then re-enter coverage area
+
+ Args:
+ idle_time: idle time at no service area
+ file_name:
+ Returns:
+ True if pass; False if fail
+ Raises:
+ TestFailure if not success.
+ '''
+ tasks_a = [(self._in_out_service_idle, (idle_time))]
+ tasks_b = [(active_file_download_test, (self.log, ad, file_name))
+ for ad in self.android_devices]
+ tasks_b.extend(tasks_a)
+ if not multithread_func(self.log, tasks_b):
+ error_msg = " data transfer fail. "
+ self.my_error_msg += error_msg
+ self.log.error(error_msg)
+ tasks = [(self.verify_device_status, (ad, VOICE_CALL))
+ for ad in self.android_devices]
+ asserts.assert_true(multithread_func(self.log, tasks), "Fail: %s."
+ %("verify_device_status failure"), extras={"failure_cause":
+ self.my_error_msg})
+ return True
+
+ def _in_out_service_idle(self, idle_time):
+ '''
+ adjust cellular signal
+
+ Args:
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(idle_time)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ return True
+
+
+
+ @test_tracker_info(uuid="053465d8-a682-404c-a0fb-8e79f6ca581d")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_idle_msim_4g_esim_4g_dds_sim1_1min(self, loop=50, idle_time=60):
+ '''
+ 1.8.17 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary idle mode - 1 min
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IDLE_CASE, loop, idle_time, 0)
+
+
+ @test_tracker_info(uuid="1ba35ced-41d1-456d-84e2-a40a0d7402b2")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_idle_msim_4g_esim_4g_dds_sim2_1min(self, loop=50, idle_time=60):
+ '''
+ 1.8.18 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary idle mode - 1 min
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IDLE_CASE, loop, idle_time, 1)
+
+ @test_tracker_info(uuid="53697dd9-a2f6-4eb5-8b2c-5c9f2a5417ad")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_idle_msim_4g_esim_4g_dds_sim1_2min(self, loop=1,
+ idle_time=120):
+ '''
+ 1.8.19 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service
+ Stationary idle mode - 2 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IDLE_CASE, loop, idle_time, 0)
+
+ @test_tracker_info(uuid="f329bb22-c74f-4688-9983-eaf88131a630")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_idle_msim_4g_esim_4g_dds_sim2_2min(self, loop=1,
+ idle_time=120):
+ '''
+ 1.8.20 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary idle mode - 2 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IDLE_CASE, loop, idle_time, 1)
+
+ @test_tracker_info(uuid="4d8cba59-921b-441c-94dc-8c43a12593ea")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_idle_msim_4g_esim_4g_dds_sim1_5min(self, loop=1,
+ idle_time=300):
+ '''
+ 1.8.21 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary idle mode - 5 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IDLE_CASE, loop, idle_time, 0)
+
+ @test_tracker_info(uuid="dfb3646f-b21f-41f4-a70b-f7ca93ff56ec")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_idle_msim_4g_esim_4g_dds_sim2_5min(self, loop=1,
+ idle_time=300):
+ '''
+ 1.8.22 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary idle mode - 5 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IDLE_CASE, loop, idle_time, 1)
+
+
+ @test_tracker_info(uuid="95e026e1-8f3e-4b9e-8d13-96a2d3be2d23")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_idle_msim_4g_esim_4g_dds_sim1_10min(self, loop=1,
+ idle_time=600):
+ '''
+ 1.8.23 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary idle mode - 10 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IDLE_CASE, loop, idle_time, 0)
+
+ @test_tracker_info(uuid="935ed9be-94ef-4f46-b742-4bfac16b876d")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_idle_msim_4g_esim_4g_dds_sim2_10min(self, loop=1,
+ idle_time=600):
+ '''
+ 1.8.24 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary idle mode - 10 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IDLE_CASE, loop, idle_time, 1)
+
+
+ @test_tracker_info(uuid="919e478e-6ea4-4bdc-b7d8-0252c7fa1510")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_4g_esim_4g_dds_sim1_1min(
+ self, loop=20, idle_time=60):
+ '''
+ 1.8.25 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary data transfer - 1 min
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(DATA_TRANSFER_CASE, loop, idle_time, 0)
+
+ @test_tracker_info(uuid="0826b234-7619-4ad9-b1e9-81d4d7e51be4")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_4g_esim_4g_dds_sim2_1min(
+ self, loop=20, idle_time=60):
+ '''
+ 1.8.26 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary data transfer - 1 min
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(DATA_TRANSFER_CASE, loop, idle_time, 1)
+
+
+ @test_tracker_info(uuid="baf5a72d-2a44-416b-b50d-80a4e6d75373")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_4g_esim_4g_dds_sim1_2min(
+ self, loop=20, idle_time=120):
+ '''
+ 1.8.27 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary data transfer - 2 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(DATA_TRANSFER_CASE, loop, idle_time, 0)
+
+
+ @test_tracker_info(uuid="e74bbe30-6ced-4122-8088-3f7f7bcd35d1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_4g_esim_4g_dds_sim2_2min(
+ self, loop=20, idle_time=120):
+ '''
+ 1.8.28 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary data transfer - 2 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(DATA_TRANSFER_CASE, loop, idle_time, 1)
+
+
+ @test_tracker_info(uuid="d605bdc1-c262-424b-aa05-dd64db0f150d")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_4g_esim_4g_dds_sim1_5min(
+ self, loop=20, idle_time=300):
+ '''
+ 1.8.29 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary data transfer - 5 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(DATA_TRANSFER_CASE, loop, idle_time, 0)
+
+
+ @test_tracker_info(uuid="590f6292-c19e-44f9-9050-8e4ad6ef0047")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_4g_esim_4g_dds_sim2_5min(
+ self, loop=20, idle_time=300):
+ '''
+ 1.8.30 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary data transfer - 5 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(DATA_TRANSFER_CASE, loop, idle_time, 1)
+
+
+ @test_tracker_info(uuid="6d4c631d-d4b1-4974-bcf5-f63d655a43d8")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_4g_esim_4g_dds_sim1_10min(
+ self, loop=20, idle_time=600):
+ '''
+ 1.8.31 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary data transfer - 10 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(DATA_TRANSFER_CASE, loop, idle_time, 0)
+
+ @test_tracker_info(uuid="ec4c4b08-d306-4d95-af07-485953afe741")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_4g_esim_4g_dds_sim2_10min(
+ self, loop=20, idle_time=600):
+ '''
+ 1.8.32 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary data transfer - 10 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(DATA_TRANSFER_CASE, loop, idle_time, 1)
+
+
+
+ @test_tracker_info(uuid="9a3827bd-132b-42de-968d-802b7e2e22cc")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_off_msim_4g_esim_4g_dds_sim1_1min(self, loop=50, idle_time=60):
+ '''
+ 1.8.33 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary data off - 1 min
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(DATA_OFF_CASE, loop, idle_time, 0)
+
+ @test_tracker_info(uuid="4c42e33b-188c-4c62-8def-f47c46a07555")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_off_msim_4g_esim_4g_dds_sim1_2min(self, loop=50, idle_time=120):
+ '''
+ 1.8.34 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary data off - 2 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(DATA_OFF_CASE, loop, idle_time, 0)
+
+ @test_tracker_info(uuid="d40ee1cb-0e63-43f4-8b45-6a3a9bc1fcaa")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_off_msim_4g_esim_4g_dds_sim1_5min(self, loop=10, idle_time=300):
+ '''
+ 1.8.35 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary data off - 5 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(DATA_OFF_CASE, loop, idle_time, dds_slot=0)
+
+
+ @test_tracker_info(uuid="a0bb09bf-36c2-45cc-91d3-5441fd90a2ee")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_off_msim_4g_esim_4g_dds_sim1_10min(self, loop=10, idle_time=600):
+ '''
+ 1.8.36 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary data off - 10 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(DATA_OFF_CASE, loop, idle_time, dds_slot=0)
+
+
+ @test_tracker_info(uuid="d267f0bb-427a-4bed-9d78-20dbc193588f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_in_call_msim_4g_esim_4g_dds_sim1_call_sim1_1min(self, loop=10, idle_time=60):
+ '''
+ 1.8.37 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall - 1 min
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IN_CALL_CASE, loop, idle_time, dds_slot=0,
+ voice_slot=0, sms_slot=0)
+
+ @test_tracker_info(uuid="f0fcfc8f-4867-4b3c-94b8-4b406fa4ce8f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_in_call_msim_4g_esim_4g_dds_sim2_call_sim2_1min(self, loop=10, idle_time=60):
+ '''
+ 1.8.38 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall - 1 min
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IN_CALL_CASE, loop, idle_time,
+ dds_slot=1, voice_slot=1, sms_slot=1)
+
+ @test_tracker_info(uuid="5f96c891-fdb3-4367-afba-539eeb57ff0f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_in_call_msim_4g_esim_4g_dds_sim1_call_sim1_2min(self, loop=10, idle_time=120):
+ '''
+ 1.8.39 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall - 2 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IN_CALL_CASE, loop, idle_time,
+ dds_slot=0, voice_slot=0, sms_slot=0)
+
+
+ @test_tracker_info(uuid="3920a8b7-492b-4bc4-9b3d-6d7df9861934")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_in_call_msim_4g_esim_4g_dds_sim2_call_sim2_2min(self, loop=10, idle_time=120):
+ '''
+ 1.8.40 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall - 2 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IN_CALL_CASE, loop, idle_time,
+ dds_slot=1, voice_slot=1, sms_slot=1)
+
+
+ @test_tracker_info(uuid="b8fac57b-fdf8-48e6-a51f-349a512d2df7")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_in_call_msim_4g_esim_4g_dds_sim1_call_sim1_5min(self, loop=10, idle_time=300):
+ '''
+ 1.8.41 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall - 5 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IN_CALL_CASE, loop, idle_time,
+ dds_slot=0, voice_slot=0, sms_slot=0)
+
+ @test_tracker_info(uuid="0f0f7749-5cf8-4030-aae5-d28cb3a26d9b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_in_call_msim_4g_esim_4g_dds_sim2_call_sim2_5min(self, loop=10,
+ idle_time=300):
+ '''
+ 1.8.42 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall - 5 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IN_CALL_CASE, loop, idle_time,
+ dds_slot=1, voice_slot=1, sms_slot=1)
+
+
+ @test_tracker_info(uuid="53c8bc90-b9a6-46c7-a412-fe5b9f8df3c3")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_in_call_msim_4g_esim_4g_dds_sim1_call_sim1_10min(self, loop=10,
+ idle_time=600):
+ '''
+ 1.8.43 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall - 10 mins
+ (1) SIM1 (pSIM): Carrier1, VoLTE
+ (2) SIM2 (eSIM): Carrier2, VoLTE
+ (3) DDS (Data preferred) on SIM1
+ (4) Call/SMS Preference: on SIM1
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IN_CALL_CASE, loop, idle_time,
+ dds_slot=0, voice_slot=0, sms_slot=0)
+
+ @test_tracker_info(uuid="cff1893e-ea14-4e32-83ae-9116ffd96da4")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_in_call_msim_4g_esim_4g_dds_sim2_call_sim2_10min(self, loop=10,
+ idle_time=600):
+ '''
+ 1.8.44 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall - 10 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(IN_CALL_CASE, loop, idle_time,
+ dds_slot=1, voice_slot=1, sms_slot=1)
+
+
+ @test_tracker_info(uuid="a73d70d2-d5dd-4901-8cfe-6e54bdd4ddc3")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_call_data_msim_4g_esim_4g_dds_sim1_call_sim1_1min(self, loop=10,
+ idle_time=60):
+ '''
+ 1.8.45 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall + data transfer - 1 min
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(CALL_DATA_CASE, loop, idle_time,
+ dds_slot=0, voice_slot=0, sms_slot=0)
+
+
+ @test_tracker_info(uuid="6d331e0e-368d-4752-810c-ad497ccb0001")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_call_data_msim_4g_esim_4g_dds_sim2_call_sim2_1min(self, loop=10, idle_time=60):
+ '''
+ 1.8.46 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall + data transfer - 1 min
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(CALL_DATA_CASE, loop, idle_time,
+ dds_slot=1, voice_slot=1, sms_slot=1)
+
+
+
+ @test_tracker_info(uuid="2b4c5912-f654-45ad-8195-284c602c194f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_call_data_msim_4g_esim_4g_dds_sim1_call_sim1_2min(self, loop=10,
+ idle_time=120):
+ '''
+ 1.8.47 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall + data transfer - 2 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(CALL_DATA_CASE, loop, idle_time,
+ dds_slot=0, voice_slot=0, sms_slot=0)
+
+
+ @test_tracker_info(uuid="d0428b18-6c5b-42d9-96fd-423a0512b95e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_call_data_msim_4g_esim_4g_dds_sim2_call_sim2_2min(self, loop=10,
+ idle_time=120):
+ '''
+ 1.8.48 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall + data transfer - 2 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(CALL_DATA_CASE, loop, idle_time,
+ dds_slot=1, voice_slot=1, sms_slot=1)
+
+
+
+ @test_tracker_info(uuid="66b2ec18-d2f8-46b3-8626-0688f4f7c0dc")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_call_data_msim_4g_esim_4g_dds_sim1_call_sim1_5min(self, loop=10,
+ idle_time=300):
+ '''
+ 1.8.49 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall + data transfer - 5 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(CALL_DATA_CASE, loop, idle_time,
+ dds_slot=0, voice_slot=0, sms_slot=0)
+
+
+ @test_tracker_info(uuid="4634689f-3ab5-4826-9057-668b0fe15402")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_call_data_msim_4g_esim_4g_dds_sim2_call_sim2_5min(self, loop=10,
+ idle_time=300):
+ '''
+ 1.8.50 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall + data transfer - 5 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(CALL_DATA_CASE, loop, idle_time,
+ dds_slot=1, voice_slot=1, sms_slot=1)
+
+
+ @test_tracker_info(uuid="5a097f66-dbd4-49d4-957c-d0e9584de36b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_call_data_msim_4g_esim_4g_dds_sim1_call_sim1_10min(self, loop=10,
+ idle_time=600):
+ '''
+ 1.8.51 - [DDS:SIM1][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall + data transfer - 10 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(CALL_DATA_CASE, loop, idle_time,
+ dds_slot=0, voice_slot=0, sms_slot=0)
+
+
+ @test_tracker_info(uuid="d99c0700-27b1-4b0c-881b-ccf908a70287")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_call_data_msim_4g_esim_4g_dds_sim2_call_sim2_10min(self, loop=10,
+ idle_time=600):
+ '''
+ 1.8.52 - [DDS:SIM2][SIM1:VoLTE, SIM2:VoLTE] In/Out service -
+ Stationary incall + data transfer - 10 mins
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: idle time at no service area
+ Returns:
+ True if pass; False if fail
+ '''
+ loop = self.user_params.get("4g_dsds_io_cycle", 1)
+ return self._dsds_in_out_service_test(CALL_DATA_CASE, loop, idle_time,
+ dds_slot=1, voice_slot=1, sms_slot=1)
\ No newline at end of file
diff --git a/acts_tests/tests/google/tel/lab/TelLabGFTDSDSTest.py b/acts_tests/tests/google/tel/lab/TelLabGFTDSDSTest.py
new file mode 100644
index 0000000..a0f0d3b
--- /dev/null
+++ b/acts_tests/tests/google/tel/lab/TelLabGFTDSDSTest.py
@@ -0,0 +1,465 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - 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 datetime
+from acts import asserts
+from acts.test_decorators import test_tracker_info
+
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.GFTInOutBaseTest import GFTInOutBaseTest
+from acts_contrib.test_utils.tel.gft_inout_defines import NO_SERVICE_POWER_LEVEL
+from acts_contrib.test_utils.tel.gft_inout_defines import IN_SERVICE_POWER_LEVEL
+from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
+from acts_contrib.test_utils.tel.tel_data_utils import start_youtube_video
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_0
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_1
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_dsds_utils import dsds_voice_call_test
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_0
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_1
+
+
+_5G_VOLTE = "5g_volte"
+_VOLTE = "volte"
+_NO_SERVICE_TIME = 30
+_ERROR_MSG_DATA_TRANSFER_FAILURE = "_test_in_out_service_data_transfer failure"
+_ERROR_MSG_IDLE_FAILURE = "_test_in_out_service_idle failure"
+
+class TelLabGFTDSDSTest(GFTInOutBaseTest):
+ def __init__(self, controllers):
+ # requirs 2 android devices to run DSDS test
+ GFTInOutBaseTest.__init__(self, controllers)
+ self.tel_logger = TelephonyMetricLogger.for_test_case()
+ self.my_error_msg = ""
+
+ def teardown_test(self):
+ GFTInOutBaseTest.teardown_class(self)
+ ensure_phones_idle(self.log, self.android_devices)
+
+ @test_tracker_info(uuid="90ef8e20-64bb-4bf8-81b6-431de524f2af")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_msim_5g_esim_5g_dds_sim1(self, loop=1):
+ '''
+ 1.7.19 - [SA/NSA][DDS:SIM1][SIM1:5G, SIM2:5G]
+ Attach to 5G after in/out service during idle
+ SIM1 (pSIM) : Carrier 1 with 5G SIM.
+ SIM2 (eSIM) : Carrier 2 with 5G SIM.
+ DDS (Data preferred) on SIM1 and this slot has the 5G capability.
+
+ (1) Moves to no service area during data idle.
+ (2) Moves to service area.
+ (3) Makes a MOMT voice/VT call on SIM1.
+ (4) Makes a MOMT voice/VT call on SIM2.
+ (5) Starts streaming.
+ Args:
+ loop: repeat this test cases for how many times
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("dsds_io_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ asserts.assert_true(
+ self._test_in_out_service_idle(_5G_VOLTE, _5G_VOLTE, 0),
+ "[Fail]%s" % (_ERROR_MSG_IDLE_FAILURE),
+ extras={"failure_cause": self.my_error_msg})
+ return True
+
+
+ @test_tracker_info(uuid="21b3ff34-e42a-4d42-ba98-87c510e83967")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_msim_5g_esim_5g_dds_sim2(self, loop=1):
+ '''
+ 1.7.20 [SA/NSA][DDS:SIM2][SIM1:5G, SIM2:5G]
+ Attach to 5G after in/out service during idle.
+ SIM1 (pSIM) : Carrier 1 with 5G SIM.
+ SIM2 (eSIM) : Carrier 2 with 5G SIM.
+ DDS (Data preferred) on SIM2
+
+ (1) Moves to no service area during data idle.
+ (2) Moves to service area.
+ (3) Makes a MOMT voice/VT call on SIM2.
+ (4) Makes a MOMT voice/VT call on SIM1.
+ (5) Starts streaming.
+
+ Args:
+ loop: repeat this test cases for how many times
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("dsds_io_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ asserts.assert_true(
+ self._test_in_out_service_idle(_5G_VOLTE, _5G_VOLTE, 1),
+ "[Fail]%s" % (_ERROR_MSG_IDLE_FAILURE),
+ extras={"failure_cause": self.my_error_msg})
+ return True
+
+
+ @test_tracker_info(uuid="f1311823-e6e4-478e-a38d-2344389698b7")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_msim_4g_esim_5g_dds_sim1(self, loop=1):
+ '''
+ 1.7.21 - [SA/NSA][DDS:SIM1][SIM1:VoLTE, SIM2:5G]
+ Attach to 5G after in/out service during idle
+ SIM1 (pSIM) : Carrier 1 with 4G SIM or 5G SIM locks in 4G.
+ SIM2 (eSIM) : Carrier 2 with 5G SIM.
+ DDS (Data preferred) on SIM1.
+
+ (1) Move to no service area during data idle.
+ (2) Moves to service area.
+ (3) Makes a MOMT voice/VT call on SIM1.
+ (4) Makes a MOMT voice/VT call on SIM2.
+ (5) Starts streaming.
+
+ Args:
+ loop: repeat this test cases for how many times
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("dsds_io_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ asserts.assert_true(
+ self._test_in_out_service_idle(_VOLTE, _5G_VOLTE, 0),
+ "[Fail]%s" % (_ERROR_MSG_IDLE_FAILURE),
+ extras={"failure_cause": self.my_error_msg})
+ return True
+
+
+ @test_tracker_info(uuid="7dc38fd5-741f-42b0-a476-3aa51610d184")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_msim_4g_esim_5g_dds_sim2(self, loop=1):
+ '''
+ 1.7.22 - [SA/NSA][DDS:SIM2][SIM1:VoLTE, SIM2:5G]
+ Attach to 5G after in/out service during idle
+ SIM1 (pSIM) : Carrier 1 with 4G SIM or 5G SIM locks in 4G.
+ SIM2 (eSIM) : Carrier 2 with 5G SIM.
+ DDS (Data preferred) on SIM2.
+
+ (1) Moves to no service area during data idle.
+ (2) Moves to service area.
+ (3) Makes a MOMT voice/VT call on SIM2.
+ (4) Makes a MOMT voice/VT call on SIM1.
+ (5) Starts streaming.
+
+ Args:
+ loop: repeat this test cases for how many times
+ Returns:
+ True if pass; False if fail
+ Raises:
+ TestFailure if not success.
+ '''
+ for x in range(self.user_params.get("dsds_io_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ asserts.assert_true(
+ self._test_in_out_service_idle(_VOLTE, _5G_VOLTE, 1),
+ "[Fail]%s" % (_ERROR_MSG_IDLE_FAILURE),
+ extras={"failure_cause": self.my_error_msg})
+ return True
+
+ @test_tracker_info(uuid="a47cdaf6-87b6-416e-a0e4-ebdd2ec5f3f1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_msim_5g_esim_4g_dds_sim1(self, loop=1):
+ '''
+ 1.7.23 - [SA/NSA][DDS:SIM1][SIM1:5G, SIM2:VoLTE]
+ Attach to 5G after in/out service during idle
+ SIM1 (pSIM) : Carrier 1 with 5G SIM.
+ SIM2 (eSIM) : Carrier 2 with 4G SIM
+ DDS (Data preferred) on SIM1.
+
+ (1) Moves to no service area during data idle.
+ (2) Moves to service area.
+ (3) Makes a MOMT voice/VT call on SIM1.
+ (4) Makes a MOMT voice/VT call on SIM2.
+ (5) Starts streaming.
+
+ Args:
+ loop: repeat this test cases for how many times
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("dsds_io_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ asserts.assert_true(
+ self._test_in_out_service_idle(_5G_VOLTE, _VOLTE, 0),
+ "[Fail]%s" % (_ERROR_MSG_IDLE_FAILURE),
+ extras={"failure_cause": self.my_error_msg})
+ return True
+
+
+ @test_tracker_info(uuid="5e2e3ce2-6d37-48dd-9007-6aa3f593150b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_msim_5g_esim_4g_dds_sim2(self, loop=1):
+ '''
+ 1.7.24 - [SA/NSA][DDS:SIM2][SIM1:5G, SIM2:VoLTE]
+ Attach to 5G after in/out service during idle
+ SIM1 (pSIM) : Carrier 1 with 5G SIM.
+ SIM2 (eSIM) : Carrier 2 with 4G SIM
+ DDS (Data preferred) on SIM1.
+
+ (1) Moves to no service area during data idle.
+ (2) Moves to service area.
+ (3) Makes a MOMT voice/VT call on SIM1.
+ (4) Makes a MOMT voice/VT call on SIM2.
+ (5) Starts streaming.
+
+ Args:
+ loop: repeat this test cases for how many times
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("dsds_io_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ asserts.assert_true(
+ self._test_in_out_service_idle(_5G_VOLTE, _VOLTE, 1),
+ "[Fail]%s" % (_ERROR_MSG_IDLE_FAILURE),
+ extras={"failure_cause": self.my_error_msg})
+ return True
+
+
+ @test_tracker_info(uuid="51f291f0-af5f-400c-9678-4f129695bb68")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_5g_esim_5g_dds_sim1(self, loop=1):
+ '''
+ 1.7.25 - [SA/NSA][DDS:SIM1][SIM1:5G, SIM2:5G]
+ Attach to 5G after in/out service during data transferring
+ SIM1 (pSIM) : Carrier 1 with 5G SIM.
+ SIM2 (eSIM) : Carrier 2 with 5G SIM
+ DDS (Data preferred) on SIM1.
+
+ (1) Moves to no service area during data transferring..
+ (2) Moves to service area.
+ (3) Makes a MOMT voice/VT call on SIM1.
+ (4) Makes a MOMT voice/VT call on SIM2.
+ (5) Starts streaming.
+
+ Args:
+ loop: repeat this test cases for how many times
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("dsds_io_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ asserts.assert_true(
+ self._test_in_out_service_data_transfer(_5G_VOLTE, _5G_VOLTE, 0),
+ "[Fail]%s" % (_ERROR_MSG_DATA_TRANSFER_FAILURE),
+ extras={"failure_cause": self.my_error_msg})
+ return True
+
+
+ @test_tracker_info(uuid="d0b134c5-380f-4c74-8ab9-8322de1c59e9")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_5g_esim_5g_dds_sim2(self, loop=1):
+ '''
+ 1.7.26 - [SA/NSA][DDS:SIM2][SIM1:5G, SIM2:5G]
+ Attach to 5G after in/out service during data transferring
+ SIM1 (pSIM) : Carrier 1 with 5G SIM.
+ SIM2 (eSIM) : Carrier 2 with 5G SIM
+ DDS (Data preferred) on SIM2.
+
+ (1) Moves to no service area during data transferring..
+ (2) Moves to service area.
+ (3) Makes a MOMT voice/VT call on SIM1.
+ (4) Makes a MOMT voice/VT call on SIM2.
+ (5) Starts streaming.
+
+ Args:
+ loop: repeat this test cases for how many times
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("dsds_io_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ asserts.assert_true(
+ self._test_in_out_service_data_transfer(_VOLTE, _5G_VOLTE, 1),
+ "[Fail]%s" % (_ERROR_MSG_DATA_TRANSFER_FAILURE),
+ extras={"failure_cause": self.my_error_msg})
+ return True
+
+
+ @test_tracker_info(uuid="c28a9ea5-28a8-4d21-ba25-cb38aca30170")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_4g_esim_5g_dds_sim1(self, loop=1):
+ '''
+ 1.7.27 - [SA/NSA][DDS:SIM1][SIM1:VoLTE, SIM2:5G]
+ Attach to 5G after in/out service during data transferring
+ SIM1 (pSIM) : Carrier 1 with 4G SIM.
+ SIM2 (eSIM) : Carrier 2 with 5G SIM
+ DDS (Data preferred) on SIM1.
+
+ (1) Moves to no service area during data transferring..
+ (2) Moves to service area.
+ (3) Makes a MOMT voice/VT call on SIM1.
+ (4) Makes a MOMT voice/VT call on SIM2.
+ (5) Starts streaming.
+
+ Args:
+ loop: repeat this test cases for how many times
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("dsds_io_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ asserts.assert_true(
+ self._test_in_out_service_data_transfer(_VOLTE, _5G_VOLTE, 0),
+ "[Fail]%s" % (_ERROR_MSG_DATA_TRANSFER_FAILURE),
+ extras={"failure_cause": self.my_error_msg})
+ return True
+
+
+ @test_tracker_info(uuid="c28a9ea5-28a8-4d21-ba25-cb38aca30170")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_4g_esim_5g_dds_sim2(self, loop=1):
+ '''
+ 1.7.28 - [SA/NSA][DDS:SIM2][SIM1:VoLTE, SIM2:5G]
+ Attach to 5G after in/out service during data transferring
+ SIM1 (pSIM) : Carrier 1 with 4G SIM.
+ SIM2 (eSIM) : Carrier 2 with 5G SIM
+ DDS (Data preferred) on SIM2.
+
+ (1) Moves to no service area during data transferring..
+ (2) Moves to service area.
+ (3) Makes a MOMT voice/VT call on SIM1.
+ (4) Makes a MOMT voice/VT call on SIM2.
+ (5) Start a download via speedtest lab mode.
+
+ Args:
+ loop: repeat this test cases for how many times
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("dsds_io_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ asserts.assert_true(
+ self._test_in_out_service_data_transfer(_VOLTE, _5G_VOLTE, 1),
+ "[Fail]%s" % (_ERROR_MSG_DATA_TRANSFER_FAILURE),
+ extras={"failure_cause": self.my_error_msg})
+ return True
+
+ @test_tracker_info(uuid="7d6a85c0-0194-4705-8a80-49f21cebc4ed")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_5g_esim_4g_dds_sim1(self, loop=1):
+ '''
+ 1.7.29 - [SA/NSA][DDS:SIM1][SIM1:5G, SIM2:VoLTE]
+ Attach to 5G after in/out service during data transferring
+ SIM1 (pSIM) : Carrier 1 with 5G SIM.
+ SIM2 (eSIM) : Carrier 2 with 4G SIM
+ DDS (Data preferred) on SIM1.
+
+ (1) Move to no service area during data transferring..
+ (2) Move to service area.
+ (3) Make a MOMT voice/VT call on SIM1.
+ (4) Makes a MOMT voice/VT call on SIM2.
+ (5) Starts streaming.
+
+ Args:
+ loop: repeat this test cases for how many times
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("dsds_io_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ asserts.assert_true(
+ self._test_in_out_service_data_transfer(_5G_VOLTE, _VOLTE, 0),
+ "[Fail]%s" % (_ERROR_MSG_DATA_TRANSFER_FAILURE),
+ extras={"failure_cause": self.my_error_msg})
+ return True
+
+
+ @test_tracker_info(uuid="43cd405f-d510-4193-9bff-795db12dbb30")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_data_transfer_msim_5g_esim_4g_dds_sim2(self, loop=1):
+ '''
+ 1.7.30 - [SA/NSA][DDS:SIM2][SIM1:5G, SIM2:VoLTE]
+ Attach to 5G after in/out service during data transferring
+ SIM1 (pSIM) : Carrier 1 with 5G SIM.
+ SIM2 (eSIM) : Carrier 2 with 4G SIM
+ DDS (Data preferred) on SIM2.
+
+ (1) Move to no service area during data transferring..
+ (2) Move to service area.
+ (3) Make a MOMT voice/VT call on SIM1.
+ (4) Make a MOMT voice/VT call on SIM2.
+ (5) start streaming.
+
+ Args:
+ loop: repeat this test cases for how many times
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("dsds_io_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ asserts.assert_true(
+ self._test_in_out_service_data_transfer(_5G_VOLTE, _VOLTE, 1),
+ "[Fail]%s" % (_ERROR_MSG_DATA_TRANSFER_FAILURE),
+ extras={"failure_cause": self.my_error_msg})
+ return True
+
+
+ def _test_in_out_service_idle(self, psim_rat=_5G_VOLTE , esim_rat=_5G_VOLTE,
+ dds_slot=0, momt_direction="mo"):
+ ad = self.android_devices[0]
+ set_dds_on_slot(ad, dds_slot)
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(_NO_SERVICE_TIME)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ return self._test_mo_voice_call(psim_rat, esim_rat, dds_slot, momt_direction)
+
+
+ def _test_in_out_service_data_transfer(self, psim_rat=_5G_VOLTE , esim_rat=_5G_VOLTE,
+ dds_slot=0, momt_direction="mo"):
+ ad = self.android_devices[0]
+ set_dds_on_slot(ad, dds_slot)
+ # start streaming
+ if not start_youtube_video(ad):
+ ad.log.warning("Fail to bring up youtube video")
+ time.sleep(10)
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(_NO_SERVICE_TIME)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ return self._test_mo_voice_call(psim_rat, esim_rat, dds_slot, momt_direction)
+
+ def _test_mo_voice_call(self, psim_rat=_5G_VOLTE , esim_rat=_5G_VOLTE,
+ dds_slot =0, momt_direction="mo"):
+ ad = self.android_devices[0]
+ # Make a MOMT voice on SIM1
+ test_result = dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 0,
+ None,
+ dds_slot,
+ mo_rat=[psim_rat, esim_rat],
+ call_direction=momt_direction)
+ ensure_phones_idle(self.log, self.android_devices)
+ # Make a MOMT voice on SIM2
+ test_result = dsds_voice_call_test(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
+ 1,
+ None,
+ dds_slot,
+ mo_rat=[psim_rat, esim_rat],
+ call_direction=momt_direction)
+ # start streaming
+ if not start_youtube_video(ad):
+ ad.log.warning("Fail to bring up youtube video")
+ time.sleep(10)
+ return test_result
\ No newline at end of file
diff --git a/acts_tests/tests/google/tel/lab/TelLabGFTInOutServiceTest.py b/acts_tests/tests/google/tel/lab/TelLabGFTInOutServiceTest.py
index 5f04fff..9694749 100644
--- a/acts_tests/tests/google/tel/lab/TelLabGFTInOutServiceTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabGFTInOutServiceTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2021 - The Android Open Source Project
+# Copyright 2022 - 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.
@@ -13,57 +13,27 @@
# 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 datetime
-import logging
-
from acts import asserts
-from acts.test_decorators import test_info
from acts.test_decorators import test_tracker_info
-
-from acts.base_test import BaseTestClass
+from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.GFTInOutBaseTest import GFTInOutBaseTest
-
-from acts_contrib.test_utils.tel.tel_test_utils import get_service_state_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import run_multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import get_screen_shot_log
-from acts_contrib.test_utils.tel.tel_test_utils import get_screen_shot_logs
-from acts_contrib.test_utils.tel.tel_test_utils import log_screen_shot
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import active_file_download_test
-
-from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
-from acts_contrib.test_utils.tel.gft_inout_utils import check_no_service_time
-from acts_contrib.test_utils.tel.gft_inout_utils import check_back_to_service_time
-from acts_contrib.test_utils.tel.gft_inout_utils import mo_voice_call
-from acts_contrib.test_utils.tel.gft_inout_utils import get_voice_call_type
-
-from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_CONNECTED
-from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_DISCONNECTED
-from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_EMERGENCY_ONLY
-from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_IN_SERVICE
-from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_UNKNOWN
-from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_OUT_OF_SERVICE
-from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_POWER_OFF
-
from acts_contrib.test_utils.tel.gft_inout_defines import VOICE_CALL
from acts_contrib.test_utils.tel.gft_inout_defines import VOLTE_CALL
from acts_contrib.test_utils.tel.gft_inout_defines import CSFB_CALL
-from acts_contrib.test_utils.tel.gft_inout_defines import WFC_CALL
from acts_contrib.test_utils.tel.gft_inout_defines import NO_SERVICE_POWER_LEVEL
from acts_contrib.test_utils.tel.gft_inout_defines import IN_SERVICE_POWER_LEVEL
-from acts_contrib.test_utils.tel.gft_inout_defines import NO_SERVICE_AREA
-from acts_contrib.test_utils.tel.gft_inout_defines import IN_SERVICE_AREA
-from acts_contrib.test_utils.tel.gft_inout_defines import WIFI_AREA
-from acts_contrib.test_utils.tel.gft_inout_defines import NO_WIFI_AREA
-from acts_contrib.test_utils.tel.gft_inout_defines import NO_SERVICE_TIME
-from acts_contrib.test_utils.tel.gft_inout_defines import WAIT_FOR_SERVICE_TIME
-
+from acts_contrib.test_utils.tel.gft_inout_utils import check_no_service_time
+from acts_contrib.test_utils.tel.gft_inout_utils import check_back_to_service_time
+from acts_contrib.test_utils.tel.gft_inout_utils import mo_voice_call
+from acts_contrib.test_utils.tel.gft_inout_utils import check_ims_state
+from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_IN_SERVICE
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
+from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_test
+from acts_contrib.test_utils.tel.tel_test_utils import get_service_state_by_adb
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
IDLE_CASE = 1
DATA_TRANSFER_CASE = 2
@@ -71,29 +41,30 @@
IN_CALL_CASE = 4
CALL_DATA_CASE = 5
+
class TelLabGFTInOutServiceTest(GFTInOutBaseTest):
def __init__(self, controllers):
GFTInOutBaseTest.__init__(self, controllers)
self.my_error_msg = ""
def setup_test(self):
+ self.check_network()
self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ for ad in self.android_devices:
+ ad.droid.wifiToggleState(False)
GFTInOutBaseTest.setup_test(self)
self.check_network()
self.my_error_msg = ""
-
@test_tracker_info(uuid="c602e556-8273-4c75-b8fa-4d51ba514654")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_no_service_idle_1min(self, idle_time=60):
""" UE is in idle
Move UE from coverage area to no service area and UE shows no service
Wait for 1 min, then re-enter coverage area
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
@@ -105,49 +76,38 @@
""" UE is in idle
Move UE from coverage area to no service area and UE shows no service
Wait for 2 min, then re-enter coverage area
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time)
-
-
@test_tracker_info(uuid="1d437482-caff-4695-9f3f-f3daf6793540")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_no_service_idle_5min(self, idle_time=300):
""" UE is in idle
Move UE from coverage area to no service area and UE shows no service
Wait for 5 min, then re-enter coverage area
-
Args:
loop: cycle
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time)
-
@test_tracker_info(uuid="339b4bf5-57a1-48f0-b26a-83a7db21b08b")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_no_service_idle_10min(self, idle_time=600):
""" UE is in idle
Move UE from coverage area to no service area and UE shows no service
Wait for 10 min, then re-enter coverage area
-
Args:
loop: cycle
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time)
-
-
@test_tracker_info(uuid="65ebac02-8d5a-48c2-bd26-6d931d6048f1")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_no_service_data_transfer_1min(self, idle_time=60):
@@ -155,171 +115,125 @@
UE is performing data transfer (E.g. Use FTP or browse tools)
move UE from coverage area to no service area and UE shows no service
Wait for 1 min, then re-enter coverage area
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, DATA_TRANSFER_CASE)
-
-
@test_tracker_info(uuid="ec3e7de4-bcf6-4a8a-ae04-868bd7925191")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_no_service_data_transfer_2min(self, idle_time=120):
""" In/Out service - Stationary data transfer - 2 min
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, DATA_TRANSFER_CASE)
-
-
@test_tracker_info(uuid="8bd7017d-0a88-4423-a94b-1e37060bba1d")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_no_service_data_transfer_5min(self, idle_time=300):
""" In/Out service - Stationary data transfer - 5 min
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, DATA_TRANSFER_CASE)
-
-
@test_tracker_info(uuid="c3b9c52d-41d3-449c-99ff-4bb830ca0219")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_no_service_data_transfer_10min(self, idle_time=600):
""" In/Out service - Stationary data transfer - 10 min
-
Args:
idle_time: idle time in service area
file_name: download filename
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, DATA_TRANSFER_CASE)
-
-
@test_tracker_info(uuid="86a6b3b3-e754-4bde-b418-d4273b1ad907")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_service_incall_1min(self, idle_time=60):
""" In/Out service - Stationary incall - 1 min
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, IN_CALL_CASE)
-
-
@test_tracker_info(uuid="0f8772cd-6f86-48eb-b583-4cbaf80a21a9")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_service_incall_2min(self, idle_time=120):
""" In/Out service - Stationary incall - 2 min
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, IN_CALL_CASE)
-
-
@test_tracker_info(uuid="11f24c0f-db33-4eb3-b847-9aed447eb820")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_service_incall_5min(self, idle_time=300):
""" In/Out service - Stationary incall - 5 min
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, IN_CALL_CASE)
-
-
@test_tracker_info(uuid="e318921b-de6b-428b-b2c4-3db7786d7558")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_service_incall_10min(self, idle_time=600):
""" In/Out service - Stationary incall - 10 min
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, IN_CALL_CASE)
-
-
@test_tracker_info(uuid="f6cf0019-e123-4ebd-990b-0fa5b236840c")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_service_call_date_1min(self, idle_time=60):
""" In/Out service - Stationary incall + data transfer - 1 mins
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, CALL_DATA_CASE)
-
-
@test_tracker_info(uuid="2f49a9de-0383-4ec6-a8ee-c62f52ea0cf2")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_service_call_date_2min(self, idle_time=120):
""" In/Out service - Stationary incall + data transfer - 2 mins
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, CALL_DATA_CASE)
-
-
@test_tracker_info(uuid="73a6eedb-791f-4486-b815-8067a95efd5c")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_service_call_date_5min(self, idle_time=300):
""" In/Out service - Stationary incall + data transfer - 5 mins
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, CALL_DATA_CASE)
-
@test_tracker_info(uuid="5cfbc90a-97e1-43e9-a69e-4ce2815c544d")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_service_call_date_10min(self, idle_time=600):
""" In/Out service - Stationary incall + data transfer - 10 mins
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, CALL_DATA_CASE)
-
@test_tracker_info(uuid="c70180c9-5a36-4dc5-9ccc-3e6c0b5e6d37")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_service_pdp_off_1min(self, idle_time=60):
@@ -327,59 +241,43 @@
Disable UE mobile data
Move UE from coverage area to no service area and UE shows no service
Wait for 1 min, then re-enter coverage area
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, PDP_OFF_CASE)
-
@test_tracker_info(uuid="50cc8e73-d96f-45a6-91cd-bf51de5241d2")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_service_pdp_off_2min(self, idle_time=120):
""" In/Out service - Stationary data off - 2 min
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, PDP_OFF_CASE)
-
-
@test_tracker_info(uuid="1f25d40c-1bfe-4d18-b57c-d7be69664f0d")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_service_pdp_off_5min(self, idle_time=300):
""" In/Out service - Stationary data off - 5 min
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, PDP_OFF_CASE)
-
-
@test_tracker_info(uuid="b076b0d0-a105-4be9-aa0b-db0d782f70f2")
@TelephonyBaseTest.tel_test_wrap
def test_in_out_service_pdp_off_10min(self, idle_time=600):
""" In/Out service - Stationary data off - 10 min
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
return self._test_in_out_service_idle(idle_time, PDP_OFF_CASE)
-
-
-
def _test_in_out_service_idle(self, idle_time, case= IDLE_CASE, loop=1):
""" UE is in idle
Move UE from coverage area to no service area and UE shows no service
@@ -394,7 +292,6 @@
test_result = True
if 'autoio_cycle' in self.user_params:
loop = self.user_params.get('autoio_cycle')
-
for x in range (loop):
self.log.info("%s loop: %s/%s" %(self.current_test_name,x+1, loop))
if case == IDLE_CASE:
@@ -416,22 +313,23 @@
extras={"failure_cause": self.my_error_msg})
return test_result
-
def _in_out_service_idle_only(self, no_service_time=60, check_back_to_service=True,
check_no_service=True):
""" Move UE from coverage area to no service area and UE shows no service
Wait for no_service_time sec , then re-enter coverage area
-
Args:
no_service_time: stay at no service area time in sec
check_back_to_service: check device is back to service flag
check_no_service: check device is no service flag
-
Returns:
True if pass; False if fail.
"""
test_result = True
error_msg = ""
+ if 'check_no_service' in self.user_params:
+ loop = self.user_params.get('check_no_service')
+ if 'check_back_to_service' in self.user_params:
+ loop = self.user_params.get('check_back_to_service')
for ad in self.android_devices:
network_type = ad.droid.telephonyGetNetworkType()
service_state = get_service_state_by_adb(self.log,ad)
@@ -442,10 +340,8 @@
ad.log.info("Device is not ready for test. Service_state=%s." %(service_state))
self.my_error_msg += error_msg
return False
-
self.log.info("Move UE from coverage area to no service area")
self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
-
if check_no_service:
tasks = [(check_no_service_time, (ad, )) for ad in self.android_devices]
if not multithread_func(self.log, tasks):
@@ -465,11 +361,9 @@
def _data_transfer_mode(self, idle_time, file_name="10MB"):
""" Download file and in/out service
-
Args:
idle_time: stay at no service area time in sec
file_name: file to be download
-
Returns:
True if pass; False if fail.
"""
@@ -482,7 +376,6 @@
error_msg = " data transfer fail. "
self.my_error_msg += error_msg
self.log.info(error_msg)
- return False
return self._check_after_no_service()
def _in_out_service_pdp_off(self, idle_time):
@@ -491,10 +384,8 @@
Move UE from coverage area to no/limited service area
enable UE mobile data
After UE show no service, re-enter coverage area
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
@@ -505,10 +396,8 @@
if not wait_for_cell_data_connection(self.log, ad, False):
self.my_error_msg += "fail to turn off mobile data"
return False
-
if not self._in_out_service_idle_only(idle_time, False):
return False
-
for ad in self.android_devices:
ad.log.info("Turn on mobile data")
ad.droid.telephonyToggleDataConnection(True)
@@ -522,10 +411,8 @@
""" UE is in call
Move UE from coverage area to no/limited service area
After UE show no service, re-enter coverage area
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
@@ -536,7 +423,6 @@
self.my_error_msg += error_msg
self.log.info(error_msg)
return False
-
if not self._in_out_service_idle_only(idle_time, False):
return False
return self._check_after_no_service()
@@ -546,10 +432,8 @@
UE makes a MO call
Move UE from coverage area to no/limited service area
After UE show no service, re-enter coverage area
-
Args:
idle_time: idle time in service area
-
Returns:
True if pass; False if fail.
"""
@@ -560,14 +444,12 @@
error_msg = "fail to perfrom data transfer/voice call"
self.my_error_msg += error_msg
return False
-
if not self._in_out_service_idle_only(idle_time, False):
return False
return self._check_after_no_service()
def _check_after_no_service(self):
""" check device is back to service or not
-
Returns:
True if pass; False if fail.
"""
@@ -578,3 +460,283 @@
self.log.info(error_msg)
return False
return True
+
+
+ @test_tracker_info(uuid="4b8fee71-0d9b-4355-b175-84ea3c2a222a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_ID_1_1_5_ims_on_off(self, loop=1):
+ '''
+ 1.1.5 - In/Out service - IMS on -> no service
+ -> service area -> IMS off
+
+ Args:
+ loop: repeat this test cases for how many times
+
+ Returns:
+ True if pass; False if fail
+ Raises:
+ TestFailure if not success.
+ '''
+ error_msg = ""
+ test_result = True
+ if 'ims_cycle' in self.user_params:
+ loop = self.user_params.get('ims_cycle')
+
+ for x in range (loop):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.my_error_msg += "cylce%s: " %(x+1)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+
+ self.log.info("Turn on IMS")
+ tasks = [(toggle_volte, (self.log, ad, True)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("fail to toggle volte, ")
+ return False
+
+ tasks = [(check_ims_state, (ad, )) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("ims is not register, ")
+ return False
+
+ self.log.info("Move to no service area")
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(60)
+
+ self.log.info("Turn off IMS")
+ tasks = [(toggle_volte, (self.log, ad, False)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("fail to toggle volte, ")
+ return False
+ self.log.info("Move back to service area and verify device status")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ tasks = [(self.verify_device_status, (ad, VOICE_CALL))
+ for ad in self.android_devices]
+ test_result = multithread_func(self.log, tasks)
+ if not test_result:
+ self._on_fail("verify_device_status fail, ")
+ return False
+ if not test_result:
+ asserts.assert_true(test_result, "[Fail]%s" %(error_msg),
+ extras={"failure_cause": error_msg})
+ return test_result
+
+
+ @test_tracker_info(uuid="6b963676-fd28-4626-ad54-e1aa04274a37")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_ID_1_1_6_ims_on_off(self, loop=1):
+ '''
+ 1.1.6 - In/Out service - IMS on -> Enter no service area
+ -> service area -> IMS off
+
+ Args:
+ loop: repeat this test cases for how many times
+
+ Returns:
+ True if pass; False if fail
+ '''
+ error_msg = ""
+ test_result = True
+ if 'ims_cycle' in self.user_params:
+ loop = self.user_params.get('ims_cylce')
+
+ for x in range (loop):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.my_error_msg += "cylce%s: " %(x+1)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+
+ tasks = [(check_ims_state, (ad, )) for ad in self.android_devices]
+ multithread_func(self.log, tasks)
+
+ self.log.info("Turn on IMS")
+ tasks = [(toggle_volte, (self.log, ad, True)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("fail to toggle volte, ")
+ return False
+
+ tasks = [(check_ims_state, (ad, )) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("ims is not register, ")
+ return False
+
+ self.log.info("Move to no service area")
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(60)
+
+ self.log.info("Move back to service area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.log.info("Turn off IMS")
+ tasks = [(toggle_volte, (self.log, ad, False)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("fail to toggle volte, ")
+ return False
+ tasks = [(self.verify_device_status, (ad, VOICE_CALL))
+ for ad in self.android_devices]
+ test_result = multithread_func(self.log, tasks)
+ if not test_result:
+ self._on_fail( "verify_device_status fail, ")
+ return False
+ return test_result
+
+ @test_tracker_info(uuid="640db83f-6ba8-4df5-9c8c-dcf52a1904a1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_ID_1_1_7_ims_on_off(self, loop=1):
+ '''
+ 1.1.7 - In/Out service - IMS off
+ -> IMS on under no service area -> Back service area
+
+ Args:
+ loop: repeat this test cases for how many times
+
+ Returns:
+ True if pass; False if fail
+ '''
+ error_msg = ""
+ test_result = True
+ if 'ims_cycle' in self.user_params:
+ loop = self.user_params.get('ims_cylce')
+
+ for x in range (loop):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.my_error_msg += "cylce%s: " %(x+1)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+
+ tasks = [(check_ims_state, (ad, )) for ad in self.android_devices]
+ multithread_func(self.log, tasks)
+
+ self.log.info("Turn off IMS")
+ tasks = [(toggle_volte, (self.log, ad, False)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("fail to toggle volte, ")
+ return False
+
+ tasks = [(check_ims_state, (ad, )) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("ims is not register, ")
+ return False
+
+ self.log.info("CSFB call in service area")
+ tasks = [(mo_voice_call, (self.log, ad, CSFB_CALL, True, 30))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("csfb_call_fail, ")
+ return False
+
+ self.log.info("Move to no service area then turn on IMS")
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(60)
+ tasks = [(toggle_volte, (self.log, ad, True)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("fail to toggle volte, ")
+ return False
+
+ self.log.info("Move back to service area and verify device status, VOLTE call")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ tasks = [(self.verify_device_status, (ad, VOLTE_CALL))
+ for ad in self.android_devices]
+ test_result = multithread_func(self.log, tasks)
+ if not test_result:
+ self._on_fail( "verify_device_status fail, ")
+ return False
+ return test_result
+
+
+ @test_tracker_info(uuid="fcb72af6-b9d0-4911-9819-79abc58d5213")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_ID_1_1_8_ims_on_off(self, loop=1, sleepTimer=15):
+ '''
+ 1.1.8 - In/Out service - IMS off -> Enter no service area
+ -> service area -> IMS on
+
+ Args:
+ loop: repeat this test cases for how many times
+
+ Returns:
+ True if pass; False if fail
+ Raises:
+ TestFailure if not success.
+ '''
+ error_msg = ""
+ test_result = True
+ if 'ims_cycle' in self.user_params:
+ loop = self.user_params.get('ims_cylce')
+
+ for x in range (loop):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.my_error_msg += "cylce%s: " %(x+1)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+
+ tasks = [(check_ims_state, (ad, )) for ad in self.android_devices]
+ multithread_func(self.log, tasks)
+
+ self.log.info("Turn off IMS")
+ tasks = [(toggle_volte, (self.log, ad, False)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("fail to toggle volte ")
+ return False
+
+ tasks = [(check_ims_state, (ad, )) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("ims is not register, ")
+ return False
+
+ self.log.info("CSFB call in service area")
+ tasks = [(mo_voice_call, (self.log, ad, CSFB_CALL, true, 30))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("csfb_call_fail, ")
+ return False
+
+ self.log.info("Move to no service area")
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(60)
+ self.log.info("Move back to service area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.log.info("Turn on ims")
+ tasks = [(toggle_volte, (self.log, ad, True)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self._on_fail("fail to toggle volte ")
+ return False
+ self.log.info("Verify device status, VOLTE call")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ tasks = [(self.verify_device_status, (ad, VOLTE_CALL))
+ for ad in self.android_devices]
+ test_result = multithread_func(self.log, tasks)
+ if not test_result:
+ self._on_fail("verify_device_status fail, ")
+ return False
+ return test_result
+
+
+ @test_tracker_info(uuid="36250121-fe44-4953-ba9f-b806d7bb0e28")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_ID_1_1_49_in_out_service_dialing(self, loop=1):
+ '''
+ 1.1.49 - In/Out service - Stationary dialing stage
+
+ Args:
+ loop: repeat this test cases for how many times
+
+ Returns:
+ True if pass; False if fail
+ '''
+ error_msg = ""
+ test_result = True
+ if 'autoio_cycle' in self.user_params:
+ loop = self.user_params.get('autoio_cycle')
+
+ for x in range (loop):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.my_error_msg += "cylce%s: " %(x+1)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ for ad in self.android_devices:
+ ad.log.info("initiate voice call to %s " %(ad.mt_phone_number))
+ ad.droid.telecomCallNumber(ad.mt_phone_number)
+ self.log.info("Move to no service area")
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(30)
+ tasks = [(hangup_call, (self.log, ad)) for ad in self.android_devices]
+ multithread_func(self.log, tasks)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ if not self._check_after_no_service():
+ return False
+ return test_result
diff --git a/acts_tests/tests/google/tel/lab/TelLabGFTModemConnectivityHelperTest.py b/acts_tests/tests/google/tel/lab/TelLabGFTModemConnectivityHelperTest.py
index 295590a..8c51b34 100644
--- a/acts_tests/tests/google/tel/lab/TelLabGFTModemConnectivityHelperTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabGFTModemConnectivityHelperTest.py
@@ -33,15 +33,14 @@
from acts_contrib.test_utils.tel.GFTInOutBaseTest import GFTInOutBaseTest
from acts.controllers.android_device import DEFAULT_QXDM_LOG_PATH
from acts.controllers.android_device import DEFAULT_SDM_LOG_PATH
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import run_multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
from acts.test_decorators import test_tracker_info
from acts.logger import epoch_to_log_line_timestamp
from acts.utils import get_current_epoch_time
+from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.gft_inout_defines import NO_SERVICE_POWER_LEVEL
from acts_contrib.test_utils.tel.gft_inout_defines import IN_SERVICE_POWER_LEVEL
diff --git a/acts_tests/tests/google/tel/lab/TelLabGFTVoWifiStressTest.py b/acts_tests/tests/google/tel/lab/TelLabGFTVoWifiStressTest.py
new file mode 100644
index 0000000..db02fa2
--- /dev/null
+++ b/acts_tests/tests/google/tel/lab/TelLabGFTVoWifiStressTest.py
@@ -0,0 +1,375 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - 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 time
+import random
+import logging
+from acts import asserts
+from acts import signals
+from acts.test_decorators import test_tracker_info
+from acts.libs.utils.multithread import multithread_func
+from acts.utils import get_current_epoch_time
+
+from acts_contrib.test_utils.tel.tel_atten_utils import set_rssi
+from acts_contrib.test_utils.tel.tel_defines import SignalStrengthContainer
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.GFTInOutBaseTest import GFTInOutBaseTest
+from acts_contrib.test_utils.tel.gft_inout_defines import VOLTE_CALL
+from acts_contrib.test_utils.tel.gft_inout_defines import WFC_CALL
+from acts_contrib.test_utils.tel.gft_inout_defines import NO_SERVICE_POWER_LEVEL
+from acts_contrib.test_utils.tel.gft_inout_defines import IN_SERVICE_POWER_LEVEL
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.wifi import wifi_power_test_utils as wputils
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_ims_registered
+from acts_contrib.test_utils.tel.tel_logging_utils import log_screen_shot
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_logging_utils import start_sdm_loggers
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_wfc
+from acts_contrib.test_utils.tel.tel_ims_utils import is_wfc_enabled
+from acts_contrib.test_utils.tel.gft_inout_utils import mo_voice_call
+
+WAIT_TIME_AT_NO_SERVICE_AREA = 300
+
+
+class TelLabGFTVoWifiStressTest(GFTInOutBaseTest):
+
+ def __init__(self, controllers):
+ GFTInOutBaseTest.__init__(self, controllers)
+ self.wifi_ssid = self.user_params.get('wifi_network_ssid')
+ self.wifi_pw = self.user_params.get('wifi_network_pw')
+ self.my_error_msg = ""
+ self.rssi = ""
+ logging.info("wifi_ssid = %s" %self.wifi_ssid)
+ logging.info("wifi_pw = %s" %self.wifi_pw )
+
+ def setup_test(self):
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ GFTInOutBaseTest.setup_test(self)
+ for ad in self.android_devices:
+ ad.droid.wifiToggleState(True)
+ ad.droid.telephonyStartTrackingSignalStrengthChange()
+ # Ensure IMS on
+ self.log.info("Turn on ims")
+ tasks = [(phone_setup_volte, (self.log, ad, )) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ for ad in self.android_devices:
+ log_screen_shot(ad, self.test_name)
+ error_msg = "fail to setup volte"
+ self.log.error(error_msg)
+ # ensure WFC is enabled
+ tasks = [(toggle_wfc, (self.log, ad,True)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ for ad in self.android_devices:
+ log_screen_shot(ad, self.test_name)
+ error_msg = "device does not support WFC!"
+ self.log.error(error_msg)
+
+
+ def teardown_test(self):
+ super().teardown_test()
+ tasks = [(toggle_airplane_mode, (self.log, ad, False))
+ for ad in self.android_devices]
+ multithread_func(self.log, tasks)
+ for ad in self.android_devices:
+ ad.droid.telephonyStopTrackingSignalStrengthChange()
+
+ def _check_signal_strength(self):
+ """
+ check cellular signal strength
+ """
+ for ad in self.android_devices:
+ # SIGNAL_STRENGTH_LTE = "lteSignalStrength"
+ # SIGNAL_STRENGTH_LTE_DBM = "lteDbm"
+ # SIGNAL_STRENGTH_LTE_LEVEL = "lteLevel"
+ result = ad.droid.telephonyGetSignalStrength()
+ ad.log.info("lteDbm: {}".format(result[SignalStrengthContainer.
+ SIGNAL_STRENGTH_LTE_DBM]))
+ ad.log.info("lteSignalStrength: {}".format(result[SignalStrengthContainer.
+ SIGNAL_STRENGTH_LTE]))
+ ad.log.info("ltelevel: {}".format(result[SignalStrengthContainer.
+ SIGNAL_STRENGTH_LTE_LEVEL]))
+
+ @TelephonyBaseTest.tel_test_wrap
+ def test_wifi_cellular_signal(self, wfc_mode=WFC_MODE_WIFI_PREFERRED):
+ """
+ check WiFi and cellular signal
+
+ Args:
+ wfc_mode: wfc mode
+
+ Returns:
+ True if pass; False if fail
+ """
+ tasks = [(phone_setup_iwlan, (self.log, ad, False, wfc_mode,
+ self.wifi_ssid)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ error_msg = "fail to setup WFC mode to %s" %(wfc_mode)
+ self.log.error(error_msg)
+ cellular_power_level = 0
+ wifi_power_level = 0
+ for x in range(20):
+ self.adjust_cellular_signal(cellular_power_level)
+ self.adjust_wifi_signal(wifi_power_level)
+ time.sleep(5)
+ for ad in self.android_devices:
+ log_screen_shot(ad)
+ wifi_rssi = wputils.get_wifi_rssi(ad)
+ ad.log.info("wifi_power_level to %s , wifi_rssi=%s"
+ %(wifi_power_level, wifi_rssi))
+ cellular_power_level += 5
+ wifi_power_level += 5
+ self._check_signal_strength()
+ return True
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="176a0230-c35d-454d-a1f7-c706f71c5dbd")
+ def test_wfc_marginal_area_random_stress(self, wfc_mode=WFC_MODE_WIFI_PREFERRED):
+ """
+ b/213907614 marginal area with random
+ Adjusts WiFi and cellular signal randomly
+
+ Args:
+ wfc_mode: wfc mode
+
+ Returns:
+ True if pass; False if fail
+ """
+ fail_count = collections.defaultdict(int)
+ loop = self.user_params.get("marginal_cycle", 5)
+ error_msg = ""
+ self.log.info("Start test at cellular and wifi area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ self.check_network()
+ tasks = [(phone_setup_iwlan, (self.log, ad, False, wfc_mode,
+ self.wifi_ssid)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ error_msg = "fail to setup WFC mode to %s" %(wfc_mode)
+ fail_count["fail_to_setup_WFC_mode"] += 1
+ iteration_result = False
+ self.log.error(error_msg)
+
+ for i in range(1, loop + 1):
+ msg = "Stress Test %s Iteration: <%s> / <%s>" % (
+ self.test_name, i, loop)
+ begin_time = get_current_epoch_time()
+ self.log.info(msg)
+ iteration_result = True
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, i, loop))
+
+ self.log.info("Randomly adjust wifi and cellular signal")
+ for x in range (1):
+ cellular_power_level = random.randint(30, 50)
+ wifi_power_level = random.randint(5, 30)
+ self.log.info("adjust wifi power level to %s"%wifi_power_level )
+ self.log.info("adjust cellular power level to %s" %cellular_power_level)
+ self.adjust_wifi_signal(wifi_power_level)
+ self.adjust_cellular_signal(cellular_power_level)
+ time.sleep(10)
+ self._check_signal_strength()
+ for ad in self.android_devices:
+ log_screen_shot(ad)
+ wifi_rssi = wputils.get_wifi_rssi(ad)
+ ad.log.info("wifi_power_level to %s , wifi_rssi=%s"
+ %(wifi_power_level, wifi_rssi))
+ self.log.info("check ims status")
+ tasks = [(wait_for_ims_registered, (self.log, ad, ))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ error_msg = "Fail: IMS is not registered"
+ fail_count["IMS_is_not_registered"] += 1
+ iteration_result = False
+ self.log.error("%s:%s", msg, error_msg)
+ tasks = [(is_wfc_enabled, (self.log, ad, ))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.log.info("WiFi Calling feature bit is False.")
+ self.log.info("Set call_type to VOLTE_CALL")
+ call_type = VOLTE_CALL
+ else:
+ self.log.info("Set call_type to WFC_CALL")
+ call_type = WFC_CALL
+ if not self._voice_call(self.android_devices, call_type, end_call=True):
+ self.log.info("voice call failure")
+ tasks = [(self.verify_device_status, (ad, call_type, True,
+ 30, True, True)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ error_msg = "Verify_device_status fail"
+ fail_count["verify_device_status_fail"] += 1
+ iteration_result = False
+ self.log.error("%s:%s", msg, error_msg)
+ self.log.info("%s %s", msg, iteration_result)
+
+ if not iteration_result:
+ self._take_bug_report("%s_No_%s" % (self.test_name, i), begin_time)
+ if self.sdm_log:
+ start_sdm_loggers(self.log, self.android_devices)
+ else:
+ start_qxdm_loggers(self.log, self.android_devices)
+ test_result = True
+ for failure, count in fail_count.items():
+ if count:
+ self.log.error("%s: %s %s failures in %s iterations",
+ self.test_name, count, failure, loop)
+ test_result = False
+ return test_result
+
+
+ @TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="111d5810-bc44-4873-b18c-265afa283d34")
+ def test_wfc_marginal_area_cellcular_good_stress(self,
+ wfc_mode=WFC_MODE_WIFI_PREFERRED):
+ """
+ b/213907614
+ Keeps cellular signal good and adjust WiFi signal slowly
+
+ Args:
+ wfc_mode: wfc mode
+ Returns:
+ True if pass; False if fail
+ """
+ loop = self.user_params.get("marginal_cycle", 5)
+ fail_count = collections.defaultdict(int)
+ error_msg = ""
+
+ self.log.info("Start test at cellular and wifi area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ self.check_network()
+ tasks = [(phone_setup_iwlan, (self.log, ad, False, wfc_mode,
+ self.wifi_ssid)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ error_msg = "fail to setup WFC mode to %s" %(wfc_mode)
+ fail_count["fail_to_setup_WFC_mode"] += 1
+ iteration_result = False
+ # self.log.error("%s:%s", msg, error_msg)
+ self.log.error(error_msg)
+
+ for i in range(1, loop + 1):
+ msg = "Stress Test %s Iteration: <%s> / <%s>" % (
+ self.test_name, i, loop)
+ begin_time = get_current_epoch_time()
+ self.log.info(msg)
+ iteration_result = True
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, i, loop))
+
+ self.log.info("Move to poor wifi area slowly")
+ wifi_power_level = 5
+ for x in range (5):
+ self.log.info("adjust wifi power level to %s" %wifi_power_level)
+ self.adjust_wifi_signal(wifi_power_level)
+ time.sleep(5)
+ self._check_signal_strength()
+ self.log.info("check ims status")
+ tasks = [(wait_for_ims_registered, (self.log, ad, ))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ error_msg = "Fail: IMS is not registered"
+ fail_count["IMS_is_not_registered"] += 1
+ iteration_result = False
+ self.log.error("%s:%s", msg, error_msg)
+ tasks = [(is_wfc_enabled, (self.log, ad, ))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.log.info("WiFi Calling feature bit is False.")
+ self.log.info("Set call_type tp VOLTE_CALL")
+ call_type = VOLTE_CALL
+ else:
+ self.log.info("Set call_type to WFC_CALL")
+ call_type = WFC_CALL
+ if not self._voice_call(self.android_devices, call_type, end_call=True):
+ error_msg = "Fail: voice call failure"
+ fail_count["voice_call_failure"] += 1
+ iteration_result = False
+ self.log.error("%s:%s", msg, error_msg)
+ wifi_power_level += 5
+ self.log.info("Move back to wifi area slowly")
+ for x in range (5):
+ self.log.info("adjust wifi power level to %s" %wifi_power_level)
+ self.adjust_wifi_signal(wifi_power_level)
+ time.sleep(5)
+ self._check_signal_strength()
+ for ad in self.android_devices:
+ wifi_rssi = wputils.get_wifi_rssi(ad)
+ ad.log.info("wifi_power_level to %s , wifi_rssi=%s"
+ %(wifi_power_level, wifi_rssi))
+ self.log.info("check ims status")
+ tasks = [(wait_for_ims_registered, (self.log, ad, ))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ error_msg = "Fail: IMS is not registered"
+ fail_count["IMS_is_not_registered"] += 1
+ iteration_result = False
+ self.log.error("%s:%s", msg, error_msg)
+ tasks = [(is_wfc_enabled, (self.log, ad, ))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.log.info("WiFi Calling feature bit is False.")
+ self.log.info("Set call_type to VOLTE_CALL")
+ call_type = VOLTE_CALL
+ else:
+ self.log.info("Set call_type to WFC_CALL")
+ call_type = WFC_CALL
+ if not self._voice_call(self.android_devices, call_type,
+ end_call=True):
+ error_msg = "voice call failure"
+ fail_count["voice_call_failure"] += 1
+ iteration_result = False
+ self.log.error("%s:%s", msg, error_msg)
+ wifi_power_level -=5
+
+ self.log.info("%s %s", msg, iteration_result)
+ if not iteration_result:
+ self._take_bug_report("%s_No_%s" % (self.test_name, i), begin_time)
+ if self.sdm_log:
+ start_sdm_loggers(self.log, self.android_devices)
+ else:
+ start_qxdm_loggers(self.log, self.android_devices)
+ test_result = True
+ for failure, count in fail_count.items():
+ if count:
+ self.log.error("%s: %s %s failures in %s iterations",
+ self.test_name, count, failure, loop)
+ test_result = False
+ return test_result
+
+
+ def _voice_call(self, ads, call_type, end_call=True, talk_time=15):
+ """ Enable Wi-Fi calling in Wi-Fi Preferred mode and connect to a
+ valid Wi-Fi AP.
+ Args:
+ ads: android devices
+ call_type: WFC call, VOLTE call. CSFB call, voice call
+ end_call: hangup call after voice call flag
+ talk_time: in call duration in sec
+ Returns:
+ True if pass; False if fail.
+ """
+ tasks = [(mo_voice_call, (self.log, ad, call_type, end_call, talk_time))
+ for ad in ads]
+ if not multithread_func(self.log, tasks):
+ error_msg = "%s failure" %(call_type)
+ self.log.error(error_msg)
+ self.my_error_msg += error_msg
+ return False
+ return True
\ No newline at end of file
diff --git a/acts_tests/tests/google/tel/lab/TelLabGFTVoWifiTest.py b/acts_tests/tests/google/tel/lab/TelLabGFTVoWifiTest.py
index ae5cb21..35305a0 100644
--- a/acts_tests/tests/google/tel/lab/TelLabGFTVoWifiTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabGFTVoWifiTest.py
@@ -14,107 +14,116 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import sys
-import collections
-import random
+
+
import time
-import datetime
-import os
import logging
-import json
-import subprocess
-import math
-import re
-
from acts import asserts
+from acts import signals
from acts.test_decorators import test_tracker_info
-
-from acts.base_test import BaseTestClass
+from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.GFTInOutBaseTest import GFTInOutBaseTest
-
-
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_wfc
-
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import run_multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import get_screen_shot_log
-from acts_contrib.test_utils.tel.tel_test_utils import get_screen_shot_logs
-from acts_contrib.test_utils.tel.tel_test_utils import log_screen_shot
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-
-from acts_contrib.test_utils.tel.gft_inout_utils import check_no_service_time
-from acts_contrib.test_utils.tel.gft_inout_utils import check_back_to_service_time
-from acts_contrib.test_utils.tel.gft_inout_utils import mo_voice_call
-from acts_contrib.test_utils.tel.gft_inout_utils import get_voice_call_type
-
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
-
+from acts_contrib.test_utils.tel.tel_atten_utils import set_rssi
from acts_contrib.test_utils.tel.gft_inout_defines import VOICE_CALL
from acts_contrib.test_utils.tel.gft_inout_defines import VOLTE_CALL
from acts_contrib.test_utils.tel.gft_inout_defines import CSFB_CALL
from acts_contrib.test_utils.tel.gft_inout_defines import WFC_CALL
+from acts_contrib.test_utils.tel.gft_inout_defines import NO_VOICE_CALL
from acts_contrib.test_utils.tel.gft_inout_defines import NO_SERVICE_POWER_LEVEL
from acts_contrib.test_utils.tel.gft_inout_defines import IN_SERVICE_POWER_LEVEL
-from acts_contrib.test_utils.tel.gft_inout_defines import NO_SERVICE_AREA
-from acts_contrib.test_utils.tel.gft_inout_defines import IN_SERVICE_AREA
-from acts_contrib.test_utils.tel.gft_inout_defines import WIFI_AREA
-from acts_contrib.test_utils.tel.gft_inout_defines import NO_WIFI_AREA
from acts_contrib.test_utils.tel.gft_inout_defines import NO_SERVICE_TIME
from acts_contrib.test_utils.tel.gft_inout_defines import WAIT_FOR_SERVICE_TIME
+from acts_contrib.test_utils.tel.gft_inout_utils import check_back_to_service_time
+from acts_contrib.test_utils.tel.gft_inout_utils import mo_voice_call
+from acts_contrib.test_utils.tel.gft_inout_utils import get_voice_call_type
+from acts_contrib.test_utils.tel.gft_inout_utils import browsing_test_ping_retry
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
+from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_ACTIVE
+from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_HOLDING
+from acts_contrib.test_utils.tel.tel_data_utils import browsing_test
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_wfc
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_ims_registered
+from acts_contrib.test_utils.tel.tel_logging_utils import log_screen_shot
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.gft_inout_utils import verify_data_connection
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
WAIT_TIME_AT_NO_SERVICE_AREA = 300
+
class TelLabGFTVoWifiTest(GFTInOutBaseTest):
+
def __init__(self, controllers):
GFTInOutBaseTest.__init__(self, controllers)
self.wifi_ssid = self.user_params.get('wifi_network_ssid')
self.wifi_pw = self.user_params.get('wifi_network_pw')
+ self.my_error_msg = ""
+ self.rssi = ""
+ logging.info("wifi_ssid = %s" %self.wifi_ssid)
+ logging.info("wifi_pw = %s" %self.wifi_pw )
def setup_test(self):
self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
GFTInOutBaseTest.setup_test(self)
+ for ad in self.android_devices:
+ ad.droid.wifiToggleState(True)
+ # Ensure IMS on
+ self.log.info("Turn on ims")
+ tasks = [(phone_setup_volte, (self.log, ad, )) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ for ad in self.android_devices:
+ log_screen_shot(ad, self.test_name)
+ error_msg = "fail to setup volte"
+ self.log.error(error_msg)
+ asserts.assert_true(False, "Fail: %s." %(error_msg),
+ extras={"failure_cause": self.my_error_msg})
+ asserts.skip(error_msg)
+ # ensure WFC is enabled
tasks = [(toggle_wfc, (self.log, ad,True)) for ad in self.android_devices]
if not multithread_func(self.log, tasks):
- msg = "device does not support WFC! Skip test"
- self.log.info(msg)
- asserts.skip(msg)
- for ad in self.android_devices:
- log_screen_shot(ad, self.test_name)
+ for ad in self.android_devices:
+ log_screen_shot(ad, self.test_name)
+ error_msg = "device does not support WFC! Skip test"
+ asserts.skip(error_msg)
- @test_tracker_info(uuid="c0e74803-44ac-4a6b-be7e-2d1337ee4521")
+
+ def teardown_test(self):
+ super().teardown_test()
+ tasks = [(toggle_airplane_mode, (self.log, ad, False))
+ for ad in self.android_devices]
+ multithread_func(self.log, tasks)
+
+
+ @test_tracker_info(uuid="21ec1aff-a161-4dc9-9682-91e0dd8a13a7")
@TelephonyBaseTest.tel_test_wrap
def test_wfc_in_out_wifi(self, loop=1, wfc_mode=WFC_MODE_WIFI_PREFERRED):
"""
Enable Wi-Fi calling in Wi-Fi Preferred mode and connect to a
valid Wi-Fi AP. Test VoWiFi call under WiFi and cellular area
-> move to WiFi only area -> move to Cellular only area
-
Args:
loop: repeat this test cases for how many times
wfc_mode: wfc mode
-
Returns:
True if pass; False if fail
"""
test_result = True
- if 'wfc_cycle' in self.user_params:
- loop = self.user_params.get('wfc_cycle')
-
- for x in range (loop):
+ for x in range(self.user_params.get("wfc_cycle", 1)):
self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
self.log.info("Start test at cellular and wifi area")
self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
self.check_network()
if self._enable_wifi_calling(wfc_mode):
- if not self._voice_call(self.android_devices, WFC_CALL, False):
+ if not self._voice_call(self.android_devices, WFC_CALL, end_call=True):
self.log.info("VoWiFi call failure")
return False
self.log.info("Move to no service area and wifi area")
@@ -126,6 +135,12 @@
self.log.info("Move back to service area and no wifi area")
self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
self.adjust_wifi_signal(NO_SERVICE_POWER_LEVEL)
+ self.log.info("check cellular data")
+ # self._data_retry_mechanism()
+ tasks = [(verify_data_connection, (ad, 3))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.log.info("verify_data_connection failure")
self.log.info("Verify device state after in-out service")
tasks = [(check_back_to_service_time, (ad,)) for ad in self.android_devices]
test_result = multithread_func(self.log, tasks)
@@ -135,42 +150,1200 @@
self.log.info("device is not back to service")
return test_result
- def _enable_wifi_calling(self, wfc_mode):
+ def _enable_wifi_calling(self, wfc_mode, call_type=NO_VOICE_CALL,
+ end_call=True, is_airplane_mode=False, talk_time=30):
""" Enable Wi-Fi calling in Wi-Fi Preferred mode and connect to a
valid Wi-Fi AP.
Args:
wfc_mode: wfc mode
+ call_type: None would not make any calls
+ end_call: hang up call
+ is_airplane_mode: toggle airplane mode on or off
+ talk_time: call duration
Returns:
True if pass; False if fail.
"""
- self.log.info("Move in WiFi area and set WFC mode to %s" %(wfc_mode))
+ self.log.info("Move in WiFi area and set WFC mode to %s, airplane mode=%s"
+ %(wfc_mode, is_airplane_mode))
self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
time.sleep(10)
- tasks = [(set_wfc_mode, (self.log, ad, wfc_mode)) for ad in self.android_devices]
+ tasks = [(phone_setup_iwlan, (self.log, ad, is_airplane_mode, wfc_mode,
+ self.wifi_ssid))
+ for ad in self.android_devices]
if not multithread_func(self.log, tasks):
- self.log.error("fail to setup WFC mode %s" %(wfc_mode))
- return False
- tasks = [(ensure_wifi_connected, (self.log, ad, self.wifi_ssid,
- self.wifi_pw)) for ad in self.android_devices]
- if not multithread_func(self.log, tasks):
- self.log.error("phone failed to connect to wifi.")
- return False
+ self.my_error_msg += "fail to setup WFC mode to %s, " %(wfc_mode)
+ raise signals.TestFailure(self.my_error_msg)
+ if call_type != NO_VOICE_CALL:
+ if not self._voice_call(self.android_devices, call_type, end_call, talk_time):
+ self.log.error("%s failuer" %call_type)
+ return False
return True
- def _voice_call(self, ads, call_type, end_call=True, talk_time=30):
+ def _voice_call(self, ads, call_type, end_call=True, talk_time=15):
""" Enable Wi-Fi calling in Wi-Fi Preferred mode and connect to a
valid Wi-Fi AP.
-
Args:
ads: android devices
call_type: WFC call, VOLTE call. CSFB call, voice call
end_call: hangup call after voice call flag
talk_time: in call duration in sec
-
Returns:
True if pass; False if fail.
"""
- tasks = [(mo_voice_call, (self.log, ad, call_type, end_call, talk_time)) for ad in self.android_devices]
- return multithread_func(self.log, tasks)
\ No newline at end of file
+ tasks = [(mo_voice_call, (self.log, ad, call_type, end_call, talk_time))
+ for ad in ads]
+ if not multithread_func(self.log, tasks):
+ error_msg = "%s failure" %(call_type)
+ self.log.error(error_msg)
+ self.my_error_msg += error_msg
+ return False
+ return True
+
+ @test_tracker_info(uuid="3ca05651-a6c9-4b6b-84c0-a5d761757061")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_idle_wifi_preferred(self, wfc_mode=WFC_MODE_WIFI_PREFERRED):
+ ''' In/Out Service - Idle + VoWiFi registered in Wi-Fi Preferred mode
+ Enable Wi-Fi calling in Wi-Fi Preferred mode and connect to a valid Wi-Fi AP.
+ Idle in service area.
+ Move to no service area for 1 minute when idle.
+ Move back to service area and verfiy device status.
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wfc mode
+
+ Returns:
+ True if pass; False if fail
+ Raises:
+ TestFailure if not success.
+ '''
+ return self._in_out_wifi_wfc_mode(1, wfc_mode)
+
+
+ @test_tracker_info(uuid="b06121de-f458-4fc0-b9ef-efac02e46181")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_idle_cellular_preferred(self, loop=1,wfc_mode=WFC_MODE_CELLULAR_PREFERRED):
+ ''' In/Out Service - Idle + VoLTE registered in Cellular preferred mode
+ Enable Wi-Fi calling in Cellular preferred mode and connect to a valid Wi-Fi AP.
+ Idle in service area.
+ Move to no service area for 1 minute when idle.
+ Move back to service area and verify device status
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wfc mode
+
+ Returns:
+ True if pass; False if fail
+ Raises:
+ TestFailure if not success.
+ '''
+ asserts.assert_true(self._in_out_wifi_wfc_mode(1, WFC_MODE_CELLULAR_PREFERRED),
+ "Fail: %s." %(self.my_error_msg), extras={"failure_cause": self.my_error_msg})
+
+ def _in_out_wifi_wfc_mode(self, loop=1, wfc_mode=WFC_MODE_CELLULAR_PREFERRED):
+ error_msg = ""
+ test_result = True
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.my_error_msg += "cylce%s: " %(x+1)
+ self.log.info("Move in Wi-Fi area and set to %s" %(wfc_mode))
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ if not self._enable_wifi_calling(wfc_mode):
+ error_msg = "Fail to setup WFC mode"
+ self.log.info(error_msg)
+ self.my_error_msg += error_msg
+ return False
+ self.log.info("Idle in service area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.check_network()
+
+ self.log.info("Move to no service area in idle mode for 1 min")
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(NO_SERVICE_TIME)
+
+ self.log.info("Move back to service area and verify device status")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.log.info("Verify device status after in-out service")
+ tasks = [(check_back_to_service_time, (ad,)) for ad in self.android_devices]
+ test_result = multithread_func(self.log, tasks)
+ if test_result:
+ tasks = [(self.verify_device_status, (ad, VOICE_CALL))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ error_msg = "verify_device_status fail, "
+ self.log.info(error_msg)
+ else:
+ error_msg = "device is not back to service, "
+ self.log.info(error_msg)
+ self.my_error_msg += error_msg
+ return test_result
+
+ @test_tracker_info(uuid="95bf5006-4ff6-4e7e-a02d-156e6b43f129")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_wifi_apm_on(self):
+ '''
+ 1.1.4 In/Out Service - Idle + VoWiFi registered in Airplane on
+ + Wi-Fi on in default mode
+
+ Returns:
+ True if pass; False if fail
+ Raises:
+ TestFailure if not success.
+ '''
+ asserts.assert_true(self._ID_1_1_4_in_out_vowifi(1, 180), "Fail: %s."
+ %(self.my_error_msg), extras={"failure_cause": self.my_error_msg})
+ asserts.assert_true(self._ID_1_1_4_in_out_vowifi(1, 60), "Fail: %s."
+ %(self.my_error_msg), extras={"failure_cause": self.my_error_msg})
+ return True
+
+ def _ID_1_1_4_in_out_vowifi(self, loop=1, idle_time=60):
+ '''
+ 1.1.4 In/Out Service - Idle + VoWiFi registered in Airplane on
+ + Wi-Fi on in default mode
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: at no service area
+
+ Returns:
+ True if pass; False if fail
+ '''
+ error_msg = ""
+ test_result = True
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.my_error_msg += "cylce%s: " %(x+1)
+ self.log.info("Enable Wi-Fi calling in Airplane on")
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+
+ ad = self.android_devices[0]
+ wfc_mode = ad.droid.imsGetWfcMode()
+ tasks = [(phone_setup_iwlan, (self.log, ad, True, wfc_mode, self.wifi_ssid))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.my_error_msg += "fail to setup WFC mode to %s, " %(wfc_mode)
+ raise signals.TestFailure(self.my_error_msg)
+ self.log.info("idle in service area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ time.sleep(10)
+ self.log.info("Move to no service area for %s sec" %(idle_time))
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(idle_time)
+
+ self.log.info("Move back to service area and verify device status")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.log.info("Verify device status after in-out service")
+ tasks = [(check_back_to_service_time, (ad,)) for ad in self.android_devices]
+ test_result = multithread_func(self.log, tasks)
+ if test_result:
+ tasks = [(self.verify_device_status, (ad, VOICE_CALL))
+ for ad in self.android_devices]
+ test_result = multithread_func(self.log, tasks)
+ if not test_result:
+ error_msg = "verify_device_status fail, "
+ else:
+ error_msg = "device is not back to service, "
+ self.log.info(error_msg)
+ return test_result
+
+
+ def _device_status_check(self, call_type=None, end_call=True,
+ talk_time=30, verify_data=True, verify_voice=True):
+ '''
+ Check device status
+ Args:
+ ad: android device
+ call_type: WFC call, VOLTE call. CSFB call, voice call
+ end_call: hangup call after voice call flag
+ talk_time: in call duration in sec
+ verify_data: flag to check data connection
+ verify_voice: flag to check voice
+ Returns:
+ True if pass; False if fail
+ '''
+ tasks = [(check_back_to_service_time, (ad,))
+ for ad in self.android_devices]
+ if multithread_func(self.log, tasks):
+ tasks = [(self.verify_device_status, (ad, call_type, end_call,
+ talk_time, verify_data, verify_voice)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.my_error_msg += "Verify_device_status fail, "
+ return False
+ else:
+ self.my_error_msg += "device is not back to service, "
+ return False
+ return True
+
+ def _move_in_out_wifi_cellular_area(self, cellular_power_level,
+ wifi_power_level, hangup=False):
+ '''
+ Moves in out wifi/cellular area
+
+ Args:
+ cellular_power_level: cellular power level
+ wifi_power_level: wifi power level
+
+ Raises:
+ TestFailure if not success.
+
+ Returns:
+ True if pass; False if fail
+ '''
+ self.adjust_cellular_signal(cellular_power_level)
+ self.adjust_wifi_signal(wifi_power_level)
+ time.sleep(WAIT_FOR_SERVICE_TIME)
+ tasks = [(wait_for_ims_registered, (self.log, ad, ))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ return False
+ if hangup:
+ for ad in self.android_devices:
+ hangup_call(self.log, ad)
+ time.sleep(3)
+ return True
+
+ @test_tracker_info(uuid="7d308a3e-dc01-4bc1-b986-14f6adc9d2ed")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_hand_in_out_vowifi_incall (self, loop=1, wfc_mode = WFC_MODE_WIFI_PREFERRED):
+ '''1.2.17 - [Wi-Fi Preferred] Hand In/Out while VoWiFi incall
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wfc mode
+
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ test_result = True
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Start test at wifi area and no service area")
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ if not self._enable_wifi_calling(wfc_mode, call_type=WFC_CALL,
+ end_call=False):
+ self.log.info("WFC call failure")
+ test_result = False
+ self.log.info("Move out Wi-Fi area to VoLTE area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(WAIT_FOR_SERVICE_TIME)
+ self.log.info("check cellular data")
+ # self._data_retry_mechanism()
+ tasks = [(verify_data_connection, (ad, 3))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.log.info("verify_data_connection failure")
+ for ad in self.android_devices:
+ hangup_call(self.log, ad)
+ # Make a MO VoLTE call and verify data connection
+ if not self._voice_call(self.android_devices, VOLTE_CALL, False):
+ self.log.info("VOLTE call failure")
+ test_result = False
+ #Move back to Wi-Fi area during incall.
+ self.log.info("Move back to Wi-Fi area during incall.")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ time.sleep(WAIT_FOR_SERVICE_TIME)
+ for ad in self.android_devices:
+ hangup_call(self.log, ad)
+ # check device status
+ test_result = self._device_status_check()
+ return test_result
+
+
+ @test_tracker_info(uuid="9dda069f-068c-47c8-b9e1-2b1a0f3a6bdd")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_hand_in_out_vowifi_incall_stress_ims_on(self, loop=1,
+ wfc_mode=WFC_MODE_WIFI_PREFERRED):
+ '''
+ 1.2.18 - [Wi-Fi Preferred] Hand In/Out while VoWiFi incall
+ - Stress, IMS on
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wfc mode
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ test_result = True
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Start test at wifi area and service area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ if not self._enable_wifi_calling(wfc_mode, call_type=WFC_CALL,
+ end_call=False):
+ raise signals.TestFailure("VoWiFi call failure: %s"
+ %(self.my_error_msg))
+ # Move out Wi-Fi area to VoLTE area during incall.
+ self.log.info("Move out Wi-Fi area to VoLTE area")
+ if not self._move_in_out_wifi_cellular_area(
+ IN_SERVICE_POWER_LEVEL,NO_SERVICE_POWER_LEVEL):
+ raise signals.TestFailure("ims is not registered: %s"
+ %(self.my_error_msg))
+ self.log.info("Move back to Wi-Fi area")
+ if not self._move_in_out_wifi_cellular_area(
+ IN_SERVICE_POWER_LEVEL, IN_SERVICE_POWER_LEVEL, True):
+ raise signals.TestFailure("ims is not registered: %s"
+ %(self.my_error_msg))
+ if not self._device_status_check():
+ raise signals.TestFailure(self.my_error_msg)
+ return test_result
+
+
+ @test_tracker_info(uuid="e3633a6b-425a-4e4f-a58c-2d6aea56ec96")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_hand_in_out_vowifi_incall_stress_ims_off(self, loop=1,
+ wfc_mode = WFC_MODE_WIFI_PREFERRED):
+ '''
+ [Wi-Fi Preferred] Hand In/Out while VoWiFi incall -
+ Hand In/Out stress, IMS on - Hand In/Out, IMS off
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wfc mode
+
+ Raises:
+ TestFailure if not success.
+
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ tasks = [(toggle_volte, (self.log, ad, False))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("fail to turn off IMS: %s"
+ %(self.my_error_msg))
+ self.log.info("Start test at wifi area and service area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ if not self._enable_wifi_calling(wfc_mode, call_type=WFC_CALL,
+ end_call=False):
+ raise signals.TestFailure("VoWiFi call failure: %s"
+ %(self.my_error_msg))
+ #Move out Wi-Fi area to VoLTE area during incall.
+ self.log.info("Move out Wi-Fi area to VoLTE area")
+ self._move_in_out_wifi_cellular_area(
+ IN_SERVICE_POWER_LEVEL, IN_SERVICE_POWER_LEVEL)
+ time.sleep(3)
+ #Make a MO CSFB call "
+ if not self._voice_call(self.android_devices, CSFB_CALL, False):
+ raise signals.TestFailure("CSFB call failure: %s"
+ %(self.my_error_msg))
+ #Move back to Wi-Fi area during incall.
+ self.log.info("Move to WiFi only area and no VoLTE area")
+ self._move_in_out_wifi_cellular_area(NO_SERVICE_POWER_LEVEL,
+ IN_SERVICE_POWER_LEVEL, True)
+ if not self._device_status_check():
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+
+
+ @test_tracker_info(uuid="1f0697e5-6798-4cb1-af3f-c246cac59a40")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_rove_in_out_ims_on_cellular_preferred(self, loop=1,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED):
+ '''
+ [Cellular Preferred] Rove In/Out when idle - IMS on
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wfc mode
+
+ Raises:
+ TestFailure if not success.
+
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("roveinout_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Move in Wi-Fi area in cellular preferred mode")
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ time.sleep(10)
+ if not self._enable_wifi_calling(wfc_mode, call_type=VOLTE_CALL,
+ end_call=False):
+ raise signals.TestFailure("VoLTE call failure: %s"
+ %(self.my_error_msg))
+
+ self.log.info("Move out Wi-Fi area to VoLTE area")
+ self.adjust_wifi_signal(NO_SERVICE_POWER_LEVEL)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ time.sleep(WAIT_FOR_SERVICE_TIME)
+ self.log.info("check cellular data")
+ # self._data_retry_mechanism()
+ tasks = [(verify_data_connection, (ad, 3))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.log.info("verify_data_connection failure")
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ tasks = [(wait_for_ims_registered, (self.log, ad, )) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("IMS is not registered: %s"
+ %(self.my_error_msg))
+ if not self._device_status_check():
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+
+ @test_tracker_info(uuid="89690d28-e21e-4baf-88cf-be04675b764b")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_rove_in_out_ims_on_wifi_preferred(self, loop=1, wfc_mode=WFC_MODE_WIFI_PREFERRED):
+ ''' 1.2.154 - [Wi-Fi Preferred] Rove In/Out when idle - IMS on
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wfc mode
+
+ Raises:
+ TestFailure if not success.
+
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("roveinout_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Move in Wi-Fi area in wifi preferred mode")
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ time.sleep(10)
+ if not self._enable_wifi_calling(wfc_mode, call_type=WFC_CALL,
+ end_call=False):
+ raise signals.TestFailure("VoWiFi call failure: %s"
+ %(self.my_error_msg))
+
+ self.log.info("Move out Wi-Fi area to VoLTE area when idle.")
+ self.adjust_wifi_signal(NO_SERVICE_POWER_LEVEL)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+
+ tasks = [(wait_for_ims_registered, (self.log, ad, ))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("IMS is not registered: %s"
+ %(self.my_error_msg))
+ self.log.info("check cellular data")
+ # self._data_retry_mechanism()
+ tasks = [(verify_data_connection, (ad, 3))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.log.info("verify_data_connection failure")
+ self.log.info("Move back to Wi-Fi area when idle.")
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+
+ tasks = [(wait_for_ims_registered, (self.log, ad, ))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("IMS is not registered: %s"
+ %(self.my_error_msg))
+ if not self._device_status_check():
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+
+ @test_tracker_info(uuid="cd453193-4769-4fa5-809c-a6afb1d833c3")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_rove_in_out_ims_off_wifi_preferred(self, loop=1, wfc_mode=WFC_MODE_WIFI_PREFERRED):
+ ''' [Wi-Fi Preferred] Rove In/Out when idle - IMS off
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wfc mode
+
+ Raises:
+ TestFailure if not success.
+
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("roveinout_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Turn off IMS")
+ tasks = [(toggle_volte, (self.log, ad, False))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("fail to turn off IMS: %s"
+ %(self.my_error_msg))
+ self.log.info("Move in Wi-Fi area in wifi preferred mode")
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ time.sleep(10)
+ if not self._enable_wifi_calling(wfc_mode, call_type=WFC_CALL,
+ end_call=False):
+ raise signals.TestFailure("VoWiFi call failure: %s"
+ %(self.my_error_msg))
+
+ self.log.info("Move out Wi-Fi area to VoLTE area when idle.")
+ self.adjust_wifi_signal(NO_SERVICE_POWER_LEVEL)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+
+ tasks = [(wait_for_ims_registered, (self.log, ad, ))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("IMS is not registered: %s"
+ %(self.my_error_msg))
+ self.log.info("check cellular data")
+ # self._data_retry_mechanism()
+ tasks = [(verify_data_connection, (ad, 3))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.log.info("verify_data_connection failure")
+ self.log.info("Move back to Wi-Fi area when idle.")
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+
+ tasks = [(wait_for_ims_registered, (self.log, ad, ))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("IMS is not registered: %s"
+ %(self.my_error_msg))
+ if not self._device_status_check():
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+
+ @test_tracker_info(uuid="2632e594-3715-477b-b905-405ac8e490a9")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_vowifi_airplane_mode_on(self):
+ '''
+ Enable Wi-Fi calling in Airplane on + Wi-Fi on in default mode and
+ connect to a valid Wi-Fi AP.
+ Make a MO VoWiFi call in service area.
+ Move to no service area for 1 minute during incall.
+ Move back to service area
+
+ Returns:
+ True if pass; False if fail
+ Raises:
+ TestFailure if not success.
+ '''
+ asserts.assert_true(self._ID_1_1_11_vowifi_airplane_mode_on(1, 60),
+ "Fail: %s." %(self.my_error_msg), extras={"failure_cause": self.my_error_msg})
+ asserts.assert_true(self._ID_1_1_11_vowifi_airplane_mode_on(1, 180),
+ "Fail: %s." %(self.my_error_msg), extras={"failure_cause": self.my_error_msg})
+ return True
+
+ def _ID_1_1_11_vowifi_airplane_mode_on(self, loop=1, idle_time=60):
+ '''
+ 1.1.11 - In/Out Service - VoWiFi incall in Airplane on + Wi-Fi on in default mode
+
+ Args:
+ loop: repeat this test cases for how many times
+ idle_time: at no service area
+
+ Returns:
+ True if pass; False if fail
+ '''
+ error_msg = ""
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.my_error_msg += "cylce%s: " %(x+1)
+ self.log.info("idle in service area")
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ # Make a MO VoWiFi call in service area.
+ self.log.info("Enable Wi-Fi calling in Airplane on")
+ ad = self.android_devices[0]
+ wfc_mode = ad.droid.imsGetWfcMode()
+ tasks = [(phone_setup_iwlan, (self.log, ad, True, wfc_mode, self.wifi_ssid))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.my_error_msg += "fail to setup WFC mode to %s, " %(wfc_mode)
+ raise signals.TestFailure(self.my_error_msg)
+ self.log.info("Move to no service area for %s sec" %(idle_time))
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(idle_time)
+ self.log.info("Move back to service area and verify device status")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ if not self._device_status_check():
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+
+ @test_tracker_info(uuid="2b1f19c5-1214-41bd-895f-86987f1cf2b5")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_vowifi_call_wifi_preferred(self, loop=1 ,wfc_mode=WFC_MODE_WIFI_PREFERRED):
+ '''
+ In/Out Service - VoWiFi incall in Wi-Fi Preferred mode
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wifi prefer mode
+
+ Returns:
+ True if pass; False if fail
+ Raises:
+ TestFailure if not success.
+ '''
+ for x in range(self.user_params.get("roveinout_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Start test at cellular and wifi area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ self.check_network()
+ if not self._enable_wifi_calling(wfc_mode, call_type=WFC_CALL,
+ end_call=False):
+ raise signals.TestFailure("VoWiFi call failure: %s"
+ %(self.my_error_msg))
+
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(WAIT_FOR_SERVICE_TIME)
+ # check call status
+ for ad in self.android_devices:
+ get_voice_call_type(ad)
+ self.log.info("Move back to service area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.log.info("Verify device state after in-out service")
+ if not self._device_status_check():
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+
+
+ @test_tracker_info(uuid="63dfa017-8bdb-4c61-a29e-7c347982a5ac")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_volte_call_cellular_preferred(self, loop=1, wfc_mode=WFC_MODE_CELLULAR_PREFERRED):
+ '''
+ In/Out Service - VoLTE incall in Cellular preferred mode
+ Make sure that MO/MT VoWiFi call can be made after In/Out service
+ in Wi-Fi Preferred mode and Airplane on + Wi-Fi on and MO/MT
+ VoLTE call can be made in Cellular preferred mode.
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wifi prefer mode
+
+ Returns:
+ True if pass; False if fail
+ Raises:
+ TestFailure if not success.
+ '''
+ for x in range(self.user_params.get("roveinout_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Start test at cellular and wifi area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ self.check_network()
+
+ if not self._enable_wifi_calling(wfc_mode, call_type=WFC_CALL,
+ end_call=False):
+ raise signals.TestFailure("VoWiFi call failure: %s"
+ %(self.my_error_msg))
+ self.log.info(" Move to no service area for 1 minute during incall.")
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(WAIT_FOR_SERVICE_TIME)
+ # check call status
+ for ad in self.android_devices:
+ get_voice_call_type(ad)
+ self.log.info("Move back to service area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.log.info("Verify device state after in-out service")
+ if not self._device_status_check(call_type=VOLTE_CALL):
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+
+ @test_tracker_info(uuid="4f196186-b163-4c78-bdd9-d8fd7dc79dac")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_wfc_in_out_wifi_disabled(self, loop=1, wfc_mode=WFC_MODE_DISABLED):
+ """
+ [LAB][Wi-Fi Preferred/Cellular Preferred] In/Out Wi-Fi only area with
+ Wi-Fi calling disabled - Idle -> Make sure that radio function can work
+ after in/out Wi-Fi only area when Wi-Fi calling disabled.
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wfc mode
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ """
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Start test at cellular and wifi area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ if not self._enable_wifi_calling(wfc_mode, ):
+ raise signals.TestFailure("_enable_wifi_calling failure: %s"
+ %(self.my_error_msg))
+ self.log.info("Move out cellular area to Wi-Fi only area")
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(WAIT_TIME_AT_NO_SERVICE_AREA)
+ self.log.info("Move back to service area and no wifi area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(NO_SERVICE_POWER_LEVEL)
+
+ self.log.info("Verify device state after in-out service")
+ if not self._device_status_check(call_type=VOICE_CALL):
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+ @test_tracker_info(uuid="d597a694-fae9-426b-ba5e-97a9844cba4f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_wifi_browsing_wifi_preferred(self, loop=1, wfc_mode=WFC_MODE_WIFI_PREFERRED):
+ '''
+ [LAB][Wi-Fi Preferred] In/Out Wi-Fi only area with Wi-Fi calling enabled
+ Browsing -> Make sure that radio function can work after in/out Wi-Fi
+ only area in Wi-Fi preferred mode.
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wfc mode
+
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Start test at cellular and wifi area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ self.check_network()
+ if not self._enable_wifi_calling(wfc_mode, call_type=WFC_CALL,
+ end_call=False):
+ raise signals.TestFailure("VoWiFi call failure: %s"
+ %(self.my_error_msg))
+ #Keep browsing then move out cellular area to Wi-Fi only area
+ tasks_a = [(self._in_out_browse, ())]
+ tasks_b = [(browsing_test_ping_retry, (ad, )) for ad in self.android_devices]
+ tasks_b.extend(tasks_a)
+ if not multithread_func(self.log, tasks_b):
+ raise signals.TestFailure("in/out browsing failure: %s"
+ %(self.my_error_msg))
+ self.log.info("Verify device state after in-out service")
+ if not self._device_status_check(call_type=VOICE_CALL):
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+ @test_tracker_info(uuid="c7d3dc90-c0ed-48f8-b674-6d5b1efea3cc")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_in_out_wifi_browsing_wfc_disabled(self, loop=1, wfc_mode=WFC_MODE_DISABLED):
+ '''
+ [LAB][Wi-Fi Preferred/Cellular Preferred] In/Out Wi-Fi only area
+ with Wi-Fi calling disabled - Browsing
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wfc mode
+
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Start test at cellular and wifi area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ if not self._enable_wifi_calling(wfc_mode, call_type=WFC_CALL,
+ end_call=False):
+ raise signals.TestFailure("VoWiFi call failure: %s"
+ %(self.my_error_msg))
+ # Keep browsing then move out cellular area to Wi-Fi only area
+ tasks_a = [(self._in_out_browse, ())]
+ tasks_b = [(browsing_test_ping_retry, (ad, )) for ad in self.android_devices]
+ tasks_b.extend(tasks_a)
+ if not multithread_func(self.log, tasks_b):
+ for ad in self.android_devices:
+ log_screen_shot(ad, "browsing_failure")
+ raise signals.TestFailure("in/out browsing failure: %s"
+ %(self.my_error_msg))
+ if not self._device_status_check(call_type=VOICE_CALL):
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+ def _in_out_browse(self):
+ '''
+ Move out cellular area to Wi-Fi only area and
+ move back to service area and no wifi area
+ '''
+ self.log.info("Move out cellular area to Wi-Fi only area")
+ self.adjust_cellular_signal(NO_SERVICE_POWER_LEVEL)
+ # browsing at no service area
+ time.sleep(WAIT_TIME_AT_NO_SERVICE_AREA)
+ self.log.info("Move back to service area and no wifi area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(NO_SERVICE_POWER_LEVEL)
+ return True
+
+ @test_tracker_info(uuid="9029f3bb-3aca-42be-9241-ed21aab418ff")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_hand_in_out_vowifi_incall_data_transfer(self, loop=1,
+ wfc_mode=WFC_MODE_WIFI_PREFERRED):
+ '''
+ [Wi-Fi Preferred] Hand In/Out while VoWiFi incall -
+ Data transferring -> Make sure that IMS can register between Wi-Fi
+ and LTE NW and no call dropped during data transferring after
+ hand in/out in Wi-Fi Preferred mode.
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode: wfc mode
+
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Start test at cellular and wifi area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ self.check_network()
+ if not self._enable_wifi_calling(wfc_mode, call_type=WFC_CALL,
+ end_call=False):
+ raise signals.TestFailure("VoWiFi call failure: %s"
+ %(self.my_error_msg))
+ #Download a large file in the background then make a MO VoWiFi call.
+ if not self._voice_call(self.android_devices, WFC_CALL, False,):
+ error_msg = "VoWiFi call failure, "
+ self.log.info(error_msg)
+ self._on_failure(error_msg)
+ self.log.info("Move out Wi-Fi area to VoLTE area during incall + data transferring.")
+ self.adjust_wifi_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(WAIT_FOR_SERVICE_TIME)
+ for ad in self.android_devices:
+ hangup_call(self.log, ad)
+ if not self._device_status_check(call_type=VOLTE_CALL):
+ raise signals.TestFailure(self.my_error_msg)
+ # Download a file in the background then make a MO VoLTE call.
+ self.log.info("Move back to Wi-Fi area during incall + data transferring.")
+ # Move back to Wi-Fi area during incall + data transferring.
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ time.sleep(160)
+ for ad in self.android_devices:
+ hangup_call(self.log, ad)
+ if not self._device_status_check(call_type=VOICE_CALL):
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+
+ @test_tracker_info(uuid="45c1f623-5eeb-4ee4-8739-2b0ebcd5f19f")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_rove_in_out_ims_on_airplane_mode(self, loop=1,):
+ '''
+ [Wi-Fi Calling+Airplane On] Rove In/Out when idle - IMS on ->
+ Make sure that IMS can register between Wi-Fi and LTE NW and
+ VoWiFi call can be made after rove in/out.
+
+ Args:
+ loop: repeat this test cases for how many times
+
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.my_error_msg += "cylce%s: " %(x+1)
+
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.log.info("Enable Wi-Fi calling in Airplane on")
+ ad = self.android_devices[0]
+ wfc_mode = ad.droid.imsGetWfcMode()
+ tasks = [(phone_setup_iwlan, (self.log, ad, True, wfc_mode, self.wifi_ssid))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.my_error_msg += "fail to setup WFC mode to %s, " %(wfc_mode)
+ raise signals.TestFailure(self.my_error_msg)
+
+ self.log.info("Make a MO VoWiFi call in service area")
+ if not self._voice_call(self.android_devices, WFC_CALL, False):
+ raise signals.TestFailure("VoWiFi call failure: %s"
+ %(self.my_error_msg))
+
+ self.log.info("Move out Wi-Fi area to VoLTE area when idle.")
+ self.adjust_wifi_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(WAIT_FOR_SERVICE_TIME)
+ # if not self._device_status_check(call_type=VOICE_CALL):
+ # raise signals.TestFailure(self.my_error_msg)
+ self.log.info("Move back to Wi-Fi area when idle.")
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ self.log.info("Verify device status after in-out service")
+ self.log.info("Wait for maximum to 160 sec before IMS switched")
+ tasks = [(wait_for_ims_registered, (self.log, ad, 160))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ asserts.assert_true(False, "Fail: %s." %("wait_for_ims_registered failure"),
+ extras={"failure_cause": self.my_error_msg})
+ # turn off APM
+ self.log.info("Turn off airplande mode")
+ tasks = [(toggle_airplane_mode, (self.log, ad, False))
+ for ad in self.android_devices]
+ multithread_func(self.log, tasks)
+ return True
+
+
+ @test_tracker_info(uuid="fb431706-737d-4020-b3d1-347dc4d7ce03")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_wifi_rove_out_wfc(self,loop=1, wfc_mode=WFC_MODE_WIFI_PREFERRED, idle_time=180):
+ '''
+ [Wi-Fi Preferred] Rove In/Out when idle for 1 hours - Wi-Fi calling enabled
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode:
+ idle_time: how long device will be idle
+
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Start test at cellular and wifi area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ if not self._enable_wifi_calling(wfc_mode, call_type=WFC_CALL,
+ end_call=False):
+ raise signals.TestFailure("VoWiFi call failure: %s"
+ %(self.my_error_msg))
+
+ if not self._voice_call(self.android_devices, WFC_CALL, ):
+ raise signals.TestFailure("VoWiFi call failure: %s"
+ %(self.my_error_msg))
+ time.sleep(idle_time)
+
+ self.log.info("Move out Wi-Fi area to VoLTE area when idle.")
+ self.adjust_wifi_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(30)
+ self.log.info("check cellular data")
+ # self._data_retry_mechanism()
+ tasks = [(verify_data_connection, (ad, 3))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.log.info("verify_data_connection failure")
+ if not self._voice_call(self.android_devices, VOLTE_CALL, ):
+ raise signals.TestFailure("VOLTE call failure: %s"
+ %(self.my_error_msg))
+ self.log.info("Move back to Wi-Fi area when idle.")
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ if not self._device_status_check(call_type=WFC_CALL):
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+
+ @test_tracker_info(uuid="fb431706-737d-4020-b3d1-347dc4d7ce03")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_wifi_rove_out_no_wfc(self,loop=1, wfc_mode=WFC_MODE_DISABLED,
+ idle_time=180):
+ '''
+ [Wi-Fi Preferred] Rove In/Out when idle for 1 hours
+ Wi-Fi calling disabled. Make sure that IMS can register between
+ Wi-Fi and LTE NW and VoWiFi call can be made after rove in/out.
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode:
+ idle_time: how long device will be idle
+
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Start test at cellular and wifi area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ self.check_network()
+ if not self._enable_wifi_calling(wfc_mode):
+ raise signals.TestFailure("_enable_wifi_calling failure: %s"
+ %(self.my_error_msg))
+
+ if not self._voice_call(self.android_devices, VOLTE_CALL, ):
+ raise signals.TestFailure("VOLTE call failure: %s"
+ %(self.my_error_msg))
+ time.sleep(idle_time)
+
+ self.log.info("Move out Wi-Fi area to VoLTE area when idle.")
+ self.adjust_wifi_signal(NO_SERVICE_POWER_LEVEL)
+ time.sleep(30)
+ self.log.info("check cellular data")
+ # self._data_retry_mechanism()
+ tasks = [(verify_data_connection, (ad, 3))
+ for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ self.log.info("verify_data_connection failure")
+ if not self._voice_call(self.android_devices, VOLTE_CALL, ):
+ raise signals.TestFailure("VOLTE call failure: %s"
+ %(self.my_error_msg))
+ self.log.info("Move back to Wi-Fi area when idle.")
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ # Enable Wi-Fi calling in Wi-Fi Preferred mode
+ if not self._enable_wifi_calling(WFC_MODE_WIFI_PREFERRED):
+ raise signals.TestFailure("_enable_wifi_calling failure: %s"
+ %(self.my_error_msg))
+ # check device status
+ if not self._device_status_check(call_type=WFC_CALL):
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+
+ @test_tracker_info(uuid="5ddfa906-7756-42b4-b1c4-2ac507211547")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_hand_in_out_vowifi_incall_call_hold(self,loop=1,
+ wfc_mode=WFC_MODE_WIFI_PREFERRED, idle_time=180):
+ '''
+ [NSA/SA][Wi-Fi Preferred] Hand In/Out while VoWiFi incall - Hold
+ Ensure IMS can register between Wi-Fi and LTE/NR NW and no call dropped
+ during incall with hold on after hand in/out in Wi-Fi Preferred mode.
+
+ Args:
+ loop: repeat this test cases for how many times
+ wfc_mode:
+ idle_time: how long device will be idle
+
+ Raises:
+ TestFailure if not success.
+ Returns:
+ True if pass; False if fail
+ '''
+ for x in range(self.user_params.get("wfc_cycle", 1)):
+ self.log.info("%s loop: %s/%s" %(self.current_test_name, x+1, loop))
+ self.log.info("Start test at wifi area and service area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ #Make a MO VoWiFi call and hold the call.
+ if not self._enable_wifi_calling(wfc_mode, call_type=WFC_CALL,
+ end_call=False):
+ raise signals.TestFailure("VoWiFi call failure: %s"
+ %(self.my_error_msg))
+ tasks = [(self._call_hold, (ad,)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("fail to hold call: %s"
+ %(self.my_error_msg))
+
+ # Move out Wi-Fi area to 4G area during incall
+ self.log.info("Move out Wi-Fi area to VoLTE area")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(NO_SERVICE_POWER_LEVEL)
+ # Unhold the call
+ tasks = [(self._call_unhold, (ad,)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("fail to unhold call: %s"
+ %(self.my_error_msg))
+ time.sleep(30)
+ for ad in self.android_devices:
+ hangup_call(self.log, ad)
+
+ # Make a MO VoLTE call and hold the call.
+ if not self._voice_call(self.android_devices, VOLTE_CALL, False):
+ raise signals.TestFailure("VoLTE call failure: %s"
+ %(self.my_error_msg))
+ tasks = [(self._call_hold, (ad,)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("fail to hold call: %s"
+ %(self.my_error_msg))
+
+ #Move back to Wi-Fi area during incall.
+ self.log.info("Move back to Wi-Fi area during incall.")
+ self.adjust_cellular_signal(IN_SERVICE_POWER_LEVEL)
+ self.adjust_wifi_signal(IN_SERVICE_POWER_LEVEL)
+ tasks = [(self._call_unhold, (ad,)) for ad in self.android_devices]
+ if not multithread_func(self.log, tasks):
+ raise signals.TestFailure("fail to unhold call: %s"
+ %(self.my_error_msg))
+ time.sleep(30)
+ for ad in self.android_devices:
+ hangup_call(self.log, ad)
+ # check device status
+ if not self._device_status_check(call_type=WFC_CALL):
+ raise signals.TestFailure(self.my_error_msg)
+ return True
+
+
+ def _call_hold(self, ad, wait_time=WAIT_TIME_IN_CALL):
+ '''
+ Press call hold
+
+ Args:
+ ad: android device
+ wait_time: wait time after press hold/unhold in sec
+
+ Returns:
+ True if pass; False if fail
+ '''
+ if ad.droid.telecomIsInCall():
+ ad.droid.telecomShowInCallScreen()
+ call_list = ad.droid.telecomCallGetCallIds()
+ ad.log.info("Calls in PhoneA %s", call_list)
+ call_id = call_list[0]
+ call_state = ad.droid.telecomCallGetCallState(call_id)
+ if call_state != CALL_STATE_ACTIVE:
+ ad.log.error("Call_id:%s, state:%s, expected: STATE_ACTIVE",
+ call_id,
+ ad.droid.telecomCallGetCallState(call_id))
+ return False
+ ad.log.info("Hold call_id %s on PhoneA", call_id)
+ log_screen_shot(ad, "before_call_hold")
+ ad.droid.telecomCallHold(call_id)
+ time.sleep(wait_time)
+
+ call_state = ad.droid.telecomCallGetCallState(call_id)
+ log_screen_shot(ad, "after_call_hold")
+ if call_state != CALL_STATE_HOLDING:
+ ad.log.error("Call_id:%s, state:%s, expected: STATE_HOLDING",
+ call_id,
+ ad.droid.telecomCallGetCallState(call_id))
+ log_screen_shot(ad, "hold_failure")
+ return False
+ else:
+ ad.log.info("device is not in call")
+ return False
+ return True
+
+ def _call_unhold(self, ad, wait_time=WAIT_TIME_IN_CALL):
+ '''
+ Press call unhold
+
+ Args:
+ ad: android device
+ wait_time: wait time after press hold/unhold in sec
+
+ Returns:
+ True if pass; False if fail
+ '''
+ if ad.droid.telecomIsInCall():
+ ad.droid.telecomShowInCallScreen()
+ call_list = ad.droid.telecomCallGetCallIds()
+ ad.log.info("Calls in PhoneA %s", call_list)
+ call_id = call_list[0]
+ call_state = ad.droid.telecomCallGetCallState(call_id)
+ if call_state != CALL_STATE_HOLDING:
+ ad.log.error("Call_id:%s, state:%s, expected: STATE_HOLDING",
+ call_id,
+ ad.droid.telecomCallGetCallState(call_id))
+ return False
+ ad.log.info("Unhold call_id %s on PhoneA", call_id)
+ log_screen_shot(ad, "before_unhold")
+ ad.droid.telecomCallUnhold(call_id)
+ time.sleep(wait_time)
+ call_state = ad.droid.telecomCallGetCallState(call_id)
+ log_screen_shot(ad, "after_unhold")
+ if call_state != CALL_STATE_ACTIVE:
+ ad.log.error("Call_id:%s, state:%s, expected: STATE_ACTIVE",
+ call_id,
+ call_state)
+ log_screen_shot(ad, "_unhold_failure")
+ return False
+ else:
+ ad.log.info("device is not in call")
+ return False
+ return True
+
diff --git a/acts_tests/tests/google/tel/lab/TelLabMobilityTest.py b/acts_tests/tests/google/tel/lab/TelLabMobilityTest.py
index aba648b..ccfdf78 100644
--- a/acts_tests/tests/google/tel/lab/TelLabMobilityTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabMobilityTest.py
@@ -28,9 +28,6 @@
from acts_contrib.test_utils.tel.anritsu_utils import tear_down_call
from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_lte_lte
from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_lte_wcdma
-from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_lte_gsm
-from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_lte_1x
-from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_lte_evdo
from acts_contrib.test_utils.tel.anritsu_utils import set_usim_parameters
from acts_contrib.test_utils.tel.anritsu_utils import set_post_sim_params
from acts_contrib.test_utils.tel.tel_defines import CALL_TEARDOWN_PHONE
@@ -38,7 +35,6 @@
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_UMTS
-from acts_contrib.test_utils.tel.tel_defines import RAT_1XRTT
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_CDMA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GSM_ONLY
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GSM_UMTS
@@ -46,22 +42,17 @@
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_GSM_WCDMA
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL_FOR_IMS
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_rat
from acts_contrib.test_utils.tel.tel_test_utils import get_host_ip_address
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte
-from acts_contrib.test_utils.tel.tel_test_utils import run_multithread_func
from acts_contrib.test_utils.tel.tel_test_utils import iperf_test_by_adb
from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_apn_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_volte
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts.utils import adb_shell_ping
-from acts.utils import rand_ascii_str
-from acts.controllers import iperf_server
-from acts.utils import exe_cmd
+from acts.libs.utils.multithread import run_multithread_func
DEFAULT_CALL_NUMBER = "+11234567891"
DEFAULT_PING_DURATION = 5
diff --git a/acts_tests/tests/google/tel/lab/TelLabNeighborCellTest.py b/acts_tests/tests/google/tel/lab/TelLabNeighborCellTest.py
index 8690ae7..ae26d91 100644
--- a/acts_tests/tests/google/tel/lab/TelLabNeighborCellTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabNeighborCellTest.py
@@ -44,8 +44,8 @@
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_UMTS
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_rat
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts.controllers.anritsu_lib.cell_configurations import \
diff --git a/acts_tests/tests/google/tel/lab/TelLabProjectFiTest.py b/acts_tests/tests/google/tel/lab/TelLabProjectFiTest.py
index 4208689..c151811 100644
--- a/acts_tests/tests/google/tel/lab/TelLabProjectFiTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabProjectFiTest.py
@@ -14,22 +14,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
-Fi Switching Methods
+Fi Switching Methods
"""
import time
+from acts.libs.utils.multithread import multithread_func
from acts.controllers.anritsu_lib._anritsu_utils import AnritsuError
-from acts.controllers.anritsu_lib.md8475a import CBCHSetup
-from acts.controllers.anritsu_lib.md8475a import CTCHSetup
from acts.controllers.anritsu_lib.md8475a import MD8475A
from acts_contrib.test_utils.tel.anritsu_utils import cb_serial_number
from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_lte
from acts_contrib.test_utils.tel.anritsu_utils import set_usim_parameters
from acts_contrib.test_utils.tel.anritsu_utils import set_post_sim_params
-from acts_contrib.test_utils.tel.tel_test_utils import \
- ensure_preferred_network_type_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_GSM_WCDMA
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
@@ -38,20 +32,23 @@
from acts_contrib.test_utils.tel.tel_defines import CARRIER_SPT
from acts_contrib.test_utils.tel.tel_defines import CARRIER_TMO
from acts_contrib.test_utils.tel.tel_defines import CARRIER_USCC
+from acts_contrib.test_utils.tel.tel_logging_utils import log_screen_shot
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
from acts_contrib.test_utils.tel.tel_lookup_tables import operator_name_from_plmn_id
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_preferred_network_type_for_subscription
from acts_contrib.test_utils.tel.tel_test_utils import abort_all_tests
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
from acts_contrib.test_utils.tel.tel_test_utils import is_sim_ready
-from acts_contrib.test_utils.tel.tel_test_utils import log_screen_shot
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
from acts_contrib.test_utils.tel.tel_test_utils import reboot_device
from acts_contrib.test_utils.tel.tel_test_utils import refresh_droid_config
from acts_contrib.test_utils.tel.tel_test_utils import send_dialer_secret_code
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
from acts_contrib.test_utils.tel.tel_test_utils import wait_for_state
from acts_contrib.test_utils.tel.tel_test_utils import add_google_account
from acts_contrib.test_utils.tel.tel_test_utils import remove_google_account
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
WAIT_TIME_BETWEEN_REG_AND_MSG = 15 # default 15 sec
CARRIER = None
diff --git a/acts_tests/tests/google/tel/lab/TelLabPwsTest.py b/acts_tests/tests/google/tel/lab/TelLabPwsTest.py
new file mode 100644
index 0000000..188783a
--- /dev/null
+++ b/acts_tests/tests/google/tel/lab/TelLabPwsTest.py
@@ -0,0 +1,373 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - Google
+#
+# 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 datetime
+import enum
+import logging
+import time
+from typing import Callable
+
+from acts import asserts
+from acts.controllers.amarisoft_lib import amarisoft_client
+from acts.controllers.amarisoft_lib import config_utils
+from acts.controllers.amarisoft_lib import ssh_utils
+from acts.controllers.amarisoft_lib import ims
+from acts.controllers.amarisoft_lib import mme
+from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel import tel_defines
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts.libs.proc import job
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+
+PWS_ALERT_4370 = 4370
+PWS_ALERT_4371 = 4371
+PWS_ALERT_4380 = 4380
+PWS_ALERT_911 = 911
+PWS_ALERT_4383 = 4383
+PWS_ALERT_4384 = 4384
+PWS_ALERT_4393 = 4393
+PWS_ALERT_919 = 919
+
+PREFERENCES_XML_FILENAME = '/data/user_de/0/com.google.android.cellbroadcastreceiver/shared_prefs/com.google.android.cellbroadcastreceiver_preferences.xml'
+ENABLE_TEST_ALERT_CMD = (
+ "sed -i 's/"
+ "enable_test_alerts\\\" value=\\\"false/"
+ "enable_test_alerts\\\" value=\\\"true/"
+ f"' {PREFERENCES_XML_FILENAME}")
+PWS_DUPLICATE_DETECTION_OFF = (
+ 'am broadcast -a '
+ 'com.android.cellbroadcastservice.action.DUPLICATE_DETECTION '
+ '--ez enable false')
+
+IN_CALL_DURATION = datetime.timedelta(seconds=10)
+CHECK_INTERVAL = datetime.timedelta(seconds=1)
+SERVICE_RESTART_TIME_OUT = datetime.timedelta(seconds=10)
+REGISTRATION_TIMEOUT = datetime.timedelta(seconds=120)
+WAIT_CALL_STATE_TIMEOUT = datetime.timedelta(seconds=30)
+PWS_START_END_INTERVAL = datetime.timedelta(seconds=15)
+
+
+class TestScenario(enum.Enum):
+ """Test scenario for PWS test."""
+ PS = 0
+ CS = 1
+ IDLE = 2
+
+
+class CallState(enum.Enum):
+ """Telephony call state."""
+ IDLE = 0
+ RINGING = 1
+ OFFHOOK = 2
+
+
+def wait_until(condition: Callable[..., bool], interval: datetime.timedelta,
+ timeout: datetime.timedelta, ret: bool, *argv) -> bool:
+ """Waits for the condition to occur.
+
+ Args:
+ condition: Function to check specific event occur or not.
+ interval: Time period during each check.
+ timeout: A timer which wait for event occur.
+ ret: Expected result of condition.
+ *argv: Parameters used by condition.
+
+ Returns:
+ True if condition match ret, False otherwise.
+ """
+ start_time = datetime.datetime.now()
+ while datetime.datetime.now() - start_time < timeout:
+ if condition(*argv) == ret:
+ return True
+ time.sleep(interval.total_seconds())
+ return False
+
+
+def is_in_service(ad) -> bool:
+ """Checks radio service state of android device .
+
+ Args:
+ ad: Mobly's Android controller objects.
+
+ Returns:
+ True if device is in service, False otherwise.
+ """
+ service_state = ad.droid.telephonyGetServiceState()
+ if service_state is None:
+ return False
+ return service_state.get('serviceState') == 'IN_SERVICE'
+
+
+class TelLabPwsTest(TelephonyBaseTest):
+
+ def setup_class(self):
+ super().setup_class()
+ self.ad = self.android_devices[0]
+ self.ad.info = self.user_params.get('AndroidDevice')[0]
+ self.amarisoft_ip_address = self.user_params.get('amarisoft_ip_address')
+ self.amarisoft_username = self.user_params.get('amarisoft_username')
+ self.amarisoft_pw = self.user_params.get('amarisoft_pw')
+ self.amarisoft_call_num = self.user_params.get('amarisoft_call_num')
+ self.remote = amarisoft_client.AmariSoftClient(self.amarisoft_ip_address,
+ self.amarisoft_username,
+ self.amarisoft_pw)
+ self.remote.connect()
+ self.config = config_utils.ConfigUtils(self.remote)
+ self.mme = mme.MmeFunctions(self.remote)
+ self.ims = ims.ImsFunctions(self.remote)
+ self._amarisoft_preset()
+ self._android_device_preset()
+
+ def _amarisoft_preset(self) -> None:
+ """Sets Amarisoft test network."""
+
+ if not self.remote.ssh_is_connected():
+ raise ssh_utils.NotConnectedError(
+ 'amarisoft_preset: amarisoft is not connected.')
+ self.remote.lte_service_start()
+
+ asserts.skip_if(
+ not self.config.upload_enb_template(config_utils.EnbCfg.ENB_GENERIC),
+ 'amarisoft_preset: Failed to upload enb configuration.')
+ asserts.skip_if(
+ not self.config.upload_mme_template(config_utils.MmeCfg.MME_GENERIC),
+ 'amarisoft_preset: Failed to upload mme configuration.')
+ asserts.skip_if(
+ not self.config.enb_set_plmn('46697'),
+ 'amarisoft_preset: Failed to set ENB PLMN.')
+ asserts.skip_if(
+ not self.config.mme_set_plmn('46697'),
+ 'amarisoft_preset: Failed to set MME PLMN.')
+ asserts.skip_if(
+ not self.config.enb_set_spectrum_tech(config_utils.SpecTech.FDD.value),
+ 'amarisoft_preset: Failed to set ENB spectrum technique.')
+ asserts.skip_if(
+ not self.config.enb_set_fdd_arfcn(275),
+ 'amarisoft_preset: Failed to set ENB FDD ARFCN.')
+
+ self.remote.lte_service_restart()
+ start_time = datetime.datetime.now()
+ while not self.remote.lte_service_is_active():
+ if datetime.datetime.now() - start_time > SERVICE_RESTART_TIME_OUT:
+ asserts.fail('amarisoft_preset: Amarisoft service restart failed.')
+ else:
+ time.sleep(CHECK_INTERVAL)
+ self.log.info('Amarisoft preset completed.')
+
+ def _android_device_preset(self)->None:
+ """Presets the device before the test starts."""
+
+ self.log.info('Android device preset start.')
+ self.ad.droid.connectivityToggleAirplaneMode(False)
+ asserts.skip_if(
+ not wait_until(is_in_service, CHECK_INTERVAL, REGISTRATION_TIMEOUT,
+ True, self.ad), 'android_device_preset: '
+ f'{self.ad.serial} is still out of service after airplane mode off.')
+ self.ad.droid.toggleRingerSilentMode(False)
+ self.ad.adb.shell(ENABLE_TEST_ALERT_CMD)
+ self.ad.reboot()
+ self.ad.droid.setMediaVolume(3)
+ self.ad.droid.setRingerVolume(3)
+ self.ad.droid.setVoiceCallVolume(3)
+ self.ad.droid.setAlarmVolume(3)
+ asserts.assert_true(
+ phone_setup_volte(self.log, self.ad),
+ 'android_device_preset: Failed to set up VoLTE.')
+ self.log.info('Android device preset completed.')
+
+ def mo_call_to_amarisoft(self) -> None:
+ """Executes a MO call process including checking the call status during the MO call.
+
+ The method focus on if any issue found on MO side with below steps:
+ (1) Make a voice call from MO side to MT side(Amarisoft).
+ (2) MT side accepts the call.
+ (3) Check if the call is connect.
+ (4) Monitor the in-call status for MO side during in-call duration.
+ (5) End the call on MO side.
+ """
+ if not self.ad.droid.telephonyIsImsRegistered():
+ asserts.skip(
+ 'mo_call_process: No IMS registered, cannot perform VoLTE call test.')
+ self.ad.log.info('Dial a Call to callbox.')
+ self.ad.droid.telecomCallNumber(self.amarisoft_call_num, False)
+ asserts.assert_true(
+ wait_until(self.ad.droid.telecomGetCallState, CHECK_INTERVAL,
+ WAIT_CALL_STATE_TIMEOUT, CallState.OFFHOOK.name),
+ 'mo_call_process: The call is not connected.')
+ asserts.assert_false(
+ wait_until(self.ad.droid.telecomIsInCall, CHECK_INTERVAL,
+ IN_CALL_DURATION, False),
+ 'mo_call_process: UE drop call before end call.')
+ self.ad.droid.telecomEndCall()
+ asserts.assert_true(
+ wait_until(self.ad.droid.telecomGetCallState, CHECK_INTERVAL,
+ WAIT_CALL_STATE_TIMEOUT, CallState.IDLE.name),
+ 'mo_call_process: UE is still in-call after hanging up the call.')
+
+ def pws_action(self, msg: str, test_scenario: int) -> None:
+ """Performs a PWS broadcast and check android device receives PWS message.
+
+ (1) Device idle or perform mo call/ping test according to test scenario.
+ (2) Broadcast a specific PWS message.
+ (3) Wait 15 seconds for device receive PWS message.
+ (4) Stop broadcast PWS message.
+ (5) Verify android device receive PWS message by check keywords in logcat.
+ (6) Perform mo call/ping test according to test scenario.
+
+ Args:
+ msg: The PWS parameter to be broadcast.
+ test_scenario: The parameters of the test scenario to be executed.
+ """
+ if test_scenario == TestScenario.PS:
+ job.run(f'adb -s {self.ad.serial} shell ping -c 5 8.8.8.8')
+ elif test_scenario == TestScenario.CS:
+ self.mo_call_to_amarisoft()
+
+ logging.info('Broadcast PWS: %s', msg)
+ # Advance the start time by one second to avoid loss of logs
+ # due to time differences between test device and mobileharness.
+ start_time = datetime.datetime.now() - datetime.timedelta(seconds=1)
+ self.mme.pws_write(msg)
+ time.sleep(PWS_START_END_INTERVAL.seconds)
+ self.mme.pws_kill(msg)
+
+ asserts.assert_true(
+ self.ad.search_logcat(
+ f'CBChannelManager: isEmergencyMessage: true, message id = {msg}',
+ start_time), f'{msg} not received.')
+ asserts.assert_false(
+ self.ad.search_logcat('Failed to play alert sound', start_time),
+ f'{msg} failed to play alert sound.')
+
+ if msg in [PWS_ALERT_911, PWS_ALERT_919]:
+ asserts.assert_true(
+ self.ad.search_logcat('playAlertTone: alertType=INFO', start_time),
+ f'{msg} alertType not match expected (alertType=INFO).')
+ else:
+ asserts.assert_true(
+ self.ad.search_logcat('playAlertTone: alertType=DEFAULT', start_time),
+ f'{msg} alertType not match expected (alertType=DEFAULT).')
+
+ if test_scenario == TestScenario.PS:
+ job.run(f'adb -s {self.ad.serial} shell ping -c 5 8.8.8.8')
+ elif test_scenario == TestScenario.CS:
+ self.mo_call_to_amarisoft()
+
+ def teardown_test(self):
+ self.ad.adb.shell(PWS_DUPLICATE_DETECTION_OFF)
+ super().teardown_test()
+
+ def teardown_class(self):
+ self.ad.droid.connectivityToggleAirplaneMode(True)
+ super().teardown_class()
+
+ @test_tracker_info(uuid="f8971b34-fcaa-4915-ba05-36c754378987")
+ def test_pws_idle_4370(self):
+ self.pws_action(PWS_ALERT_4370, TestScenario.IDLE)
+
+ @test_tracker_info(uuid="ed925410-646f-475a-8765-44ea1631cc6a")
+ def test_pws_idle_4371(self):
+ self.pws_action(PWS_ALERT_4371, TestScenario.IDLE)
+
+ @test_tracker_info(uuid="253f2e2e-8262-43b5-a66e-65b2bc73df58")
+ def test_pws_idle_4380(self):
+ self.pws_action(PWS_ALERT_4380, TestScenario.IDLE)
+
+ @test_tracker_info(uuid="95ed6407-3c5b-4f58-9fd9-e5021972f03c")
+ def test_pws_idle_911(self):
+ self.pws_action(PWS_ALERT_911, TestScenario.IDLE)
+
+ @test_tracker_info(uuid="a6f76e03-b808-4194-b286-54a2ca02cb7f")
+ def test_pws_idle_4383(self):
+ self.pws_action(PWS_ALERT_4383, TestScenario.IDLE)
+
+ @test_tracker_info(uuid="8db4be15-2e2c-4616-8f7f-a6b8062d7265")
+ def test_pws_idle_4384(self):
+ self.pws_action(PWS_ALERT_4384, TestScenario.IDLE)
+
+ @test_tracker_info(uuid="79ba63d7-8ffb-48d3-b27e-a8b152ee5a25")
+ def test_pws_idle_4393(self):
+ self.pws_action(PWS_ALERT_4393, TestScenario.IDLE)
+
+ @test_tracker_info(uuid="a07b1c14-dd3f-4818-bc8d-120d006dcea5")
+ def test_pws_idle_919(self):
+ self.pws_action(PWS_ALERT_919, TestScenario.IDLE)
+
+ @test_tracker_info(uuid="00b607a9-e75c-4342-9c7f-9528704ae3bd")
+ def test_pws_ps_4370(self):
+ self.pws_action(PWS_ALERT_4370, TestScenario.PS)
+
+ @test_tracker_info(uuid="feff8d7a-52fe-46f0-abe5-0da698fc985c")
+ def test_pws_ps_4371(self):
+ self.pws_action(PWS_ALERT_4371, TestScenario.PS)
+
+ @test_tracker_info(uuid="22afaaa1-7738-4499-a378-eabb9ae19fa6")
+ def test_pws_ps_4380(self):
+ self.pws_action(PWS_ALERT_4380, TestScenario.PS)
+
+ @test_tracker_info(uuid="d6fb35fa-9058-4c90-ac8d-bc49d6be1070")
+ def test_pws_ps_911(self):
+ self.pws_action(PWS_ALERT_911, TestScenario.PS)
+
+ @test_tracker_info(uuid="9937c39f-4b47-47f4-904a-108123919716")
+ def test_pws_ps_4383(self):
+ self.pws_action(PWS_ALERT_4383, TestScenario.PS)
+
+ @test_tracker_info(uuid="01faa5bb-e02a-42a3-bf08-30e422c684f4")
+ def test_pws_ps_4384(self):
+ self.pws_action(PWS_ALERT_4384, TestScenario.PS)
+
+ @test_tracker_info(uuid="71d02b4a-a1a3-44e1-a28a-aea3a62f758f")
+ def test_pws_ps_4393(self):
+ self.pws_action(PWS_ALERT_4393, TestScenario.PS)
+
+ @test_tracker_info(uuid="f5e7801c-80e0-4cbe-b4b1-133fa88fa4a3")
+ def test_pws_ps_919(self):
+ self.pws_action(PWS_ALERT_919, TestScenario.PS)
+
+ @test_tracker_info(uuid="b68e5593-1748-434c-be2a-e684791f2ca8")
+ def test_pws_cs_4370(self):
+ self.pws_action(PWS_ALERT_4370, TestScenario.CS)
+
+ @test_tracker_info(uuid="a04f433d-bbf0-4a09-b958-719ec8df9991")
+ def test_pws_cs_4371(self):
+ self.pws_action(PWS_ALERT_4371, TestScenario.CS)
+
+ @test_tracker_info(uuid="48432d8d-847a-44e3-aa24-32ae704e15de")
+ def test_pws_cs_4380(self):
+ self.pws_action(PWS_ALERT_4380, TestScenario.CS)
+
+ @test_tracker_info(uuid="9fde76b2-e568-4aa5-a627-9d682ba9e1fb")
+ def test_pws_cs_911(self):
+ self.pws_action(PWS_ALERT_911, TestScenario.CS)
+
+ @test_tracker_info(uuid="fa1f0c6a-22af-4daf-ab32-a508b06de165")
+ def test_pws_cs_4383(self):
+ self.pws_action(PWS_ALERT_4383, TestScenario.CS)
+
+ @test_tracker_info(uuid="45d924be-e204-497d-b598-e18a8c668492")
+ def test_pws_cs_4384(self):
+ self.pws_action(PWS_ALERT_4384, TestScenario.CS)
+
+ @test_tracker_info(uuid="ff4f0e6e-2bda-4047-a69c-7b103868e2d5")
+ def test_pws_cs_4393(self):
+ self.pws_action(PWS_ALERT_4393, TestScenario.CS)
+
+ @test_tracker_info(uuid="ab2bd166-c5e0-4505-ba37-6192bf53226f")
+ def test_pws_cs_919(self):
+ self.pws_action(PWS_ALERT_919, TestScenario.CS)
+
+
diff --git a/acts_tests/tests/google/tel/lab/TelLabSmsTest.py b/acts_tests/tests/google/tel/lab/TelLabSmsTest.py
index 2f2bc68..3ecb101 100644
--- a/acts_tests/tests/google/tel/lab/TelLabSmsTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabSmsTest.py
@@ -44,10 +44,10 @@
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_UMTS
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_rat
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte
from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_apn_by_adb
from acts_contrib.test_utils.tel.tel_defines import CALL_TEARDOWN_PHONE
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_CDMA2000
diff --git a/acts_tests/tests/google/tel/lab/TelLabUeIdentityTest.py b/acts_tests/tests/google/tel/lab/TelLabUeIdentityTest.py
index e7858ce..031c33b 100644
--- a/acts_tests/tests/google/tel/lab/TelLabUeIdentityTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabUeIdentityTest.py
@@ -37,8 +37,8 @@
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_UMTS
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_rat
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
diff --git a/acts_tests/tests/google/tel/lab/TelLabVoiceTest.py b/acts_tests/tests/google/tel/lab/TelLabVoiceTest.py
index f2417dd..ac0b6a2 100644
--- a/acts_tests/tests/google/tel/lab/TelLabVoiceTest.py
+++ b/acts_tests/tests/google/tel/lab/TelLabVoiceTest.py
@@ -23,11 +23,9 @@
from acts.controllers.anritsu_lib.md8475a import CsfbType
from acts.controllers.anritsu_lib.md8475a import MD8475A
from acts.controllers.anritsu_lib.md8475a import VirtualPhoneAutoAnswer
-from acts.controllers.anritsu_lib.md8475a import VirtualPhoneStatus
from acts_contrib.test_utils.tel.anritsu_utils import WAIT_TIME_ANRITSU_REG_AND_CALL
from acts_contrib.test_utils.tel.anritsu_utils import call_mo_setup_teardown
from acts_contrib.test_utils.tel.anritsu_utils import ims_call_cs_teardown
-from acts_contrib.test_utils.tel.anritsu_utils import call_mt_setup_teardown
from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_1x
from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_1x_evdo
from acts_contrib.test_utils.tel.anritsu_utils import set_system_model_gsm
@@ -43,7 +41,6 @@
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_UMTS
-from acts_contrib.test_utils.tel.tel_defines import RAT_1XRTT
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_CDMA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GSM_ONLY
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GSM_UMTS
@@ -52,13 +49,12 @@
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_GSM_WCDMA
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL_FOR_IMS
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_rat
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte
from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_apn_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_volte
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
DEFAULT_CALL_NUMBER = "0123456789"
diff --git a/acts_tests/tests/google/tel/live/TelLiveCBRSTest.py b/acts_tests/tests/google/tel/live/TelLiveCBRSTest.py
index 7b63288..9cd049b 100644
--- a/acts_tests/tests/google/tel/live/TelLiveCBRSTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveCBRSTest.py
@@ -30,14 +30,21 @@
from acts_contrib.test_utils.tel.tel_defines import EventActiveDataSubIdChanged
from acts_contrib.test_utils.tel.tel_defines import NetworkCallbackAvailable
from acts_contrib.test_utils.tel.tel_defines import EventNetworkCallback
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_logger
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import is_phone_not_in_call
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_2g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_not_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_cdma
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_2g
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_cbrs_and_default_sub_id
from acts_contrib.test_utils.tel.tel_test_utils import get_phone_number
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_not_in_call
-from acts_contrib.test_utils.tel.tel_test_utils import wait_and_answer_call
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
from acts_contrib.test_utils.tel.tel_test_utils import load_scone_cat_simulate_data
from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_success_using_sl4a
from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_failure_using_sl4a
@@ -46,27 +53,18 @@
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
from acts_contrib.test_utils.tel.tel_test_utils import STORY_LINE
from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_logger
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_toggle_state
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call_by_adb
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_not_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_general
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte_for_subscription
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_cdma
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_not_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_volte
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_operatorname_from_slot_index
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_cbrs_and_default_sub_id
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
from acts.utils import get_current_epoch_time
from queue import Empty
@@ -74,6 +72,7 @@
WAIT_TIME_BETWEEN_HANDOVER = 10
TIME_PERMITTED_FOR_CBRS_SWITCH = 2
+
class TelLiveCBRSTest(TelephonyBaseTest):
def setup_class(self):
super().setup_class()
diff --git a/acts_tests/tests/google/tel/live/TelLiveCellInfoTest.py b/acts_tests/tests/google/tel/live/TelLiveCellInfoTest.py
index 5895d10..3f7bdc9 100644
--- a/acts_tests/tests/google/tel/live/TelLiveCellInfoTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveCellInfoTest.py
@@ -19,8 +19,8 @@
import time
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected, \
- toggle_airplane_mode, ensure_phones_idle, start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
from acts_contrib.test_utils.wifi import wifi_test_utils
from acts.utils import disable_usb_charging, enable_usb_charging
diff --git a/acts_tests/tests/google/tel/live/TelLiveConnectivityMonitorBaseTest.py b/acts_tests/tests/google/tel/live/TelLiveConnectivityMonitorBaseTest.py
index 5ec5ddb..79035cb 100644
--- a/acts_tests/tests/google/tel/live/TelLiveConnectivityMonitorBaseTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveConnectivityMonitorBaseTest.py
@@ -29,38 +29,37 @@
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_FOR_STATE_CHANGE
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL
+from acts_contrib.test_utils.tel.tel_bootloader_utils import fastboot_wipe
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_wfc
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_enabled
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_2g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
from acts_contrib.test_utils.tel.tel_test_utils import bring_up_connectivity_monitor
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import fastboot_wipe
from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
from acts_contrib.test_utils.tel.tel_test_utils import get_model_name
from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
from acts_contrib.test_utils.tel.tel_test_utils import get_outgoing_voice_sub_id
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import last_call_drop_reason
from acts_contrib.test_utils.tel.tel_test_utils import reboot_device
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_wfc
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wfc_enabled
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_toggle_state
from acts_contrib.test_utils.tel.tel_test_utils import trigger_modem_crash
from acts_contrib.test_utils.tel.tel_test_utils import trigger_modem_crash_by_modem
+from acts_contrib.test_utils.tel.tel_video_utils import video_call_setup_teardown
+from acts_contrib.test_utils.tel.tel_video_utils import phone_setup_video
+from acts_contrib.test_utils.tel.tel_video_utils import is_phone_in_call_video_bidirectional
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_video_utils import video_call_setup_teardown
-from acts_contrib.test_utils.tel.tel_video_utils import phone_setup_video
-from acts_contrib.test_utils.tel.tel_video_utils import \
- is_phone_in_call_video_bidirectional
+from acts_contrib.test_utils.tel.tel_voice_utils import last_call_drop_reason
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
CALL_DROP_CODE_MAPPING = {
373: "Radio Internal Error",
diff --git a/acts_tests/tests/google/tel/live/TelLiveConnectivityMonitorMobilityTest.py b/acts_tests/tests/google/tel/live/TelLiveConnectivityMonitorMobilityTest.py
index fd76813..03fbc55 100644
--- a/acts_tests/tests/google/tel/live/TelLiveConnectivityMonitorMobilityTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveConnectivityMonitorMobilityTest.py
@@ -28,15 +28,14 @@
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_WIFI_RSSI_CALIBRATION_SCREEN_ON
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_WIFI_RSSI_CALIBRATION_WIFI_CONNECTED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WIFI_WEAK_RSSI_VALUE
from acts_contrib.test_utils.tel.tel_defines import SignalStrengthContainer
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_default_state
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wifi_data_connection
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_wifi_data_connection
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_default_state
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_subscription
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
from TelLiveConnectivityMonitorBaseTest import TelLiveConnectivityMonitorBaseTest
# Attenuator name
diff --git a/acts_tests/tests/google/tel/live/TelLiveDSDSVoiceTest.py b/acts_tests/tests/google/tel/live/TelLiveDSDSVoiceTest.py
index 4a711ce..78bd320 100644
--- a/acts_tests/tests/google/tel/live/TelLiveDSDSVoiceTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveDSDSVoiceTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3.4
#
-# Copyright 2019 - Google
+# Copyright 2022 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -21,105 +21,56 @@
import random
import collections
-from queue import Empty
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED
from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_TERMINATED
-from acts_contrib.test_utils.tel.tel_defines import GEN_3G
-from acts_contrib.test_utils.tel.tel_defines import GEN_4G
-from acts_contrib.test_utils.tel.tel_defines import INVALID_WIFI_RSSI
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_DROP
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
-from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
-from acts_contrib.test_utils.tel.tel_defines import PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND
-from acts_contrib.test_utils.tel.tel_defines import PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND
-from acts_contrib.test_utils.tel.tel_defines import PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING
-from acts_contrib.test_utils.tel.tel_defines import RAT_LTE
-from acts_contrib.test_utils.tel.tel_defines import RAT_IWLAN
-from acts_contrib.test_utils.tel.tel_defines import RAT_WCDMA
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_REG_AND_CALL
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_WIFI_RSSI_CALIBRATION_SCREEN_ON
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_WIFI_RSSI_CALIBRATION_WIFI_CONNECTED
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
-from acts_contrib.test_utils.tel.tel_defines import WIFI_WEAK_RSSI_VALUE
-from acts_contrib.test_utils.tel.tel_defines import EventNetworkCallback
-from acts_contrib.test_utils.tel.tel_defines import NetworkCallbackAvailable
-from acts_contrib.test_utils.tel.tel_defines import NetworkCallbackLost
-from acts_contrib.test_utils.tel.tel_defines import SignalStrengthContainer
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_toggle_state
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_generation
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_default_state
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import get_phone_number
-from acts_contrib.test_utils.tel.tel_test_utils import get_phone_number_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import is_network_call_back_event_match
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_not_in_call
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte
-from acts_contrib.test_utils.tel.tel_test_utils import wait_and_answer_call
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_cell_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_droid_not_in_call
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wfc_disabled
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wfc_enabled
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wifi_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.tel.tel_test_utils import get_telephony_signal_strength
-from acts_contrib.test_utils.tel.tel_test_utils import get_lte_rsrp
-from acts_contrib.test_utils.tel.tel_test_utils import get_wifi_signal_strength
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_state
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_logger
-from acts_contrib.test_utils.tel.tel_test_utils import active_file_download_test
-from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_success_using_sl4a
-from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_failure_using_sl4a
-from acts_contrib.test_utils.tel.tel_test_utils import sms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import mms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_not_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_general
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_3g_for_subscription
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_not_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_2g
+from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_test
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_logger
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_message_utils import mms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import is_phone_not_in_call
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_2g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_3g_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_2g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_not_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_volte
from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_outgoing_call
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_incoming_voice_sub_id
from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
from acts_contrib.test_utils.tel.tel_subscription_utils import get_operatorname_from_slot_index
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id
from acts_contrib.test_utils.tel.tel_subscription_utils import perform_dds_switch
from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_data
from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_0
from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_1
from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_message
from acts_contrib.test_utils.tel.tel_subscription_utils import set_always_allow_mms_data
+from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
+from acts_contrib.test_utils.tel.tel_test_utils import get_phone_number
+from acts_contrib.test_utils.tel.tel_test_utils import get_phone_number_for_subscription
+from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
+from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_success_using_sl4a
+from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_failure_using_sl4a
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call_by_adb
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_not_iwlan
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
from acts.utils import get_current_epoch_time
from acts.utils import rand_ascii_str
diff --git a/acts_tests/tests/google/tel/live/TelLiveDataTest.py b/acts_tests/tests/google/tel/live/TelLiveDataTest.py
index 7881a8c..cd297ba 100755
--- a/acts_tests/tests/google/tel/live/TelLiveDataTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveDataTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3.4
#
-# Copyright 2016 - Google
+# Copyright 2022 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -23,13 +23,8 @@
import os
from acts import signals
-from acts.utils import disable_doze
-from acts.utils import enable_doze
from acts.utils import rand_ascii_str
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_subid_from_slot_index
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_data
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED
from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_TERMINATED
@@ -48,25 +43,30 @@
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_TETHERING_ENTITLEMENT_CHECK
from acts_contrib.test_utils.tel.tel_defines import TETHERING_MODE_WIFI
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_AFTER_REBOOT
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
-from acts_contrib.test_utils.tel.tel_defines import \
- WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_TETHERING_AFTER_REBOOT
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING
from acts_contrib.test_utils.tel.tel_defines import TETHERING_PASSWORD_HAS_ESCAPE
from acts_contrib.test_utils.tel.tel_defines import TETHERING_SPECIAL_SSID_LIST
from acts_contrib.test_utils.tel.tel_defines import TETHERING_SPECIAL_PASSWORD_LIST
+from acts_contrib.test_utils.tel.tel_bt_utils import verify_bluetooth_tethering_connection
+from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_test
from acts_contrib.test_utils.tel.tel_data_utils import airplane_mode_test
from acts_contrib.test_utils.tel.tel_data_utils import browsing_test
+from acts_contrib.test_utils.tel.tel_data_utils import get_mobile_data_usage
from acts_contrib.test_utils.tel.tel_data_utils import reboot_test
from acts_contrib.test_utils.tel.tel_data_utils import change_data_sim_and_verify_data
+from acts_contrib.test_utils.tel.tel_data_utils import check_data_stall_detection
+from acts_contrib.test_utils.tel.tel_data_utils import check_data_stall_recovery
+from acts_contrib.test_utils.tel.tel_data_utils import check_network_validation_fail
from acts_contrib.test_utils.tel.tel_data_utils import data_connectivity_single_bearer
+from acts_contrib.test_utils.tel.tel_data_utils import remove_mobile_data_usage_limit
+from acts_contrib.test_utils.tel.tel_data_utils import set_mobile_data_usage_limit
from acts_contrib.test_utils.tel.tel_data_utils import tethering_check_internet_connection
from acts_contrib.test_utils.tel.tel_data_utils import test_data_connectivity_multi_bearer
from acts_contrib.test_utils.tel.tel_data_utils import test_setup_tethering
from acts_contrib.test_utils.tel.tel_data_utils import test_tethering_wifi_and_voice_call
from acts_contrib.test_utils.tel.tel_data_utils import test_wifi_connect_disconnect
-from acts_contrib.test_utils.tel.tel_data_utils import verify_bluetooth_tethering_connection
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_wifi_data_connection
from acts_contrib.test_utils.tel.tel_data_utils import wifi_cell_switching
from acts_contrib.test_utils.tel.tel_data_utils import wifi_tethering_cleanup
from acts_contrib.test_utils.tel.tel_data_utils import verify_toggle_apm_tethering_internet_connection
@@ -81,53 +81,38 @@
from acts_contrib.test_utils.tel.tel_data_utils import setup_device_internet_connection_then_reboot
from acts_contrib.test_utils.tel.tel_data_utils import verify_internet_connection_in_doze_mode
from acts_contrib.test_utils.tel.tel_data_utils import verify_toggle_data_during_wifi_tethering
-from acts_contrib.test_utils.tel.tel_test_utils import active_file_download_test
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import check_is_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_default_state
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_generation
-from acts_contrib.test_utils.tel.tel_test_utils import \
- ensure_network_generation_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import get_mobile_data_usage
-from acts_contrib.test_utils.tel.tel_test_utils import get_slot_index_from_subid
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import remove_mobile_data_usage_limit
-from acts_contrib.test_utils.tel.tel_test_utils import set_mobile_data_usage_limit
-from acts_contrib.test_utils.tel.tel_test_utils import stop_wifi_tethering
-from acts_contrib.test_utils.tel.tel_test_utils import start_wifi_tethering
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_subid
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_data
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_4g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_default_state
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation_for_subscription
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_cell_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import \
- wait_for_data_attach_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wifi_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_reset
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_toggle_state
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_SSID_KEY
-from acts_contrib.test_utils.tel.tel_test_utils import check_data_stall_detection
-from acts_contrib.test_utils.tel.tel_test_utils import check_network_validation_fail
+from acts_contrib.test_utils.tel.tel_test_utils import wait_for_data_attach_for_subscription
from acts_contrib.test_utils.tel.tel_test_utils import break_internet_except_sl4a_port
from acts_contrib.test_utils.tel.tel_test_utils import resume_internet_with_sl4a_port
from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
-from acts_contrib.test_utils.tel.tel_test_utils import check_data_stall_recovery
-from acts_contrib.test_utils.tel.tel_test_utils import \
- test_data_browsing_success_using_sl4a
-from acts_contrib.test_utils.tel.tel_test_utils import \
- test_data_browsing_failure_using_sl4a
+from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_success_using_sl4a
+from acts_contrib.test_utils.tel.tel_test_utils import test_data_browsing_failure_using_sl4a
from acts_contrib.test_utils.tel.tel_test_utils import set_time_sync_from_network
from acts_contrib.test_utils.tel.tel_test_utils import datetime_handle
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_4g
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import stop_wifi_tethering
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_reset
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
class TelLiveDataTest(TelephonyBaseTest):
@@ -140,7 +125,7 @@
def setup_test(self):
TelephonyBaseTest.setup_test(self)
- self.number_of_devices = 1
+ self.number_of_devices = 2
def teardown_class(self):
TelephonyBaseTest.teardown_class(self)
@@ -162,10 +147,13 @@
"""
ad = self.android_devices[0]
wifi_toggle_state(ad.log, ad, False)
+ self.number_of_devices = 1
+
for iteration in range(3):
ad.log.info("Attempt %d", iteration + 1)
if test_data_browsing_success_using_sl4a(ad.log, ad):
- ad.log.info("Call test PASS in iteration %d", iteration + 1)
+ ad.log.info("Data Browsing test PASS in iteration %d",
+ iteration + 1)
return True
time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
ad.log.info("Data Browsing test FAIL for all 3 iterations")
@@ -185,6 +173,8 @@
"""
ad = self.android_devices[0]
wifi_toggle_state(ad.log, ad, True)
+ self.number_of_devices = 1
+
if not ensure_wifi_connected(ad.log, ad, self.wifi_network_ssid,
self.wifi_network_pass):
ad.log.error("WiFi connect fail.")
@@ -192,7 +182,8 @@
for iteration in range(3):
ad.log.info("Attempt %d", iteration + 1)
if test_data_browsing_success_using_sl4a(ad.log, ad):
- ad.log.info("Call test PASS in iteration %d", iteration + 1)
+ ad.log.info("Data Browsing test PASS in iteration %d",
+ iteration + 1)
wifi_toggle_state(ad.log, ad, False)
return True
time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
@@ -214,6 +205,8 @@
Returns:
True if pass; False if fail.
"""
+ self.number_of_devices = 1
+
return airplane_mode_test(self.log, self.android_devices[0])
@test_tracker_info(uuid="47430f01-583f-4efb-923a-285a51b75d50")
@@ -231,6 +224,8 @@
Returns:
True if pass.
"""
+ self.number_of_devices = 1
+
return wifi_cell_switching(self.log, self.android_devices[0], GEN_4G,
self.wifi_network_ssid,
self.wifi_network_pass)
@@ -249,6 +244,7 @@
success_count = 0
fail_count = 0
self.stress_test_number = 10
+ self.number_of_devices = 1
for i in range(1, self.stress_test_number + 1):
ensure_phones_default_state(
@@ -289,6 +285,8 @@
Returns:
True if pass.
"""
+ self.number_of_devices = 1
+
return wifi_cell_switching(self.log, self.android_devices[0], GEN_3G,
self.wifi_network_ssid,
self.wifi_network_pass)
@@ -308,6 +306,8 @@
Returns:
True if pass.
"""
+ self.number_of_devices = 1
+
return wifi_cell_switching(self.log, self.android_devices[0], GEN_2G,
self.wifi_network_ssid,
self.wifi_network_pass)
@@ -330,6 +330,8 @@
False if failed.
"""
ads = self.android_devices
+ self.number_of_devices = 1
+
if not phone_setup_volte(self.log, self.android_devices[0]):
self.log.error("Failed to setup VoLTE")
return False
@@ -405,7 +407,6 @@
MINIMUM_SUCCESS_RATE = .95
success_count = 0
fail_count = 0
- self.number_of_devices = 2
for i in range(1, self.stress_test_number + 1):
@@ -486,6 +487,8 @@
True if success.
False if failed.
"""
+ self.number_of_devices = 1
+
wifi_reset(self.log, self.android_devices[0])
wifi_toggle_state(self.log, self.android_devices[0], False)
return data_connectivity_single_bearer(self.log,
@@ -506,6 +509,8 @@
True if success.
False if failed.
"""
+ self.number_of_devices = 1
+
wifi_reset(self.log, self.android_devices[0])
wifi_toggle_state(self.log, self.android_devices[0], False)
wifi_toggle_state(self.log, self.android_devices[0], True)
@@ -527,6 +532,8 @@
True if success.
False if failed.
"""
+ self.number_of_devices = 1
+
wifi_reset(self.log, self.android_devices[0])
wifi_toggle_state(self.log, self.android_devices[0], False)
return data_connectivity_single_bearer(self.log,
@@ -547,6 +554,8 @@
True if success.
False if failed.
"""
+ self.number_of_devices = 1
+
wifi_reset(self.log, self.android_devices[0])
wifi_toggle_state(self.log, self.android_devices[0], False)
wifi_toggle_state(self.log, self.android_devices[0], True)
@@ -568,6 +577,8 @@
True if success.
False if failed.
"""
+ self.number_of_devices = 1
+
wifi_reset(self.log, self.android_devices[0])
wifi_toggle_state(self.log, self.android_devices[0], False)
return data_connectivity_single_bearer(self.log,
@@ -588,6 +599,8 @@
True if success.
False if failed.
"""
+ self.number_of_devices = 1
+
wifi_reset(self.log, self.android_devices[0])
wifi_toggle_state(self.log, self.android_devices[0], False)
wifi_toggle_state(self.log, self.android_devices[0], True)
@@ -609,6 +622,7 @@
MINIMUM_SUCCESS_RATE = .95
success_count = 0
fail_count = 0
+ self.number_of_devices = 1
for i in range(1, self.stress_test_number + 1):
@@ -1463,6 +1477,8 @@
Returns:
True if entitlement check returns True.
"""
+ self.number_of_devices = 1
+
return verify_tethering_entitlement_check(self.log,
self.provider)
@@ -1565,7 +1581,7 @@
return False
ssid_list = TETHERING_SPECIAL_SSID_LIST
fail_list = {}
- self.number_of_devices = 2
+
for ssid in ssid_list:
password = rand_ascii_str(8)
self.log.info("SSID: <{}>, Password: <{}>".format(ssid, password))
@@ -1599,7 +1615,7 @@
return False
password_list = TETHERING_SPECIAL_PASSWORD_LIST
fail_list = {}
- self.number_of_devices = 2
+
for password in password_list:
ssid = rand_ascii_str(8)
self.log.info("SSID: <{}>, Password: <{}>".format(ssid, password))
@@ -1887,9 +1903,10 @@
False if failed.
"""
ad = self.android_devices[0]
+ self.number_of_devices = 1
current_data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
current_sim_slot_index = get_slot_index_from_subid(
- self.log, ad, current_data_sub_id)
+ ad, current_data_sub_id)
if current_sim_slot_index == SIM1_SLOT_INDEX:
next_sim_slot_index = SIM2_SLOT_INDEX
else:
@@ -1950,6 +1967,8 @@
"""
ad = self.android_devices[0]
+ self.number_of_devices = 1
+
if not ensure_network_generation_for_subscription(
self.log, ad, ad.droid.subscriptionGetDefaultDataSubId(),
GEN_4G, MAX_WAIT_TIME_NW_SELECTION, NETWORK_SERVICE_DATA):
@@ -1979,6 +1998,8 @@
"""
ad = self.android_devices[0]
+ self.number_of_devices = 1
+
if not ensure_network_generation_for_subscription(
self.log, ad, ad.droid.subscriptionGetDefaultDataSubId(),
GEN_3G, MAX_WAIT_TIME_NW_SELECTION, NETWORK_SERVICE_DATA):
@@ -2007,6 +2028,8 @@
False if failed.
"""
ad = self.android_devices[0]
+ self.number_of_devices = 1
+
if not ensure_network_generation_for_subscription(
self.log, ad, ad.droid.subscriptionGetDefaultDataSubId(),
GEN_2G, MAX_WAIT_TIME_NW_SELECTION, NETWORK_SERVICE_DATA):
@@ -2181,7 +2204,7 @@
current_data_sub_id = self.provider.droid.subscriptionGetDefaultDataSubId(
)
current_sim_slot_index = get_slot_index_from_subid(
- self.log, self.provider, current_data_sub_id)
+ self.provider, current_data_sub_id)
self.provider.log.info("Current Data is on subId: %s, SIM slot: %s",
current_data_sub_id, current_sim_slot_index)
if not test_setup_tethering(self.log, self.provider, self.clients, None):
@@ -2240,9 +2263,11 @@
False if failed.
"""
ad = self.android_devices[0]
+ self.number_of_devices = 1
+
current_data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
current_sim_slot_index = get_slot_index_from_subid(
- self.log, ad, current_data_sub_id)
+ ad, current_data_sub_id)
if current_sim_slot_index == SIM1_SLOT_INDEX:
next_sim_slot_index = SIM2_SLOT_INDEX
else:
@@ -2298,6 +2323,8 @@
@TelephonyBaseTest.tel_test_wrap
def test_vzw_embms_services(self):
ad = self.android_devices[0]
+ self.number_of_devices = 1
+
# Install App and Push config
self.log.info("Pushing embms config and apk to the Android device.")
android_embms_path = "/sdcard/mobitv"
@@ -2391,9 +2418,10 @@
False if failed.
"""
ad = self.android_devices[0]
+ self.number_of_devices = 1
current_data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
current_sim_slot_index = get_slot_index_from_subid(
- self.log, ad, current_data_sub_id)
+ ad, current_data_sub_id)
if current_sim_slot_index == SIM1_SLOT_INDEX:
non_active_sim_slot_index = SIM2_SLOT_INDEX
else:
@@ -2440,6 +2468,7 @@
total_count = 0
self.result_info = collections.defaultdict(int)
dut = self.android_devices[0]
+ self.number_of_devices = 1
self.max_sleep_time = int(self.user_params.get("max_sleep_time", 1200))
#file_names = ["5MB", "10MB", "20MB", "50MB", "200MB", "512MB", "1GB"]
file_names = ["5MB", "10MB", "20MB", "50MB", "200MB", "512MB"]
@@ -2499,6 +2528,7 @@
"""
dut = self.android_devices[0]
+ self.number_of_devices = 1
ensure_phones_default_state(self.log, [dut])
subscriber_id = dut.droid.telephonyGetSubscriberId()
old_data_usage = get_mobile_data_usage(dut, subscriber_id)
@@ -2538,6 +2568,8 @@
def _test_data_stall_detection_recovery(self, nw_type="cellular",
validation_type="detection"):
dut = self.android_devices[0]
+ self.number_of_devices = 1
+
try:
cmd = ('ss -l -p -n | grep "tcp.*droid_script" | tr -s " " '
'| cut -d " " -f 5 | sed s/.*://g')
@@ -2585,6 +2617,7 @@
def _test_airplane_mode_stress(self):
ad = self.android_devices[0]
+ self.number_of_devices = 1
total_iteration = self.stress_test_number
fail_count = collections.defaultdict(int)
current_iteration = 1
@@ -2668,6 +2701,8 @@
@TelephonyBaseTest.tel_test_wrap
def test_browsing_4g(self):
ad = self.android_devices[0]
+ self.number_of_devices = 1
+
self.log.info("Connect to LTE and verify internet connection.")
if not phone_setup_4g(self.log, ad):
return False
@@ -2680,6 +2715,8 @@
@TelephonyBaseTest.tel_test_wrap
def test_browsing_wifi(self):
ad = self.android_devices[0]
+ self.number_of_devices = 1
+
self.log.info("Connect to Wi-Fi and verify internet connection.")
if not ensure_wifi_connected(self.log, ad, self.wifi_network_ssid,
self.wifi_network_pass):
@@ -2754,6 +2791,8 @@
"""
ad = self.android_devices[0]
+ self.number_of_devices = 1
+
wifi_toggle_state(ad.log, ad, False)
return self._test_sync_time_from_network(ad)
@@ -2770,6 +2809,8 @@
"""
ad = self.android_devices[0]
+ self.number_of_devices = 1
+
wifi_toggle_state(ad.log, ad, False)
return self._test_sync_time_from_network(ad, data_on=False)
@@ -2777,6 +2818,8 @@
@TelephonyBaseTest.tel_test_wrap
def test_reboot_4g(self):
ad = self.android_devices[0]
+ self.number_of_devices = 1
+
self.log.info("Connect to LTE and verify internet connection.")
if not phone_setup_4g(self.log, ad):
return False
@@ -2789,6 +2832,8 @@
@TelephonyBaseTest.tel_test_wrap
def test_reboot_3g(self):
ad = self.android_devices[0]
+ self.number_of_devices = 1
+
self.log.info("Connect to 3G and verify internet connection.")
if not phone_setup_3g(self.log, ad):
return False
@@ -2801,6 +2846,8 @@
@TelephonyBaseTest.tel_test_wrap
def test_reboot_wifi(self):
ad = self.android_devices[0]
+ self.number_of_devices = 1
+
self.log.info("Connect to Wi-Fi and verify internet connection.")
if not ensure_wifi_connected(self.log, ad, self.wifi_network_ssid,
self.wifi_network_pass):
diff --git a/acts_tests/tests/google/tel/live/TelLiveEmergencyBase.py b/acts_tests/tests/google/tel/live/TelLiveEmergencyBase.py
index edb8b39..eb60081 100644
--- a/acts_tests/tests/google/tel/live/TelLiveEmergencyBase.py
+++ b/acts_tests/tests/google/tel/live/TelLiveEmergencyBase.py
@@ -20,38 +20,26 @@
import re
import time
from acts import signals
-from acts.test_decorators import test_tracker_info
+from acts.utils import get_current_epoch_time
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC
-from acts_contrib.test_utils.tel.tel_defines import DEFAULT_DEVICE_PASSWORD
-from acts_contrib.test_utils.tel.tel_defines import PHONE_TYPE_CDMA
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
-from acts_contrib.test_utils.tel.tel_lookup_tables import operator_capabilities
+from acts_contrib.test_utils.tel.tel_bootloader_utils import reset_device_password
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_default_state
from acts_contrib.test_utils.tel.tel_test_utils import abort_all_tests
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import dumpsys_last_call_info
-from acts_contrib.test_utils.tel.tel_test_utils import dumpsys_last_call_number
-from acts_contrib.test_utils.tel.tel_test_utils import dumpsys_new_call_info
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_default_state
from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
from acts_contrib.test_utils.tel.tel_test_utils import get_service_state_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import fastboot_wipe
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
from acts_contrib.test_utils.tel.tel_test_utils import is_sim_lock_enabled
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_emergency_dialer_call_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import last_call_drop_reason
-from acts_contrib.test_utils.tel.tel_test_utils import reset_device_password
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
from acts_contrib.test_utils.tel.tel_test_utils import unlock_sim
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_cell_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_sim_ready_by_adb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
-from acts.utils import get_current_epoch_time
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import dumpsys_last_call_info
+from acts_contrib.test_utils.tel.tel_voice_utils import dumpsys_last_call_number
+from acts_contrib.test_utils.tel.tel_voice_utils import dumpsys_new_call_info
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call_by_adb
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_emergency_dialer_call_by_adb
+from acts_contrib.test_utils.tel.tel_voice_utils import last_call_drop_reason
CARRIER_OVERRIDE_CMD = (
"am broadcast -a com.google.android.carrier.action.LOCAL_OVERRIDE -n "
diff --git a/acts_tests/tests/google/tel/live/TelLiveEmergencyTest.py b/acts_tests/tests/google/tel/live/TelLiveEmergencyTest.py
index e29ed7a..9f078b3 100644
--- a/acts_tests/tests/google/tel/live/TelLiveEmergencyTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveEmergencyTest.py
@@ -23,15 +23,15 @@
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC
from acts_contrib.test_utils.tel.tel_defines import DEFAULT_DEVICE_PASSWORD
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.tel.tel_bootloader_utils import fastboot_wipe
+from acts_contrib.test_utils.tel.tel_bootloader_utils import reset_device_password
from acts_contrib.test_utils.tel.tel_lookup_tables import operator_capabilities
-from acts_contrib.test_utils.tel.tel_test_utils import fastboot_wipe
-from acts_contrib.test_utils.tel.tel_test_utils import reset_device_password
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_2g
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
from acts_contrib.test_utils.tel.tel_test_utils import wait_for_sim_ready_by_adb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
from TelLiveEmergencyBase import TelLiveEmergencyBase
diff --git a/acts_tests/tests/google/tel/live/TelLiveGFTDSDSDDSSwitchTest.py b/acts_tests/tests/google/tel/live/TelLiveGFTDSDSDDSSwitchTest.py
index 2734fed..b762af0 100644
--- a/acts_tests/tests/google/tel/live/TelLiveGFTDSDSDDSSwitchTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveGFTDSDSDDSSwitchTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2020 - Google
+# Copyright 2022 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,64 +14,54 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import re
import time
-from acts import asserts
from acts import signals
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import \
- TelephonyVoiceTestResult
-from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import \
- TelephonyMetricLogger
+from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
+from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_data_utils import reboot_test
+from acts_contrib.test_utils.tel.tel_data_utils import start_youtube_video
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection_for_subscription
+from acts_contrib.test_utils.tel.tel_ims_utils import is_volte_enabled
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode_for_subscription
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte_for_subscription
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_wfc_for_subscription
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_enabled
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify_for_subscription
+from acts_contrib.test_utils.tel.tel_message_utils import mms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_message_utils import log_messaging_screen_shot
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_on_rat
from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_subid
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
from acts_contrib.test_utils.tel.tel_subscription_utils import set_message_subid
from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_data
from acts_contrib.test_utils.tel.tel_subscription_utils import set_voice_sub_id
from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_0
from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_1
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_subid_on_same_network_of_host_ad
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import start_youtube_video
-from acts_contrib.test_utils.tel.tel_test_utils import \
- wait_for_cell_data_connection_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_wfc_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import \
- sms_send_receive_verify_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import mms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad
from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import log_messaging_screen_shot
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import get_slot_index_from_subid
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_test_utils import is_volte_enabled
-from acts_contrib.test_utils.tel.tel_test_utils import check_is_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wfc_enabled
-from acts_contrib.test_utils.tel.tel_voice_utils import \
- phone_setup_volte_for_subscription
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_on_rat
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_on_rat
from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_msim_for_slot
+from acts_contrib.test_utils.tel.tel_wifi_utils import check_is_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
from acts.utils import rand_ascii_str
CallResult = TelephonyVoiceTestResult.CallResult.Value
+
class TelLiveGFTDSDSDDSSwitchTest(TelephonyBaseTest):
def setup_class(self):
TelephonyBaseTest.setup_class(self)
@@ -335,10 +325,8 @@
if call_or_sms_or_mms == "call":
self.log.info("Step 4: Make voice call.")
- mo_slot = get_slot_index_from_subid(
- self.log, ad_mo, mo_sub_id)
- mt_slot = get_slot_index_from_subid(
- self.log, ad_mt, mt_sub_id)
+ mo_slot = get_slot_index_from_subid(ad_mo, mo_sub_id)
+ mt_slot = get_slot_index_from_subid(ad_mt, mt_sub_id)
result = two_phone_call_msim_for_slot(
self.log,
ad_mo,
@@ -668,8 +656,8 @@
return False
self.log.info("Step 6: Make voice call.")
- mo_slot = get_slot_index_from_subid(self.log, ad_mo, mo_sub_id)
- mt_slot = get_slot_index_from_subid(self.log, ad_mt, mt_sub_id)
+ mo_slot = get_slot_index_from_subid(ad_mo, mo_sub_id)
+ mt_slot = get_slot_index_from_subid(ad_mt, mt_sub_id)
result = two_phone_call_msim_for_slot(
self.log,
ad_mo,
diff --git a/acts_tests/tests/google/tel/live/TelLiveGFTDSDSMessageTest.py b/acts_tests/tests/google/tel/live/TelLiveGFTDSDSMessageTest.py
index b735184..344da22 100644
--- a/acts_tests/tests/google/tel/live/TelLiveGFTDSDSMessageTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveGFTDSDSMessageTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2020 - Google
+# Copyright 2021 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,51 +14,31 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import time
-
-from acts import asserts
from acts import signals
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import \
- TelephonyVoiceTestResult
-from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import \
- TelephonyMetricLogger
+from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
+from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_incoming_voice_sub_id
+from acts_contrib.test_utils.tel.tel_dsds_utils import dsds_message_test
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_on_rat
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_subid
from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_outgoing_message_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad
from acts_contrib.test_utils.tel.tel_subscription_utils import set_message_subid
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_data
from acts_contrib.test_utils.tel.tel_subscription_utils import set_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_0
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_1
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_subid_on_same_network_of_host_ad
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import \
- sms_send_receive_verify_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import \
- sms_in_collision_send_receive_verify_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import \
- sms_rx_power_off_multiple_send_receive_verify_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import \
- voice_call_in_collision_with_mt_sms_msim
-from acts_contrib.test_utils.tel.tel_test_utils import mms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot
+from acts_contrib.test_utils.tel.tel_message_utils import log_messaging_screen_shot
+from acts_contrib.test_utils.tel.tel_message_utils import sms_in_collision_send_receive_verify_for_subscription
+from acts_contrib.test_utils.tel.tel_message_utils import sms_rx_power_off_multiple_send_receive_verify_for_subscription
+from acts_contrib.test_utils.tel.tel_message_utils import voice_call_in_collision_with_mt_sms_msim
from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.tel.tel_test_utils import log_messaging_screen_shot
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import get_slot_index_from_subid
-from acts_contrib.test_utils.tel.tel_voice_utils import \
- phone_setup_voice_general_for_subscription
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_on_rat
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_on_rat
from acts.utils import rand_ascii_str
+from acts.libs.utils.multithread import multithread_func
CallResult = TelephonyVoiceTestResult.CallResult.Value
@@ -71,71 +51,6 @@
def teardown_test(self):
ensure_phones_idle(self.log, self.android_devices)
- def _msim_message_test(
- self,
- ad_mo,
- ad_mt,
- mo_sub_id,
- mt_sub_id, msg="SMS",
- max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
- expected_result=True):
- """Make MO/MT SMS/MMS at specific slot.
-
- Args:
- ad_mo: Android object of the device sending SMS/MMS
- ad_mt: Android object of the device receiving SMS/MMS
- mo_sub_id: Sub ID of MO device
- mt_sub_id: Sub ID of MT device
- max_wait_time: Max wait time before SMS/MMS is received.
- expected_result: True for successful sending/receiving and False on
- the contrary
-
- Returns:
- True if the result matches expected_result and False on the
- contrary.
- """
-
- if msg == "SMS":
- for length in self.message_lengths:
- message_array = [rand_ascii_str(length)]
- if not sms_send_receive_verify_for_subscription(
- self.log,
- ad_mo,
- ad_mt,
- mo_sub_id,
- mt_sub_id,
- message_array,
- max_wait_time):
- ad_mo.log.warning(
- "%s of length %s test failed", msg, length)
- return False
- else:
- ad_mo.log.info(
- "%s of length %s test succeeded", msg, length)
- self.log.info("%s test of length %s characters succeeded.",
- msg, self.message_lengths)
-
- elif msg == "MMS":
- for length in self.message_lengths:
- message_array = [("Test Message", rand_ascii_str(length), None)]
-
- if not mms_send_receive_verify(
- self.log,
- ad_mo,
- ad_mt,
- message_array,
- max_wait_time,
- expected_result):
- self.log.warning("%s of body length %s test failed",
- msg, length)
- return False
- else:
- self.log.info(
- "%s of body length %s test succeeded", msg, length)
- self.log.info("%s test of body lengths %s succeeded",
- msg, self.message_lengths)
- return True
-
def _msim_sms_collision_test(
self,
ad_mo,
@@ -245,181 +160,6 @@
"off succeeded.", self.message_lengths)
return True
-
- def _test_msim_message(
- self,
- mo_slot,
- mt_slot,
- dds_slot,
- msg="SMS",
- mo_rat=["", ""],
- mt_rat=["", ""],
- direction="mo",
- expected_result=True):
- """Make MO/MT SMS/MMS at specific slot in specific RAT with DDS at
- specific slot.
-
- Test step:
- 1. Get sub IDs of specific slots of both MO and MT devices.
- 2. Switch DDS to specific slot.
- 3. Check HTTP connection after DDS switch.
- 4. Set up phones in desired RAT.
- 5. Send SMS/MMS.
-
- Args:
- mo_slot: Slot sending MO SMS (0 or 1)
- mt_slot: Slot receiving MT SMS (0 or 1)
- dds_slot: Preferred data slot
- mo_rat: RAT for both slots of MO device
- mt_rat: RAT for both slots of MT device
- direction: "mo" or "mt"
- expected_result: True of False
-
- Returns:
- TestFailure if failed.
- """
- ads = self.android_devices
-
- if direction == "mo":
- ad_mo = ads[0]
- ad_mt = ads[1]
- else:
- ad_mo = ads[1]
- ad_mt = ads[0]
-
- if mo_slot is not None:
- mo_sub_id = get_subid_from_slot_index(self.log, ad_mo, mo_slot)
- if mo_sub_id == INVALID_SUB_ID:
- ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot)
- return False
- mo_other_sub_id = get_subid_from_slot_index(
- self.log, ad_mo, 1-mo_slot)
- set_message_subid(ad_mo, mo_sub_id)
- else:
- _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(
- ads, type="sms")
- if mo_sub_id == INVALID_SUB_ID:
- ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot)
- return False
- mo_slot = "auto"
- set_message_subid(ad_mo, mo_sub_id)
- if msg == "MMS":
- set_subid_for_data(ad_mo, mo_sub_id)
- ad_mo.droid.telephonyToggleDataConnection(True)
- ad_mo.log.info("Sub ID for outgoing %s at slot %s: %s", msg, mo_slot,
- get_outgoing_message_sub_id(ad_mo))
-
- if mt_slot is not None:
- mt_sub_id = get_subid_from_slot_index(self.log, ad_mt, mt_slot)
- if mt_sub_id == INVALID_SUB_ID:
- ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
- return False
- mt_other_sub_id = get_subid_from_slot_index(
- self.log, ad_mt, 1-mt_slot)
- set_message_subid(ad_mt, mt_sub_id)
- else:
- _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(
- ads, type="sms")
- if mt_sub_id == INVALID_SUB_ID:
- ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
- return False
- mt_slot = "auto"
- set_message_subid(ad_mt, mt_sub_id)
- if msg == "MMS":
- set_subid_for_data(ad_mt, mt_sub_id)
- ad_mt.droid.telephonyToggleDataConnection(True)
- ad_mt.log.info("Sub ID for incoming %s at slot %s: %s", msg, mt_slot,
- get_outgoing_message_sub_id(ad_mt))
-
- self.log.info("Step 1: Switch DDS.")
- if dds_slot:
- if not set_dds_on_slot_1(ads[0]):
- self.log.warning(
- "Failed to set DDS at eSIM on %s", ads[0].serial)
- return False
- else:
- if not set_dds_on_slot_0(ads[0]):
- self.log.warning(
- "Failed to set DDS at pSIM on %s", ads[0].serial)
- return False
-
- self.log.info("Step 2: Check HTTP connection after DDS switch.")
- if not verify_http_connection(self.log,
- ads[0],
- url="https://www.google.com",
- retry=5,
- retry_interval=15,
- expected_state=True):
-
- self.log.error("Failed to verify http connection.")
- return False
- else:
- self.log.info("Verify http connection successfully.")
-
- if mo_slot == 0 or mo_slot == 1:
- phone_setup_on_rat(self.log, ad_mo, mo_rat[1-mo_slot], mo_other_sub_id)
- else:
- phone_setup_on_rat(self.log, ad_mo, 'general', sub_id_type='sms')
-
- if mt_slot == 0 or mt_slot == 1:
- phone_setup_on_rat(self.log, ad_mt, mt_rat[1-mt_slot], mt_other_sub_id)
- else:
- phone_setup_on_rat(self.log, ad_mt, 'general', sub_id_type='sms')
-
- if mo_slot == 0 or mo_slot == 1:
- mo_phone_setup_func = phone_setup_on_rat(
- self.log,
- ad_mo,
- mo_rat[mo_slot],
- only_return_fn=True)
- else:
- mo_phone_setup_func = phone_setup_voice_general_for_subscription
-
- if mt_slot == 0 or mt_slot == 1:
- mt_phone_setup_func = phone_setup_on_rat(
- self.log,
- ad_mt,
- mt_rat[mt_slot],
- only_return_fn=True)
- else:
- mt_phone_setup_func = phone_setup_voice_general_for_subscription
-
- self.log.info("Step 3: Set up phones in desired RAT.")
- tasks = [(mo_phone_setup_func, (self.log, ad_mo, mo_sub_id)),
- (mt_phone_setup_func, (self.log, ad_mt, mt_sub_id))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
-
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- self.log.info("Step 4: Send %s.", msg)
-
- if msg == "MMS":
- for ad, current_data_sub_id, current_msg_sub_id in [
- [ ads[0],
- get_default_data_sub_id(ads[0]),
- get_outgoing_message_sub_id(ads[0]) ],
- [ ads[1],
- get_default_data_sub_id(ads[1]),
- get_outgoing_message_sub_id(ads[1]) ]]:
- if current_data_sub_id != current_msg_sub_id:
- ad.log.warning(
- "Current data sub ID (%s) does not match message"
- " sub ID (%s). MMS should NOT be sent.",
- current_data_sub_id,
- current_msg_sub_id)
- expected_result = False
-
- result = self._msim_message_test(ad_mo, ad_mt, mo_sub_id, mt_sub_id,
- msg=msg, expected_result=expected_result)
-
- if not result:
- log_messaging_screen_shot(ad_mo, test_name="%s_tx" % msg)
- log_messaging_screen_shot(ad_mt, test_name="%s_rx" % msg)
-
- return result
-
-
def _test_msim_voice_call_in_collision_with_mt_sms(
self,
mo_voice_slot,
@@ -456,21 +196,17 @@
_, mt_voice_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
set_voice_sub_id(ad_mt_voice, mt_voice_sub_id)
ad_mt_voice.log.info("Sub ID for incoming call at slot %s: %s",
- get_slot_index_from_subid(self.log, ad_mt_voice, mt_voice_sub_id),
+ get_slot_index_from_subid(ad_mt_voice, mt_voice_sub_id),
get_incoming_voice_sub_id(ad_mt_voice))
set_message_subid(
ad, get_subid_from_slot_index(self.log, ad, mt_sms_slot))
self.log.info("Step 1: Switch DDS.")
- if dds_slot:
- if not set_dds_on_slot_1(ads[0]):
- ads[0].log.warning("Failed to set DDS at eSIM.")
- return False
- else:
- if not set_dds_on_slot_0(ads[0]):
- ads[0].log.warning("Failed to set DDS at pSIM.")
- return False
+ if not set_dds_on_slot(ads[0], dds_slot):
+ ads[0].log.error(
+ "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
+ return False
self.log.info("Step 2: Check HTTP connection after DDS switch.")
if not verify_http_connection(self.log,
@@ -548,7 +284,7 @@
mo_voice_slot,
ad_mt_voice.serial,
get_slot_index_from_subid(
- self.log, ad_mt_voice, mt_voice_sub_id))
+ ad_mt_voice, mt_voice_sub_id))
extras = {"call_fail_reason": str(result.result_value)}
if not sms_result or not call_result:
@@ -661,865 +397,1153 @@
@test_tracker_info(uuid="4ae61fdf-2078-4e50-ae03-cb2e9299ce8d")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_volte_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["volte", "volte"], msg="SMS", direction="mo")
@test_tracker_info(uuid="0e8801f8-7203-45ba-aff3-cb667fd538e1")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_volte_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["volte", "volte"], msg="SMS", direction="mo")
@test_tracker_info(uuid="d54c2b4e-2e32-49f0-9536-879eb6f6577e")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_volte_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["volte", "volte"], msg="SMS", direction="mt")
@test_tracker_info(uuid="feed9119-df31-46f7-afd8-addf4052422a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_volte_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["volte", "volte"], msg="SMS", direction="mt")
@test_tracker_info(uuid="1da9965c-c863-4e6e-9374-a082fa16d6fd")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_volte_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["volte", "volte"], msg="SMS", direction="mo")
@test_tracker_info(uuid="64aec600-851f-4bde-b66c-130c69d1d5b6")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_volte_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["volte", "volte"], msg="SMS", direction="mo")
@test_tracker_info(uuid="9ce40c2c-3a59-4612-a0cc-4fcba887856c")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_volte_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["volte", "volte"], msg="SMS", direction="mt")
@test_tracker_info(uuid="4e46081d-733d-47d9-be4d-9e492de38bcd")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_volte_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["volte", "volte"], msg="SMS", direction="mt")
@test_tracker_info(uuid="5ede96ed-78b5-4cfb-94a3-44c34d610bef")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_volte_csfb_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["volte", "csfb"], msg="SMS", direction="mo")
@test_tracker_info(uuid="ae681d36-e450-4453-88a8-e9abf4bdf723")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_volte_csfb_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["volte", "csfb"], msg="SMS", direction="mo")
@test_tracker_info(uuid="6490abf9-7fc9-4168-ba20-7da0cb18d96e")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_volte_csfb_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["volte", "csfb"], msg="SMS", direction="mt")
@test_tracker_info(uuid="71590c9e-add0-4cbb-a530-07f58d26d954")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_volte_csfb_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["volte", "csfb"], msg="SMS", direction="mt")
@test_tracker_info(uuid="1b033914-8a26-48e0-829a-c85b5a93ce42")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_volte_csfb_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["volte", "csfb"], msg="SMS", direction="mo")
@test_tracker_info(uuid="15ebac40-5dc3-47ee-a787-ae6f9d71aff6")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_volte_csfb_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["volte", "csfb"], msg="SMS", direction="mo")
@test_tracker_info(uuid="b38390d2-b5ab-414b-9c61-2324395a56a6")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_volte_csfb_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["volte", "csfb"], msg="SMS", direction="mt")
@test_tracker_info(uuid="1c4a3a34-800a-4117-8c32-b6ec7d58a5cb")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_volte_csfb_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["volte", "csfb"], msg="SMS", direction="mt")
@test_tracker_info(uuid="c7645032-8006-448e-ae3e-86c9223482cf")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_csfb_volte_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["csfb", "volte"], msg="SMS", direction="mo")
@test_tracker_info(uuid="a4455da1-6314-4d2e-a6eb-c7e063a5fd10")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_csfb_volte_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["csfb", "volte"], msg="SMS", direction="mo")
@test_tracker_info(uuid="60828bcc-0111-4d97-ac01-b43ff9c33b11")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_csfb_volte_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["csfb", "volte"], msg="SMS", direction="mt")
@test_tracker_info(uuid="d0f04ab9-c1fe-41b1-8ffc-7bf7cbb408ea")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_csfb_volte_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["csfb", "volte"], msg="SMS", direction="mt")
@test_tracker_info(uuid="97ad2e6f-8b71-49d4-870c-2f4438351880")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_csfb_volte_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["csfb", "volte"], msg="SMS", direction="mo")
@test_tracker_info(uuid="8353bce2-a800-440c-9822-a922343d0ff5")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_csfb_volte_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["csfb", "volte"], msg="SMS", direction="mo")
@test_tracker_info(uuid="7659d23d-8cf4-4ace-8e53-b26fc2fca38c")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_csfb_volte_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["csfb", "volte"], msg="SMS", direction="mt")
@test_tracker_info(uuid="91577f12-4a0e-4743-82bc-1b7581a6940d")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_csfb_volte_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["csfb", "volte"], msg="SMS", direction="mt")
@test_tracker_info(uuid="a5f2c1b0-5ae7-4187-ad63-4782dc47f62b")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_volte_3g_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["volte", "3g"], msg="SMS", direction="mo")
@test_tracker_info(uuid="0c983462-5372-4aae-a484-53da4d2b9553")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_volte_3g_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["volte", "3g"], msg="SMS", direction="mo")
@test_tracker_info(uuid="8266aaac-9d67-42c3-9260-d80c377b1ef9")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_volte_3g_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["volte", "3g"], msg="SMS", direction="mt")
@test_tracker_info(uuid="d6ae749b-5e69-489e-8fda-fcb38aaa6cb0")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_volte_3g_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["volte", "3g"], msg="SMS", direction="mt")
@test_tracker_info(uuid="f4985e53-d530-491c-94cd-51ba22a34eff")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_volte_3g_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["volte", "3g"], msg="SMS", direction="mo")
@test_tracker_info(uuid="b4fc2379-6937-404a-a659-249c1ccf9dd0")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_volte_3g_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["volte", "3g"], msg="SMS", direction="mo")
@test_tracker_info(uuid="e1027a25-b19f-4fb7-bfb9-79919e380c25")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_volte_3g_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["volte", "3g"], msg="SMS", direction="mt")
@test_tracker_info(uuid="7cf99f83-0542-42c8-8e72-1653e381aa6c")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_volte_3g_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["volte", "3g"], msg="SMS", direction="mt")
@test_tracker_info(uuid="c1084606-a63b-41da-a0cb-2db972b6a8ce")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_3g_volte_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["3g", "volte"], msg="SMS", direction="mo")
@test_tracker_info(uuid="4806716c-047a-4a33-a317-97d3cce5d2ca")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_3g_volte_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["3g", "volte"], msg="SMS", direction="mo")
@test_tracker_info(uuid="2877ff0b-d567-4683-baa3-20e254ed025c")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_3g_volte_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["3g", "volte"], msg="SMS", direction="mt")
@test_tracker_info(uuid="6bf3ea1b-e75c-4844-a311-5a18b1b7a1b8")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_3g_volte_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["3g", "volte"], msg="SMS", direction="mt")
@test_tracker_info(uuid="fb7bf8b2-fa44-4e05-a0ab-16e7b1907e6b")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_3g_volte_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["3g", "volte"], msg="SMS", direction="mo")
@test_tracker_info(uuid="d9090125-61cb-4ef5-97de-06c2ec8529bd")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_3g_volte_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["3g", "volte"], msg="SMS", direction="mo")
@test_tracker_info(uuid="d764c5ea-a34a-4b29-ab50-63bd63ebe5c4")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_3g_volte_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["3g", "volte"], msg="SMS", direction="mt")
@test_tracker_info(uuid="fe7d2f8c-eeb6-4ae9-a57d-1636d3153d2b")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_3g_volte_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["3g", "volte"], msg="SMS", direction="mt")
@test_tracker_info(uuid="b9a5cb40-4986-4811-90e7-628d1729ccb2")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_csfb_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["csfb", "csfb"], msg="SMS", direction="mo")
@test_tracker_info(uuid="220665c1-4c63-4450-b8bb-17fc6df24498")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_csfb_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["csfb", "csfb"], msg="SMS", direction="mo")
@test_tracker_info(uuid="968217a6-320f-41f0-b401-7c377309d983")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_csfb_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["csfb", "csfb"], msg="SMS", direction="mt")
@test_tracker_info(uuid="c6a5bf63-af40-4619-a0eb-0d1835fde36c")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_csfb_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["csfb", "csfb"], msg="SMS", direction="mt")
@test_tracker_info(uuid="ea9f4e72-0dea-4f5f-b5ff-4a0bad0d29a0")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_csfb_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["csfb", "csfb"], msg="SMS", direction="mo")
@test_tracker_info(uuid="4eb935f0-2b11-4b2d-8faa-9a022e36813a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_csfb_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["csfb", "csfb"], msg="SMS", direction="mo")
@test_tracker_info(uuid="765e31fd-b412-43a8-a6a8-5d3ae66cab18")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_csfb_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["csfb", "csfb"], msg="SMS", direction="mt")
@test_tracker_info(uuid="bc6ada03-6a5e-4fe7-80c4-3aebc9fa426f")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_csfb_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["csfb", "csfb"], msg="SMS", direction="mt")
@test_tracker_info(uuid="a42994d0-bdb3-487e-98f2-665899d3edba")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_csfb_3g_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["csfb", "3g"], msg="SMS", direction="mo")
@test_tracker_info(uuid="d8ef0ac8-9cb1-4f32-8211-84dee563af00")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_csfb_3g_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["csfb", "3g"], msg="SMS", direction="mo")
@test_tracker_info(uuid="f4eb2254-5148-4cf9-b53f-56d8665de645")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_csfb_3g_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["csfb", "3g"], msg="SMS", direction="mt")
@test_tracker_info(uuid="fd546290-f7e7-47ff-b165-a9bb01e91c64")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_csfb_3g_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["csfb", "3g"], msg="SMS", direction="mt")
@test_tracker_info(uuid="d6994024-e845-48e2-9cd6-d72e97480a8a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_csfb_3g_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["csfb", "3g"], msg="SMS", direction="mo")
@test_tracker_info(uuid="c816165e-49d8-4d0a-8bb5-e64ad910a55a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_csfb_3g_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["csfb", "3g"], msg="SMS", direction="mo")
@test_tracker_info(uuid="647d546f-b325-4b91-be84-0bedf5a33210")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_csfb_3g_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["csfb", "3g"], msg="SMS", direction="mt")
@test_tracker_info(uuid="98b7e161-4953-4566-a96c-21545bf05e51")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_csfb_3g_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["csfb", "3g"], msg="SMS", direction="mt")
@test_tracker_info(uuid="9a3d1330-e70e-4ac0-a8bc-fec5710a8dcd")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_3g_csfb_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["3g", "csfb"], msg="SMS", direction="mo")
@test_tracker_info(uuid="51b4edd3-a867-409e-b367-2fd8cf0eb4a6")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_3g_csfb_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["3g", "csfb"], msg="SMS", direction="mo")
@test_tracker_info(uuid="dba9cb2b-84bd-47db-a5a6-826e54a1bbeb")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_3g_csfb_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["3g", "csfb"], msg="SMS", direction="mt")
@test_tracker_info(uuid="263494aa-f3c4-450e-b5bf-b9331d9c9dd8")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_3g_csfb_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["3g", "csfb"], msg="SMS", direction="mt")
@test_tracker_info(uuid="7ba231b8-edc9-4f64-ba7e-5f0360c4eed5")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_3g_csfb_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["3g", "csfb"], msg="SMS", direction="mo")
@test_tracker_info(uuid="ca1e9c35-07f2-4e32-8a59-61efc37f11a4")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_3g_csfb_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["3g", "csfb"], msg="SMS", direction="mo")
@test_tracker_info(uuid="f19252c0-8ff6-4267-adcd-f676407333e6")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_3g_csfb_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["3g", "csfb"], msg="SMS", direction="mt")
@test_tracker_info(uuid="34ef2001-d80d-4818-b458-1e8a9556e5cd")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_3g_csfb_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["3g", "csfb"], msg="SMS", direction="mt")
@test_tracker_info(uuid="947ceba7-9aeb-402c-ba36-4856bc4352eb")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_3g_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["3g", "3g"], msg="SMS", direction="mo")
@test_tracker_info(uuid="9f9677e1-1215-49ed-a671-22e7779659a9")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_3g_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["3g", "3g"], msg="SMS", direction="mo")
@test_tracker_info(uuid="f77112c8-85e8-4584-a0b7-bba11c23be7d")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_3g_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["3g", "3g"], msg="SMS", direction="mt")
@test_tracker_info(uuid="facc19fd-7846-488e-9cf1-755f81d0fee2")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_3g_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["3g", "3g"], msg="SMS", direction="mt")
@test_tracker_info(uuid="5a26f35e-c038-409e-8941-7e0b475ebda8")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_3g_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["3g", "3g"], msg="SMS", direction="mo")
@test_tracker_info(uuid="c303aa26-0fd0-44d7-b2fc-32782deaf5ea")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mo_3g_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["3g", "3g"], msg="SMS", direction="mo")
@test_tracker_info(uuid="45cbddd3-889d-46ab-8d7f-9dd971287155")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_3g_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["3g", "3g"], msg="SMS", direction="mt")
@test_tracker_info(uuid="7dacd6b2-9d21-4c4d-bec4-fdfe685cdce8")
@TelephonyBaseTest.tel_test_wrap
def test_msim_sms_mt_3g_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["3g", "3g"], msg="SMS", direction="mt")
@test_tracker_info(uuid="24268e9f-b047-4c67-92f9-22e0bd8b3a11")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_volte_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["volte", "volte"], msg="MMS", direction="mo")
@test_tracker_info(uuid="1d72b01d-5ca7-4899-ae57-ecbeff09bc39")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_volte_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["volte", "volte"], msg="MMS", direction="mo")
@test_tracker_info(uuid="ca2ad510-7f5e-49e4-861e-d433f86c2237")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_volte_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["volte", "volte"], msg="MMS", direction="mt")
@test_tracker_info(uuid="63a0480a-18dd-43e5-82e9-45e008346ea9")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_volte_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["volte", "volte"], msg="MMS", direction="mt")
@test_tracker_info(uuid="5e51f0d9-f1b6-4bfe-88ab-f28ebaa6ee55")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_volte_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["volte", "volte"], msg="MMS", direction="mo")
@test_tracker_info(uuid="fcc7e8aa-41a4-48a1-9586-d6080c77a79b")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_volte_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["volte", "volte"], msg="MMS", direction="mo")
@test_tracker_info(uuid="f633bf56-2d15-462b-994d-e9294d87ca23")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_volte_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["volte", "volte"], msg="MMS", direction="mt")
@test_tracker_info(uuid="3c336061-32cf-4e9a-bb1e-b54e3357e644")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_volte_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["volte", "volte"], msg="MMS", direction="mt")
@test_tracker_info(uuid="50ee8103-0196-4194-b982-9d07c68e57e4")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_volte_csfb_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["volte", "csfb"], msg="MMS", direction="mo")
@test_tracker_info(uuid="ec09405d-b12d-405c-9bfd-ba3eb20eb752")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_volte_csfb_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["volte", "csfb"], msg="MMS", direction="mo")
@test_tracker_info(uuid="26bea731-b653-4e9f-98d1-1b290b959bfc")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_volte_csfb_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["volte", "csfb"], msg="MMS", direction="mt")
@test_tracker_info(uuid="ecc010da-1798-4da3-b041-13e2b2547548")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_volte_csfb_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["volte", "csfb"], msg="MMS", direction="mt")
@test_tracker_info(uuid="cf4c5bd0-525a-497a-a0f8-17acd9dbeabd")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_volte_csfb_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["volte", "csfb"], msg="MMS", direction="mo")
@test_tracker_info(uuid="603f22db-913b-4ad3-b148-7c6d3624bc09")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_volte_csfb_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["volte", "csfb"], msg="MMS", direction="mo")
@test_tracker_info(uuid="561efaf1-7fe4-4196-991e-d03eee28fb4e")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_volte_csfb_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["volte", "csfb"], msg="MMS", direction="mt")
@test_tracker_info(uuid="6f383ef0-d99a-4a3d-b137-e24fa03306b9")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_volte_csfb_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["volte", "csfb"], msg="MMS", direction="mt")
@test_tracker_info(uuid="eeaa1262-c2a0-4f47-baa5-7435fa9e9315")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_csfb_volte_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["csfb", "volte"], msg="MMS", direction="mo")
@test_tracker_info(uuid="478f5497-cc21-4634-8b97-df70dbe286c0")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_csfb_volte_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["csfb", "volte"], msg="MMS", direction="mo")
@test_tracker_info(uuid="1c4af9c6-87d6-438c-aba7-70d8bb4b357e")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_csfb_volte_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["csfb", "volte"], msg="MMS", direction="mt")
@test_tracker_info(uuid="825daee3-db6c-404a-a454-cea98182bf5a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_csfb_volte_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["csfb", "volte"], msg="MMS", direction="mt")
@test_tracker_info(uuid="50fe9f3e-eae1-4a01-8655-02340f85037a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_csfb_volte_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["csfb", "volte"], msg="MMS", direction="mo")
@test_tracker_info(uuid="bae89139-f73f-4a06-bb65-a0bae385fae9")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_csfb_volte_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["csfb", "volte"], msg="MMS", direction="mo")
@test_tracker_info(uuid="42e897e3-4411-45a0-bf62-3ea6f59c2617")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_csfb_volte_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["csfb", "volte"], msg="MMS", direction="mt")
@test_tracker_info(uuid="9847b0c8-517e-42ea-9306-8a4a1cd46cd8")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_csfb_volte_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["csfb", "volte"], msg="MMS", direction="mt")
@test_tracker_info(uuid="5057f8e4-19e7-42c0-bc63-1678d8ce1504")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_volte_3g_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["volte", "3g"], msg="MMS", direction="mo")
@test_tracker_info(uuid="52bb44ae-0263-4415-8a61-337a8f990f8b")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_volte_3g_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["volte", "3g"], msg="MMS", direction="mo")
@test_tracker_info(uuid="deb00e73-b63a-4ed8-8b7f-953704b5d783")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_volte_3g_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["volte", "3g"], msg="MMS", direction="mt")
@test_tracker_info(uuid="e0aa9846-2c02-4ba1-aeef-08a673c497ae")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_volte_3g_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["volte", "3g"], msg="MMS", direction="mt")
@test_tracker_info(uuid="ef06ae23-6f52-4c3b-b228-5c95ed780cd2")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_volte_3g_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["volte", "3g"], msg="MMS", direction="mo")
@test_tracker_info(uuid="69a62cd6-290b-4e58-81ff-0b35ac82262c")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_volte_3g_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["volte", "3g"], msg="MMS", direction="mo")
@test_tracker_info(uuid="645cef41-ddf8-49b4-8a58-2da019883f32")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_volte_3g_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["volte", "3g"], msg="MMS", direction="mt")
@test_tracker_info(uuid="b0b8aac3-cc85-47d9-828a-8016138fe466")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_volte_3g_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["volte", "3g"], msg="MMS", direction="mt")
@test_tracker_info(uuid="1dcebefb-3338-4550-96fa-07b64493db1c")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_3g_volte_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["3g", "volte"], msg="MMS", direction="mo")
@test_tracker_info(uuid="3d06854e-5b86-46fb-9ca2-a217b026733d")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_3g_volte_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["3g", "volte"], msg="MMS", direction="mo")
@test_tracker_info(uuid="0c0f72bc-4076-411d-8a8d-fc6ae414a73a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_3g_volte_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["3g", "volte"], msg="MMS", direction="mt")
@test_tracker_info(uuid="b63211fa-baf0-4dff-bd18-d7f80e85e551")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_3g_volte_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["3g", "volte"], msg="MMS", direction="mt")
@test_tracker_info(uuid="80c2fe4d-e87a-45d7-9b83-23863e75cd94")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_3g_volte_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["3g", "volte"], msg="MMS", direction="mo")
@test_tracker_info(uuid="84be29a1-0b29-4785-baaa-6cf84c503fa6")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_3g_volte_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["3g", "volte"], msg="MMS", direction="mo")
@test_tracker_info(uuid="591d2948-2257-4a46-8ccb-5c628d85fc43")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_3g_volte_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["3g", "volte"], msg="MMS", direction="mt")
@test_tracker_info(uuid="67e4dae5-8ca5-475f-af0e-f91b89df68ed")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_3g_volte_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["3g", "volte"], msg="MMS", direction="mt")
@test_tracker_info(uuid="35d33d3e-f618-4ce1-8b40-3dac0ef2731a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_csfb_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["csfb", "csfb"], msg="MMS", direction="mo")
@test_tracker_info(uuid="179e49c7-7066-4285-9b5b-3ef639d8c5e4")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_csfb_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["csfb", "csfb"], msg="MMS", direction="mo")
@test_tracker_info(uuid="09d6954f-d760-47e5-8667-3ed317fdbfbc")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_csfb_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["csfb", "csfb"], msg="MMS", direction="mt")
@test_tracker_info(uuid="80f8c18f-2bd6-4310-be39-472d7a24e08a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_csfb_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["csfb", "csfb"], msg="MMS", direction="mt")
@test_tracker_info(uuid="b700d261-7616-4226-95cc-59ec54cc2678")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_csfb_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["csfb", "csfb"], msg="MMS", direction="mo")
@test_tracker_info(uuid="5cb2cc81-bf3e-4025-b85b-2bf1a4797e41")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_csfb_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["csfb", "csfb"], msg="MMS", direction="mo")
@test_tracker_info(uuid="1af2ac12-4d2d-4a36-8c46-8b3013eadab2")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_csfb_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["csfb", "csfb"], msg="MMS", direction="mt")
@test_tracker_info(uuid="66d8108e-8dd9-42e3-b2cd-49a538beecf6")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_csfb_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["csfb", "csfb"], msg="MMS", direction="mt")
@test_tracker_info(uuid="a35df875-72eb-43d7-874c-a7b3f0aea2a9")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_csfb_3g_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["csfb", "3g"], msg="MMS", direction="mo")
@test_tracker_info(uuid="cf718bda-75d6-4906-a33e-110610b01d4d")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_csfb_3g_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["csfb", "3g"], msg="MMS", direction="mo")
@test_tracker_info(uuid="342cbc1a-7151-425c-9bd6-81808a5eb7e6")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_csfb_3g_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["csfb", "3g"], msg="MMS", direction="mt")
@test_tracker_info(uuid="01e33aa4-27a9-48fd-b9e8-313980d06b0d")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_csfb_3g_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["csfb", "3g"], msg="MMS", direction="mt")
@test_tracker_info(uuid="fe527335-731e-49a5-a07e-f4999c536153")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_csfb_3g_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["csfb", "3g"], msg="MMS", direction="mo")
@test_tracker_info(uuid="1c56f866-3b3c-45c0-9c13-face44246aca")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_csfb_3g_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["csfb", "3g"], msg="MMS", direction="mo")
@test_tracker_info(uuid="4affd77a-afdc-4ac9-ba8a-a3599efe1e96")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_csfb_3g_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["csfb", "3g"], msg="MMS", direction="mt")
@test_tracker_info(uuid="8440c05e-28d9-45c7-b32e-127f240d12f0")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_csfb_3g_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["csfb", "3g"], msg="MMS", direction="mt")
@test_tracker_info(uuid="a53ebb84-945e-4068-a78a-fd78362e8073")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_3g_csfb_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["3g", "csfb"], msg="MMS", direction="mo")
@test_tracker_info(uuid="23bedcbc-7c09-430d-a162-04de75244fd8")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_3g_csfb_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["3g", "csfb"], msg="MMS", direction="mo")
@test_tracker_info(uuid="e1e1ef53-d91b-4b10-9bd6-e065ca48ab94")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_3g_csfb_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["3g", "csfb"], msg="MMS", direction="mt")
@test_tracker_info(uuid="e813ae3b-b875-43f6-a055-d2119cec9786")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_3g_csfb_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["3g", "csfb"], msg="MMS", direction="mt")
@test_tracker_info(uuid="d5863aab-a46a-4363-8bf8-5dcfc29a9055")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_3g_csfb_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["3g", "csfb"], msg="MMS", direction="mo")
@test_tracker_info(uuid="79a0bd58-0de0-471e-9e53-9cc655700428")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_3g_csfb_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["3g", "csfb"], msg="MMS", direction="mo")
@test_tracker_info(uuid="e9a340f4-22a7-4786-bb5b-370295324d5a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_3g_csfb_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["3g", "csfb"], msg="MMS", direction="mt")
@test_tracker_info(uuid="8a261b43-2532-4c47-ac0c-3a5dd0d51b69")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_3g_csfb_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["3g", "csfb"], msg="MMS", direction="mt")
@test_tracker_info(uuid="2efdf7da-d2ec-4580-a164-5f7b740f9ac6")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_3g_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 0, mo_rat=["3g", "3g"], msg="MMS", direction="mo")
@test_tracker_info(uuid="459e9b40-ad4e-4a89-ac89-f3c8ec472d3f")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_3g_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
0, None, 1, mo_rat=["3g", "3g"], msg="MMS", direction="mo")
@test_tracker_info(uuid="130a0e85-1653-4ddf-81b9-dadd26dde1e3")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_3g_psim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 0, mt_rat=["3g", "3g"], msg="MMS", direction="mt")
@test_tracker_info(uuid="e81f0b33-38b3-4a4d-9e05-fb44a689230b")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_3g_psim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 0, 1, mt_rat=["3g", "3g"], msg="MMS", direction="mt")
@test_tracker_info(uuid="61894370-93b5-4ab5-80c7-d50948d38471")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_3g_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 0, mo_rat=["3g", "3g"], msg="MMS", direction="mo")
@test_tracker_info(uuid="8d41ee9a-fed9-4472-ada7-007e56690c67")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mo_3g_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
1, None, 1, mo_rat=["3g", "3g"], msg="MMS", direction="mo")
@test_tracker_info(uuid="6aa41641-2619-48f6-8c5f-1c06260f0e28")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_3g_esim_dds_slot_0(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 0, mt_rat=["3g", "3g"], msg="MMS", direction="mt")
@test_tracker_info(uuid="94d8e05d-eb99-4a71-be00-e725cbd05cae")
@TelephonyBaseTest.tel_test_wrap
def test_msim_mms_mt_3g_esim_dds_slot_1(self):
- return self._test_msim_message(
+ return dsds_message_test(
+ self.log,
+ self.android_devices,
None, 1, 1, mt_rat=["3g", "3g"], msg="MMS", direction="mt")
@test_tracker_info(uuid="207a23b7-17f1-4e27-892d-6c276f463b07")
diff --git a/acts_tests/tests/google/tel/live/TelLiveGFTDSDSSupplementaryServiceTest.py b/acts_tests/tests/google/tel/live/TelLiveGFTDSDSSupplementaryServiceTest.py
index aae30c3..683d747 100644
--- a/acts_tests/tests/google/tel/live/TelLiveGFTDSDSSupplementaryServiceTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveGFTDSDSSupplementaryServiceTest.py
@@ -14,64 +14,26 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import re
-import time
-
-from acts import asserts
from acts import signals
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import \
- TelephonyVoiceTestResult
-from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import \
- TelephonyMetricLogger
+from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_defines import CALL_CAPABILITY_MANAGE_CONFERENCE
-from acts_contrib.test_utils.tel.tel_defines import CALL_PROPERTY_CONFERENCE
-from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_ACTIVE
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_CONFERENCE
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
-from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_incoming_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_outgoing_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_0
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_1
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_subid_on_same_network_of_host_ad
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls
-from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
+from acts_contrib.test_utils.tel.tel_dsds_utils import erase_call_forwarding
+from acts_contrib.test_utils.tel.tel_dsds_utils import msim_call_forwarding
+from acts_contrib.test_utils.tel.tel_dsds_utils import msim_call_voice_conf
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_ss_utils import set_call_waiting
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
from acts_contrib.test_utils.tel.tel_test_utils import get_capability_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.tel.tel_test_utils import set_call_waiting
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import \
- wait_and_reject_call_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import erase_call_forwarding_by_mmi
-from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
-from acts_contrib.test_utils.tel.tel_voice_utils import get_cep_conference_call_id
-from acts_contrib.test_utils.tel.tel_voice_utils import \
- three_phone_call_forwarding_short_seq
-from acts_contrib.test_utils.tel.tel_voice_utils import \
- three_phone_call_waiting_short_seq
-from acts_contrib.test_utils.tel.tel_voice_utils import swap_calls
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_on_rat
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_on_rat
-CallResult = TelephonyVoiceTestResult.CallResult.Value
class TelLiveGFTDSDSSupplementaryServiceTest(TelephonyBaseTest):
def setup_class(self):
TelephonyBaseTest.setup_class(self)
self.message_lengths = (50, 160, 180)
self.tel_logger = TelephonyMetricLogger.for_test_case()
- self.erase_call_forwarding(self.log, self.android_devices[0])
+ erase_call_forwarding(self.log, self.android_devices[0])
if not get_capability_for_subscription(
self.android_devices[0],
CAPABILITY_CONFERENCE,
@@ -83,842 +45,16 @@
def teardown_test(self):
ensure_phones_idle(self.log, self.android_devices)
- self.erase_call_forwarding(self.log, self.android_devices[0])
+ erase_call_forwarding(self.log, self.android_devices[0])
set_call_waiting(self.log, self.android_devices[0], enable=1)
- def _hangup_call(self, ad, device_description='Device'):
- if not hangup_call(self.log, ad):
- ad.log.error("Failed to hang up on %s", device_description)
- return False
- return True
-
- def erase_call_forwarding(self, log, ad):
- slot0_sub_id = get_subid_from_slot_index(log, ad, 0)
- slot1_sub_id = get_subid_from_slot_index(log, ad, 1)
- current_voice_sub_id = get_incoming_voice_sub_id(ad)
- for sub_id in (slot0_sub_id, slot1_sub_id):
- set_voice_sub_id(ad, sub_id)
- get_operator_name(log, ad, sub_id)
- erase_call_forwarding_by_mmi(log, ad)
- set_voice_sub_id(ad, current_voice_sub_id)
-
- def _three_phone_call_mo_add_mt(
- self,
- ads,
- phone_setups,
- verify_funcs,
- reject_once=False):
- """Use 3 phones to make MO call and MT call.
-
- Call from PhoneA to PhoneB, accept on PhoneB.
- Call from PhoneC to PhoneA, accept on PhoneA.
-
- Args:
- ads: list of ad object.
- The list should have three objects.
- phone_setups: list of phone setup functions.
- The list should have three objects.
- verify_funcs: list of phone call verify functions.
- The list should have three objects.
-
- Returns:
- If success, return 'call_AB' id in PhoneA.
- if fail, return None.
- """
-
- class _CallException(Exception):
- pass
-
- try:
- verify_func_a, verify_func_b, verify_func_c = verify_funcs
- tasks = []
- for ad, setup_func in zip(ads, phone_setups):
- if setup_func is not None:
- tasks.append((setup_func, (self.log, ad, get_incoming_voice_sub_id(ad))))
- if tasks != [] and not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- raise _CallException("Setup failed.")
- for ad in ads:
- ad.droid.telecomCallClearCallList()
- if num_active_calls(self.log, ad) != 0:
- ad.log.error("Phone Call List is not empty.")
- raise _CallException("Clear call list failed.")
-
- self.log.info("Step1: Call From PhoneA to PhoneB.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=verify_func_a,
- verify_callee_func=verify_func_b):
- raise _CallException("PhoneA call PhoneB failed.")
-
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
- if num_active_calls(self.log, ads[0]) != 1:
- raise _CallException("Call list verify failed.")
- call_ab_id = calls[0]
-
- self.log.info("Step2: Call From PhoneC to PhoneA.")
- if reject_once:
- self.log.info("Step2-1: Reject incoming call once.")
- if not initiate_call(
- self.log,
- ads[2],
- ads[0].telephony['subscription'][get_incoming_voice_sub_id(
- ads[0])]['phone_num']):
- ads[2].log.error("Initiate call failed.")
- raise _CallException("Failed to initiate call.")
-
- if not wait_and_reject_call_for_subscription(
- self.log,
- ads[0],
- get_incoming_voice_sub_id(ads[0]),
- incoming_number= \
- ads[2].telephony['subscription'][
- get_incoming_voice_sub_id(
- ads[2])]['phone_num']):
- ads[0].log.error("Reject call fail.")
- raise _CallException("Failed to reject call.")
-
- self._hangup_call(ads[2], "PhoneC")
- time.sleep(15)
-
- if not call_setup_teardown(
- self.log,
- ads[2],
- ads[0],
- ad_hangup=None,
- verify_caller_func=verify_func_c,
- verify_callee_func=verify_func_a):
- raise _CallException("PhoneA call PhoneC failed.")
- if not verify_incall_state(self.log, [ads[0], ads[1], ads[2]],
- True):
- raise _CallException("Not All phones are in-call.")
-
- except Exception as e:
- self.log.error(e)
- setattr(ads[0], "exception", e)
- return None
-
- return call_ab_id
-
- def _test_ims_conference_merge_drop_second_call_from_participant(
- self, call_ab_id, call_ac_id):
- """Test conference merge and drop in IMS (VoLTE or WiFi Calling) call.
- (supporting both cases of CEP enabled and disabled).
-
- PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneB.
- PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneC.
- Merge calls to conference on PhoneA.
- Hangup on PhoneC, check call continues between AB.
- Hangup on PhoneB, check A ends.
-
- Args:
- call_ab_id: call id for call_AB on PhoneA.
- call_ac_id: call id for call_AC on PhoneA.
-
- Returns:
- True if succeed;
- False if failed.
- """
- ads = self.android_devices
-
- call_conf_id = self._merge_ims_conference_call(call_ab_id, call_ac_id)
- if call_conf_id is None:
- return False
-
- self.log.info("Step5: End call on PhoneC and verify call continues.")
- if not self._hangup_call(ads[2], "PhoneC"):
- return False
- time.sleep(WAIT_TIME_IN_CALL)
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
- if not verify_incall_state(self.log, [ads[0], ads[1]], True):
- return False
- if not verify_incall_state(self.log, [ads[2]], False):
- return False
-
- self.log.info("Step6: End call on PhoneB and verify PhoneA end.")
- if not self._hangup_call(ads[1], "PhoneB"):
- return False
- time.sleep(WAIT_TIME_IN_CALL)
- if not verify_incall_state(self.log, [ads[0], ads[1], ads[2]], False):
- return False
- return True
-
- def _merge_ims_conference_call(self, call_ab_id, call_ac_id):
- """Merge IMS conference call for both cases of CEP enabled and disabled.
-
- PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneB.
- PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneC.
- Merge calls to conference on PhoneA.
-
- Args:
- call_ab_id: call id for call_AB on PhoneA.
- call_ac_id: call id for call_AC on PhoneA.
-
- Returns:
- call_id for conference
- """
- ads = self.android_devices
- self.log.info("Step4: Merge to Conf Call and verify Conf Call.")
- ads[0].droid.telecomCallJoinCallsInConf(call_ab_id, call_ac_id)
- time.sleep(WAIT_TIME_IN_CALL)
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
-
- call_conf_id = None
- if num_active_calls(self.log, ads[0]) != 1:
- ads[0].log.info("Total number of call ids is not 1.")
- call_conf_id = get_cep_conference_call_id(ads[0])
- if call_conf_id is not None:
- self.log.info("New conference call id is found. CEP enabled.")
- calls.remove(call_conf_id)
- if (set(ads[0].droid.telecomCallGetCallChildren(
- call_conf_id)) != set(calls)):
- ads[0].log.error(
- "Children list %s for conference call is not correct.",
- ads[0].droid.telecomCallGetCallChildren(call_conf_id))
- return None
-
- if (CALL_PROPERTY_CONFERENCE not in ads[0]
- .droid.telecomCallGetProperties(call_conf_id)):
- ads[0].log.error(
- "Conf call id % properties wrong: %s", call_conf_id,
- ads[0].droid.telecomCallGetProperties(call_conf_id))
- return None
-
- if (CALL_CAPABILITY_MANAGE_CONFERENCE not in ads[0]
- .droid.telecomCallGetCapabilities(call_conf_id)):
- ads[0].log.error(
- "Conf call id %s capabilities wrong: %s", call_conf_id,
- ads[0].droid.telecomCallGetCapabilities(call_conf_id))
- return None
-
- if (call_ab_id in calls) or (call_ac_id in calls):
- self.log.error("Previous call ids should not in new call"
- " list after merge.")
- return None
- else:
- for call_id in calls:
- if call_id != call_ab_id and call_id != call_ac_id:
- call_conf_id = call_id
- self.log.info("CEP not enabled.")
-
- if not call_conf_id:
- self.log.error("Merge call fail, no new conference call id.")
- raise signals.TestFailure(
- "Calls were not merged. Failed to merge calls.",
- extras={"fail_reason": "Calls were not merged."
- " Failed to merge calls."})
- if not verify_incall_state(self.log, [ads[0], ads[1], ads[2]], True):
- return False
-
- if ads[0].droid.telecomCallGetCallState(
- call_conf_id) != CALL_STATE_ACTIVE:
- ads[0].log.error(
- "Call_ID: %s, state: %s, expected: STATE_ACTIVE", call_conf_id,
- ads[0].droid.telecomCallGetCallState(call_conf_id))
- return None
-
- return call_conf_id
-
- def _test_wcdma_conference_merge_drop(self, call_ab_id, call_ac_id):
- """Test conference merge and drop in WCDMA/CSFB_WCDMA call.
-
- PhoneA in WCDMA (or CSFB_WCDMA) call with PhoneB.
- PhoneA in WCDMA (or CSFB_WCDMA) call with PhoneC.
- Merge calls to conference on PhoneA.
- Hangup on PhoneC, check call continues between AB.
- Hangup on PhoneB, check A ends.
-
- Args:
- call_ab_id: call id for call_AB on PhoneA.
- call_ac_id: call id for call_AC on PhoneA.
-
- Returns:
- True if succeed;
- False if failed.
- """
- ads = self.android_devices
-
- self.log.info("Step4: Merge to Conf Call and verify Conf Call.")
- ads[0].droid.telecomCallJoinCallsInConf(call_ab_id, call_ac_id)
- time.sleep(WAIT_TIME_IN_CALL)
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
- num_calls = num_active_calls(self.log, ads[0])
- if num_calls != 3:
- ads[0].log.error("Total number of call ids is not 3.")
- if num_calls == 2:
- if call_ab_id in calls and call_ac_id in calls:
- ads[0].log.error("Calls were not merged."
- " Failed to merge calls.")
- raise signals.TestFailure(
- "Calls were not merged. Failed to merge calls.",
- extras={"fail_reason": "Calls were not merged."
- " Failed to merge calls."})
- return False
- call_conf_id = None
- for call_id in calls:
- if call_id != call_ab_id and call_id != call_ac_id:
- call_conf_id = call_id
- if not call_conf_id:
- self.log.error("Merge call fail, no new conference call id.")
- return False
- if not verify_incall_state(self.log, [ads[0], ads[1], ads[2]], True):
- return False
-
- if ads[0].droid.telecomCallGetCallState(
- call_conf_id) != CALL_STATE_ACTIVE:
- ads[0].log.error(
- "Call_id: %s, state: %s, expected: STATE_ACTIVE", call_conf_id,
- ads[0].droid.telecomCallGetCallState(call_conf_id))
- return False
-
- self.log.info("Step5: End call on PhoneC and verify call continues.")
- if not self._hangup_call(ads[2], "PhoneC"):
- return False
- time.sleep(WAIT_TIME_IN_CALL)
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
- if num_active_calls(self.log, ads[0]) != 1:
- return False
- if not verify_incall_state(self.log, [ads[0], ads[1]], True):
- return False
- if not verify_incall_state(self.log, [ads[2]], False):
- return False
-
- self.log.info("Step6: End call on PhoneB and verify PhoneA end.")
- if not self._hangup_call(ads[1], "PhoneB"):
- return False
- time.sleep(WAIT_TIME_IN_CALL)
- if not verify_incall_state(self.log, [ads[0], ads[1], ads[2]], False):
- return False
- return True
-
- def _test_msim_call_forwarding(
- self,
- caller_slot,
- callee_slot,
- forwarded_callee_slot,
- dds_slot,
- caller_rat=["", ""],
- callee_rat=["", ""],
- forwarded_callee_rat=["", ""],
- call_forwarding_type="unconditional"):
- """Make MO voice call to the primary device at specific slot in specific
- RAT with DDS at specific slot, and then forwarded to 3rd device with
- specific call forwarding type.
-
- Test step:
- 1. Get sub IDs of specific slots of both MO and MT devices.
- 2. Switch DDS to specific slot.
- 3. Check HTTP connection after DDS switch.
- 4. Set up phones in desired RAT.
- 5. Register and enable call forwarding with specifc type.
- 5. Make voice call to the primary device and wait for being forwarded
- to 3rd device.
-
- Args:
- caller_slot: Slot of 2nd device making MO call (0 or 1)
- callee_slot: Slot of primary device receiving and forwarding MT call
- (0 or 1)
- forwarded_callee_slot: Slot of 3rd device receiving forwarded call.
- dds_slot: Preferred data slot
- caller_rat: RAT for both slots of the 2nd device
- callee_rat: RAT for both slots of the primary device
- forwarded_callee_rat: RAT for both slots of the 3rd device
- call_forwarding_type:
- "unconditional"
- "busy"
- "not_answered"
- "not_reachable"
-
- Returns:
- True or False
- """
- ads = self.android_devices
-
- ad_caller = ads[1]
- ad_callee = ads[0]
- ad_forwarded_callee = ads[2]
-
- if callee_slot is not None:
- callee_sub_id = get_subid_from_slot_index(
- self.log, ad_callee, callee_slot)
- if callee_sub_id == INVALID_SUB_ID:
- ad_callee.log.warning(
- "Failed to get sub ID at slot %s.", callee_slot)
- return False
- callee_other_sub_id = get_subid_from_slot_index(
- self.log, ad_callee, 1-callee_slot)
- set_voice_sub_id(ad_callee, callee_sub_id)
- else:
- callee_sub_id, _, _ = get_subid_on_same_network_of_host_ad(ads)
- if callee_sub_id == INVALID_SUB_ID:
- ad_callee.log.warning(
- "Failed to get sub ID at slot %s.", callee_slot)
- return False
- callee_slot = "auto"
- set_voice_sub_id(ad_callee, callee_sub_id)
- ad_callee.log.info(
- "Sub ID for incoming call at slot %s: %s",
- callee_slot, get_incoming_voice_sub_id(ad_callee))
-
- if caller_slot is not None:
- caller_sub_id = get_subid_from_slot_index(
- self.log, ad_caller, caller_slot)
- if caller_sub_id == INVALID_SUB_ID:
- ad_caller.log.warning(
- "Failed to get sub ID at slot %s.", caller_slot)
- return False
- caller_other_sub_id = get_subid_from_slot_index(
- self.log, ad_caller, 1-caller_slot)
- set_voice_sub_id(ad_caller, caller_sub_id)
- else:
- _, caller_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
- if caller_sub_id == INVALID_SUB_ID:
- ad_caller.log.warning(
- "Failed to get sub ID at slot %s.", caller_slot)
- return False
- caller_slot = "auto"
- set_voice_sub_id(ad_caller, caller_sub_id)
- ad_caller.log.info(
- "Sub ID for outgoing call at slot %s: %s",
- caller_slot, get_outgoing_voice_sub_id(ad_caller))
-
- if forwarded_callee_slot is not None:
- forwarded_callee_sub_id = get_subid_from_slot_index(
- self.log, ad_forwarded_callee, forwarded_callee_slot)
- if forwarded_callee_sub_id == INVALID_SUB_ID:
- ad_forwarded_callee.log.warning(
- "Failed to get sub ID at slot %s.", forwarded_callee_slot)
- return False
- forwarded_callee_other_sub_id = get_subid_from_slot_index(
- self.log, ad_forwarded_callee, 1-forwarded_callee_slot)
- set_voice_sub_id(
- ad_forwarded_callee, forwarded_callee_sub_id)
- else:
- _, _, forwarded_callee_sub_id = \
- get_subid_on_same_network_of_host_ad(ads)
- if forwarded_callee_sub_id == INVALID_SUB_ID:
- ad_forwarded_callee.log.warning(
- "Failed to get sub ID at slot %s.", forwarded_callee_slot)
- return False
- forwarded_callee_slot = "auto"
- set_voice_sub_id(
- ad_forwarded_callee, forwarded_callee_sub_id)
- ad_forwarded_callee.log.info(
- "Sub ID for incoming call at slot %s: %s",
- forwarded_callee_slot,
- get_incoming_voice_sub_id(ad_forwarded_callee))
-
- self.log.info("Step 1: Switch DDS.")
- if dds_slot:
- if not set_dds_on_slot_1(ads[0]):
- self.log.warning(
- "Failed to set DDS at eSIM on %s", ads[0].serial)
- return False
- else:
- if not set_dds_on_slot_0(ads[0]):
- self.log.warning(
- "Failed to set DDS at pSIM on %s", ads[0].serial)
- return False
-
- self.log.info("Step 2: Check HTTP connection after DDS switch.")
- if not verify_http_connection(self.log,
- ads[0],
- url="https://www.google.com",
- retry=5,
- retry_interval=15,
- expected_state=True):
-
- self.log.error("Failed to verify http connection.")
- return False
- else:
- self.log.info("Verify http connection successfully.")
-
- if caller_slot == 1:
- phone_setup_on_rat(
- self.log,
- ad_caller,
- caller_rat[0],
- caller_other_sub_id)
-
- elif caller_slot == 0:
- phone_setup_on_rat(
- self.log,
- ad_caller,
- caller_rat[1],
- caller_other_sub_id)
- else:
- phone_setup_on_rat(
- self.log,
- ad_caller,
- 'general')
-
- if callee_slot == 1:
- phone_setup_on_rat(
- self.log,
- ad_callee,
- callee_rat[0],
- callee_other_sub_id)
-
- elif callee_slot == 0:
- phone_setup_on_rat(
- self.log,
- ad_callee,
- callee_rat[1],
- callee_other_sub_id)
- else:
- phone_setup_on_rat(
- self.log,
- ad_callee,
- 'general')
-
- if forwarded_callee_slot == 1:
- phone_setup_on_rat(
- self.log,
- ad_forwarded_callee,
- forwarded_callee_rat[0],
- forwarded_callee_other_sub_id)
-
- elif forwarded_callee_slot == 0:
- phone_setup_on_rat(
- self.log,
- ad_forwarded_callee,
- forwarded_callee_rat[1],
- forwarded_callee_other_sub_id)
- else:
- phone_setup_on_rat(
- self.log,
- ad_forwarded_callee,
- 'general')
-
- if caller_slot == 0 or caller_slot == 1:
- caller_phone_setup_func = phone_setup_on_rat(
- self.log, ad_caller, caller_rat[caller_slot], only_return_fn=True)
- else:
- caller_phone_setup_func = phone_setup_on_rat(
- self.log, ad_caller, 'general', only_return_fn=True)
-
- callee_phone_setup_func = phone_setup_on_rat(
- self.log, ad_callee, callee_rat[callee_slot], only_return_fn=True)
-
- if forwarded_callee_slot == 0 or forwarded_callee_slot == 1:
- forwarded_callee_phone_setup_func = phone_setup_on_rat(
- self.log,
- ad_forwarded_callee,
- forwarded_callee_rat[forwarded_callee_slot],
- only_return_fn=True)
- else:
- forwarded_callee_phone_setup_func = phone_setup_on_rat(
- self.log,
- ad_forwarded_callee,
- 'general',
- only_return_fn=True)
-
- self.log.info("Step 3: Set up phones in desired RAT.")
- tasks = [(caller_phone_setup_func, (self.log, ad_caller, caller_sub_id)),
- (callee_phone_setup_func, (self.log, ad_callee, callee_sub_id)),
- (forwarded_callee_phone_setup_func,
- (self.log, ad_forwarded_callee, forwarded_callee_sub_id))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- self.tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
- raise signals.TestFailure("Failed",
- extras={"fail_reason": "Phone Failed to Set Up Properly."})
-
- is_callee_in_call = is_phone_in_call_on_rat(
- self.log, ad_callee, callee_rat[callee_slot], only_return_fn=True)
-
- is_call_waiting = re.search(
- "call_waiting (True (\d)|False)", call_forwarding_type, re.I)
- if is_call_waiting:
- if is_call_waiting.group(1) == "False":
- call_waiting = False
- scenario = None
- else:
- call_waiting = True
- scenario = int(is_call_waiting.group(2))
-
- self.log.info(
- "Step 4: Make voice call with call waiting enabled = %s.",
- call_waiting)
- result = three_phone_call_waiting_short_seq(
- self.log,
- ads[0],
- None,
- is_callee_in_call,
- ads[1],
- ads[2],
- call_waiting=call_waiting, scenario=scenario)
- else:
- self.log.info(
- "Step 4: Make voice call with call forwarding %s.",
- call_forwarding_type)
- result = three_phone_call_forwarding_short_seq(
- self.log,
- ads[0],
- None,
- is_callee_in_call,
- ads[1],
- ads[2],
- call_forwarding_type=call_forwarding_type)
-
- if not result:
- if is_call_waiting:
- pass
- else:
- self.log.error(
- "Failed to make MO call from %s slot %s to %s slot %s"
- " and forward to %s slot %s",
- ad_caller.serial,
- caller_slot,
- ad_callee.serial,
- callee_slot,
- ad_forwarded_callee.serial,
- forwarded_callee_slot)
-
- return result
-
- def _test_msim_call_voice_conf(
- self,
- host_slot,
- p1_slot,
- p2_slot,
- dds_slot,
- host_rat=["volte", "volte"],
- p1_rat="",
- p2_rat="",
- merge=True,
- disable_cw=False):
- """Make a voice conference call at specific slot in specific RAT with
- DDS at specific slot.
-
- Test step:
- 1. Get sub IDs of specific slots of both MO and MT devices.
- 2. Switch DDS to specific slot.
- 3. Check HTTP connection after DDS switch.
- 4. Set up phones in desired RAT and make 3-way voice call.
- 5. Swap calls.
- 6. Merge calls.
-
- Args:
- host_slot: Slot on the primary device to host the comference call.
- 0 or 1 (0 for pSIM or 1 for eSIM)
- p1_slot: Slot on the participant device for the call
- p2_slot: Slot on another participant device for the call
- dds_slot: Preferred data slot
- host_rat: RAT for both slots of the primary device
- p1_rat: RAT for both slots of the participant device
- p2_rat: RAT for both slots of another participant device
- merge: True for merging 2 calls into the conference call. False for
- not merging 2 separated call.
- disable_cw: True for disabling call waiting and False on the
- contrary.
-
- Returns:
- True of False
- """
- ads = self.android_devices
- ad_host = ads[0]
- ad_p1 = ads[1]
- ad_p2 = ads[2]
-
- if host_slot is not None:
- host_sub_id = get_subid_from_slot_index(
- self.log, ad_host, host_slot)
- if host_sub_id == INVALID_SUB_ID:
- ad_host.log.warning("Failed to get sub ID at slot.", host_slot)
- return False
- host_other_sub_id = get_subid_from_slot_index(
- self.log, ad_host, 1-host_slot)
- set_voice_sub_id(ad_host, host_sub_id)
- else:
- host_sub_id, _, _ = get_subid_on_same_network_of_host_ad(ads)
- if host_sub_id == INVALID_SUB_ID:
- ad_host.log.warning("Failed to get sub ID at slot.", host_slot)
- return False
- host_slot = "auto"
- set_voice_sub_id(ad_host, host_sub_id)
-
- ad_host.log.info("Sub ID for outgoing call at slot %s: %s",
- host_slot, get_outgoing_voice_sub_id(ad_host))
-
- if p1_slot is not None:
- p1_sub_id = get_subid_from_slot_index(self.log, ad_p1, p1_slot)
- if p1_sub_id == INVALID_SUB_ID:
- ad_p1.log.warning("Failed to get sub ID at slot %s.", p1_slot)
- return False
- set_voice_sub_id(ad_p1, p1_sub_id)
- else:
- _, p1_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
- if p1_sub_id == INVALID_SUB_ID:
- ad_p1.log.warning("Failed to get sub ID at slot %s.", p1_slot)
- return False
- p1_slot = "auto"
- set_voice_sub_id(ad_p1, p1_sub_id)
- ad_p1.log.info("Sub ID for incoming call at slot %s: %s",
- p1_slot, get_incoming_voice_sub_id(ad_p1))
-
- if p2_slot is not None:
- p2_sub_id = get_subid_from_slot_index(self.log, ad_p2, p2_slot)
- if p2_sub_id == INVALID_SUB_ID:
- ad_p2.log.warning("Failed to get sub ID at slot %s.", p2_slot)
- return False
- set_voice_sub_id(ad_p2, p2_sub_id)
- else:
- _, _, p2_sub_id = get_subid_on_same_network_of_host_ad(ads)
- if p2_sub_id == INVALID_SUB_ID:
- ad_p2.log.warning("Failed to get sub ID at slot %s.", p2_slot)
- return False
- p2_slot = "auto"
- set_voice_sub_id(ad_p2, p2_sub_id)
- ad_p2.log.info("Sub ID for incoming call at slot %s: %s",
- p2_slot, get_incoming_voice_sub_id(ad_p2))
-
- self.log.info("Step 1: Switch DDS.")
- if dds_slot:
- if not set_dds_on_slot_1(ads[0]):
- self.log.warning(
- "Failed to set DDS at eSIM on %s", ads[0].serial)
- return False
- else:
- if not set_dds_on_slot_0(ads[0]):
- self.log.warning(
- "Failed to set DDS at pSIM on %s", ads[0].serial)
- return False
-
- self.log.info("Step 2: Check HTTP connection after DDS switch.")
- if not verify_http_connection(self.log,
- ads[0],
- url="https://www.google.com",
- retry=5,
- retry_interval=15,
- expected_state=True):
-
- self.log.error("Failed to verify http connection.")
- return False
- else:
- self.log.info("Verify http connection successfully.")
-
- if disable_cw:
- if not set_call_waiting(self.log, ad_host, enable=0):
- return False
- else:
- if not set_call_waiting(self.log, ad_host, enable=1):
- return False
-
- if host_slot == 1:
- phone_setup_on_rat(
- self.log,
- ad_host,
- host_rat[0],
- host_other_sub_id)
-
- elif host_slot == 0:
- phone_setup_on_rat(
- self.log,
- ad_host,
- host_rat[1],
- host_other_sub_id)
-
- host_phone_setup_func = phone_setup_on_rat(
- self.log, ad_host, host_rat[host_slot], only_return_fn=True)
-
- is_host_in_call = is_phone_in_call_on_rat(
- self.log, ad_host, host_rat[host_slot], only_return_fn=True)
-
- if p1_rat:
- p1_phone_setup_func = phone_setup_on_rat(
- self.log, ad_p1, p1_rat, only_return_fn=True)
- is_p1_in_call = is_phone_in_call_on_rat(
- self.log, ad_p1, p1_rat, only_return_fn=True)
- else:
- p1_phone_setup_func = phone_setup_on_rat(
- self.log, ad_p1, 'general', only_return_fn=True)
- is_p1_in_call = is_phone_in_call_on_rat(
- self.log, ad_p1, 'general', only_return_fn=True)
-
- if p2_rat:
- p2_phone_setup_func = phone_setup_on_rat(
- self.log, ad_p2, p2_rat, only_return_fn=True)
- is_p2_in_call = is_phone_in_call_on_rat(
- self.log, ad_p2, p2_rat, only_return_fn=True)
- else:
- p2_phone_setup_func = phone_setup_on_rat(
- self.log, ad_p2, 'general', only_return_fn=True)
- is_p2_in_call = is_phone_in_call_on_rat(
- self.log, ad_p2, 'general', only_return_fn=True)
-
- self.log.info("Step 3: Set up phone in desired RAT and make 3-way"
- " voice call.")
- call_ab_id = self._three_phone_call_mo_add_mt(
- [ad_host, ad_p1, ad_p2],
- [host_phone_setup_func, p1_phone_setup_func, p2_phone_setup_func], [
- is_host_in_call, is_p1_in_call,
- is_p2_in_call
- ])
-
- if call_ab_id is None:
- if disable_cw:
- set_call_waiting(self.log, ad_host, enable=1)
- if str(getattr(ad_host, "exception", None)) == \
- "PhoneA call PhoneC failed.":
- ads[0].log.info("PhoneA failed to call PhoneC due to call"
- " waiting being disabled.")
- delattr(ad_host, "exception")
- return True
- self.log.error("Failed to get call_ab_id")
- return False
- else:
- if disable_cw:
- return False
-
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
- if num_active_calls(self.log, ads[0]) != 2:
- return False
- if calls[0] == call_ab_id:
- call_ac_id = calls[1]
- else:
- call_ac_id = calls[0]
-
- if call_ac_id is None:
- self.log.error("Failed to get call_ac_id")
- return False
-
- num_swaps = 2
- self.log.info("Step 4: Begin Swap x%s test.", num_swaps)
- if not swap_calls(self.log, ads, call_ab_id, call_ac_id,
- num_swaps):
- self.log.error("Swap test failed.")
- return False
-
- if not merge:
- result = True
- if not self._hangup_call(ads[1], "PhoneB"):
- result = False
- if not self._hangup_call(ads[2], "PhoneC"):
- result = False
- return result
- else:
- self.log.info("Step 5: Merge calls.")
- if host_rat[host_slot] == "volte":
- return self._test_ims_conference_merge_drop_second_call_from_participant(
- call_ab_id, call_ac_id)
- else:
- return self._test_wcdma_conference_merge_drop(
- call_ab_id, call_ac_id)
-
@test_tracker_info(uuid="ccaeff83-4b8c-488a-8c7f-6bb019528bf8")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_volte_psim_dds_slot_0(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
0,
None,
@@ -929,7 +65,10 @@
@test_tracker_info(uuid="a132bfa6-d545-4970-9a39-55aea7477f8c")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_volte_psim_dds_slot_1(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
0,
None,
@@ -940,7 +79,10 @@
@test_tracker_info(uuid="71a4db8a-d20f-4fcb-ac5f-5fe6b9fa36f5")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_volte_esim_dds_slot_0(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
1,
None,
@@ -951,7 +93,10 @@
@test_tracker_info(uuid="50b064e7-4bf6-4bb3-aed1-e4d78b0b6195")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_volte_esim_dds_slot_1(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
1,
None,
@@ -964,7 +109,10 @@
@test_tracker_info(uuid="b1cfe07f-f4bf-49c4-95f1-f0973f32940e")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_volte_csfb_psim_dds_slot_0(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
0,
None,
@@ -975,7 +123,10 @@
@test_tracker_info(uuid="668bd2c6-beee-4c38-a9e5-8b0cc5937c28")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_volte_csfb_psim_dds_slot_1(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
0,
None,
@@ -986,7 +137,10 @@
@test_tracker_info(uuid="d69e86f3-f279-4cc8-8c1f-8a9dce0acfdf")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_volte_csfb_esim_dds_slot_0(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
1,
None,
@@ -997,7 +151,10 @@
@test_tracker_info(uuid="6156c374-7b07-473b-84f7-45de633f9681")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_volte_csfb_esim_dds_slot_1(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
1,
None,
@@ -1005,12 +162,13 @@
callee_rat=["volte", "csfb"],
call_forwarding_type="unconditional")
-
-
@test_tracker_info(uuid="29e36a21-9c94-418b-8628-e601e56fb168")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_csfb_volte_psim_dds_slot_0(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
0,
None,
@@ -1021,7 +179,10 @@
@test_tracker_info(uuid="36ebf549-e64e-4093-bebf-c9ca56289477")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_csfb_volte_psim_dds_slot_1(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
0,
None,
@@ -1032,7 +193,10 @@
@test_tracker_info(uuid="cfb973d7-aa3b-4e59-9f00-501e42c99947")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_csfb_volte_esim_dds_slot_0(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
1,
None,
@@ -1043,7 +207,10 @@
@test_tracker_info(uuid="a347c3db-e128-4deb-9009-c8b8e8145f67")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_csfb_volte_esim_dds_slot_1(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
1,
None,
@@ -1056,7 +223,10 @@
@test_tracker_info(uuid="7040e929-eb1d-4dc6-a404-2c185dc8a0a0")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_csfb_psim_dds_slot_0(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
0,
None,
@@ -1067,7 +237,10 @@
@test_tracker_info(uuid="b88a2ce3-74c7-41df-8114-71b6c3d0b050")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_csfb_psim_dds_slot_1(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
0,
None,
@@ -1078,7 +251,10 @@
@test_tracker_info(uuid="0ffd2391-ec5a-4a48-b0a8-fceba0c922d3")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_csfb_esim_dds_slot_0(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
1,
None,
@@ -1089,7 +265,10 @@
@test_tracker_info(uuid="44937439-2d0a-4aea-bb4d-263e5ed634b4")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_csfb_esim_dds_slot_1(self):
- return self._test_msim_call_forwarding(
+ return msim_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
None,
1,
None,
@@ -1097,117 +276,158 @@
callee_rat=["csfb", "csfb"],
call_forwarding_type="unconditional")
-
-
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="73ac948b-5260-44f1-a0a6-e4a410cb3283")
def test_msim_voice_conf_call_host_volte_psim_dds_slot_0(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0, None, None, 0, host_rat=["volte", "volte"])
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="75d7fb2c-aa62-4b4f-9e70-8f6b1647f816")
def test_msim_voice_conf_call_host_volte_psim_dds_slot_1(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0, None, None, 1, host_rat=["volte", "volte"])
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="2343369e-0240-4adc-bc01-7c08f9327737")
def test_msim_voice_conf_call_host_volte_esim_dds_slot_0(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1, None, None, 0, host_rat=["volte", "volte"])
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="3a28e621-1d47-432c-a7e8-20d2d9f82588")
def test_msim_voice_conf_call_host_volte_esim_dds_slot_1(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1, None, None, 1, host_rat=["volte", "volte"])
-
-
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="378f24cf-bb96-45e1-8150-02f08d7417b6")
def test_msim_voice_conf_call_host_volte_csfb_psim_dds_slot_0(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0, None, None, 0, host_rat=["volte", "csfb"])
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="e3fdf5ec-eafe-4825-acd3-5d4ff03df1d2")
def test_msim_voice_conf_call_host_volte_csfb_psim_dds_slot_1(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0, None, None, 1, host_rat=["volte", "csfb"])
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="221da988-e8c7-43e5-ae3a-414e8f01e872")
def test_msim_voice_conf_call_host_volte_csfb_esim_dds_slot_0(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1, None, None, 0, host_rat=["volte", "csfb"])
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="ea5f0254-59b8-4f63-8a4a-6f0ecb55ddbf")
def test_msim_voice_conf_call_host_volte_csfb_esim_dds_slot_1(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1, None, None, 1, host_rat=["volte", "csfb"])
-
-
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="90abbc8a-d492-45f9-9919-fae7e44c877a")
def test_msim_voice_conf_call_host_csfb_volte_psim_dds_slot_0(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0, None, None, 0, host_rat=["csfb", "volte"])
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="da98268a-a94a-4fc7-8fb9-8e8573baed50")
def test_msim_voice_conf_call_host_csfb_volte_psim_dds_slot_1(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0, None, None, 1, host_rat=["csfb", "volte"])
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="df46bcf5-48a3-466f-ba37-9519f5a671cf")
def test_msim_voice_conf_call_host_csfb_volte_esim_dds_slot_0(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1, None, None, 0, host_rat=["csfb", "volte"])
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="f0c82ae0-c659-45e3-9a00-419e2da55739")
def test_msim_voice_conf_call_host_csfb_volte_esim_dds_slot_1(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1, None, None, 1, host_rat=["csfb", "volte"])
-
-
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="4831c07a-9a38-4ccd-8fa0-beaf52a2751e")
def test_msim_voice_conf_call_host_csfb_psim_dds_slot_0(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0, None, None, 0, host_rat=["csfb", "csfb"])
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="79cbf768-88ea-4d03-b798-2097789ee456")
def test_msim_voice_conf_call_host_csfb_psim_dds_slot_1(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0, None, None, 1, host_rat=["csfb", "csfb"])
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="68b0a15f-62e4-419d-948a-d74d763a736c")
def test_msim_voice_conf_call_host_csfb_esim_dds_slot_0(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1, None, None, 0, host_rat=["csfb", "csfb"])
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="a93af289-98a8-4d4b-bdbd-54478f273fea")
def test_msim_voice_conf_call_host_csfb_esim_dds_slot_1(self):
- return self._test_msim_call_voice_conf(
+ return msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1, None, None, 1, host_rat=["csfb", "csfb"])
-
-
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="43e450c8-8a0b-4dfc-8c59-d0865c4c6399")
def test_msim_call_waiting_volte_psim_dds_slot_0(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1215,7 +435,10 @@
host_rat=["volte", "volte"],
merge=False, disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1230,7 +453,10 @@
@test_tracker_info(uuid="7d05525e-8fcf-4630-9248-22803a14209d")
def test_msim_call_waiting_volte_psim_dds_slot_1(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1239,7 +465,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1254,7 +483,10 @@
@test_tracker_info(uuid="caec880c-948a-4fcd-b57e-e64fd3048b08")
def test_msim_call_waiting_volte_esim_dds_slot_0(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1263,7 +495,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1278,7 +513,10 @@
@test_tracker_info(uuid="72ec685d-6c36-40cd-81fd-dd97e32b1e48")
def test_msim_call_waiting_volte_esim_dds_slot_1(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1287,7 +525,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1298,13 +539,14 @@
result = False
return result
-
-
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="3cef5c80-b15f-45fa-8376-5252e61d7849")
def test_msim_call_waiting_volte_csfb_psim_dds_slot_0(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1313,7 +555,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1328,7 +573,10 @@
@test_tracker_info(uuid="5da5c799-5349-4cf3-b683-c7372aadfdfa")
def test_msim_call_waiting_volte_csfb_psim_dds_slot_1(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1337,7 +585,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1352,7 +603,10 @@
@test_tracker_info(uuid="30c06bb3-a62f-4dba-90c2-1b00c515034a")
def test_msim_call_waiting_volte_csfb_esim_dds_slot_0(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1361,7 +615,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1376,7 +633,10 @@
@test_tracker_info(uuid="d2b0fdb1-5ea6-4958-a34f-6f701801e3c9")
def test_msim_call_waiting_volte_csfb_esim_dds_slot_1(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1385,7 +645,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1396,13 +659,14 @@
result = False
return result
-
-
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="b239d4be-9a36-4791-84df-ecebae645c84")
def test_msim_call_waiting_csfb_volte_psim_dds_slot_0(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1411,7 +675,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1426,7 +693,10 @@
@test_tracker_info(uuid="51a368e6-83d8-46af-8a85-56aaed787f9f")
def test_msim_call_waiting_csfb_volte_psim_dds_slot_1(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1435,7 +705,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1450,7 +723,10 @@
@test_tracker_info(uuid="73646014-1ead-4bd9-bd8f-2c21da3d596a")
def test_msim_call_waiting_csfb_volte_esim_dds_slot_0(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1459,7 +735,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1474,7 +753,10 @@
@test_tracker_info(uuid="0d520b78-20b8-4be7-833a-40179114cbce")
def test_msim_call_waiting_csfb_volte_esim_dds_slot_1(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1483,7 +765,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1498,7 +783,10 @@
@test_tracker_info(uuid="0544abec-7a59-4de0-be45-0b9b9d706b17")
def test_msim_call_waiting_csfb_psim_dds_slot_0(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1507,7 +795,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1522,7 +813,10 @@
@test_tracker_info(uuid="4329319b-0503-4c51-8792-2f36090b8071")
def test_msim_call_waiting_csfb_psim_dds_slot_1(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1531,7 +825,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
None,
None,
@@ -1546,7 +843,10 @@
@test_tracker_info(uuid="d612ce5c-b4cd-490c-bc6c-7f67c25264aa")
def test_msim_call_waiting_csfb_esim_dds_slot_0(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1555,7 +855,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1570,7 +873,10 @@
@test_tracker_info(uuid="fb4869da-a346-4275-a742-d2c653bfc39a")
def test_msim_call_waiting_csfb_esim_dds_slot_1(self):
result = True
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
@@ -1579,7 +885,10 @@
merge=False,
disable_cw=False):
result = False
- if not self._test_msim_call_voice_conf(
+ if not msim_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
None,
None,
diff --git a/acts_tests/tests/google/tel/live/TelLiveGFTDSDSVoiceTest.py b/acts_tests/tests/google/tel/live/TelLiveGFTDSDSVoiceTest.py
index f984ed7..c51e078 100644
--- a/acts_tests/tests/google/tel/live/TelLiveGFTDSDSVoiceTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveGFTDSDSVoiceTest.py
@@ -14,40 +14,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from acts import asserts
-from acts import signals
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import \
- TelephonyVoiceTestResult
-from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import \
- TelephonyMetricLogger
+from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_CONFERENCE
-from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_incoming_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_outgoing_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_0
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_1
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_subid_on_same_network_of_host_ad
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import get_capability_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import get_slot_index_from_subid
-from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
-from acts_contrib.test_utils.tel.tel_voice_utils import \
- phone_setup_voice_general_for_subscription
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_on_rat
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_on_rat
-from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_msim_for_slot
+from acts_contrib.test_utils.tel.tel_dsds_utils import dsds_voice_call_test
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
-CallResult = TelephonyVoiceTestResult.CallResult.Value
class TelLiveGFTDSDSVoiceTest(TelephonyBaseTest):
def setup_class(self):
@@ -57,597 +29,506 @@
def teardown_test(self):
ensure_phones_idle(self.log, self.android_devices)
- def _hangup_call(self, ad, device_description='Device'):
- if not hangup_call(self.log, ad):
- ad.log.error("Failed to hang up on %s", device_description)
- return False
- return True
-
- def _test_msim_call_voice(
- self,
- mo_slot,
- mt_slot,
- dds_slot,
- mo_rat=["", ""],
- mt_rat=["", ""],
- call_direction="mo"):
- """Make MO/MT voice call at specific slot in specific RAT with DDS at
- specific slot.
-
- Test step:
- 1. Get sub IDs of specific slots of both MO and MT devices.
- 2. Switch DDS to specific slot.
- 3. Check HTTP connection after DDS switch.
- 4. Set up phones in desired RAT.
- 5. Make voice call.
-
- Args:
- mo_slot: Slot making MO call (0 or 1)
- mt_slot: Slot receiving MT call (0 or 1)
- dds_slot: Preferred data slot
- mo_rat: RAT for both slots of MO device
- mt_rat: RAT for both slots of MT device
- call_direction: "mo" or "mt"
-
- Returns:
- TestFailure if failed.
- """
- ads = self.android_devices
-
- if call_direction == "mo":
- ad_mo = ads[0]
- ad_mt = ads[1]
- else:
- ad_mo = ads[1]
- ad_mt = ads[0]
-
- if mo_slot is not None:
- mo_sub_id = get_subid_from_slot_index(self.log, ad_mo, mo_slot)
- if mo_sub_id == INVALID_SUB_ID:
- ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot)
- return False
- mo_other_sub_id = get_subid_from_slot_index(
- self.log, ad_mo, 1-mo_slot)
- set_voice_sub_id(ad_mo, mo_sub_id)
- else:
- _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
- if mo_sub_id == INVALID_SUB_ID:
- ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot)
- return False
- mo_slot = "auto"
- set_voice_sub_id(ad_mo, mo_sub_id)
- ad_mo.log.info("Sub ID for outgoing call at slot %s: %s",
- mo_slot, get_outgoing_voice_sub_id(ad_mo))
-
- if mt_slot is not None:
- mt_sub_id = get_subid_from_slot_index(self.log, ad_mt, mt_slot)
- if mt_sub_id == INVALID_SUB_ID:
- ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
- return False
- mt_other_sub_id = get_subid_from_slot_index(
- self.log, ad_mt, 1-mt_slot)
- set_voice_sub_id(ad_mt, mt_sub_id)
- else:
- _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
- if mt_sub_id == INVALID_SUB_ID:
- ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
- return False
- mt_slot = "auto"
- set_voice_sub_id(ad_mt, mt_sub_id)
- ad_mt.log.info("Sub ID for incoming call at slot %s: %s", mt_slot,
- get_incoming_voice_sub_id(ad_mt))
-
- self.log.info("Step 1: Switch DDS.")
- if dds_slot:
- if not set_dds_on_slot_1(ads[0]):
- ads[0].log.warning("Failed to set DDS at eSIM.")
- return False
- else:
- if not set_dds_on_slot_0(ads[0]):
- ads[0].log.warning("Failed to set DDS at pSIM.")
- return False
-
- self.log.info("Step 2: Check HTTP connection after DDS switch.")
- if not verify_http_connection(self.log,
- ads[0],
- url="https://www.google.com",
- retry=5,
- retry_interval=15,
- expected_state=True):
-
- self.log.error("Failed to verify http connection.")
- return False
- else:
- self.log.info("Verify http connection successfully.")
-
- if mo_slot == 0 or mo_slot == 1:
- phone_setup_on_rat(self.log, ad_mo, mo_rat[1-mo_slot], mo_other_sub_id)
- mo_phone_setup_func = phone_setup_on_rat(
- self.log,
- ad_mo,
- mo_rat[mo_slot],
- only_return_fn=True)
- is_mo_in_call = is_phone_in_call_on_rat(
- self.log, ad_mo, mo_rat[mo_slot], only_return_fn=True)
- else:
- phone_setup_on_rat(self.log, ad_mo, 'general')
- mo_phone_setup_func = phone_setup_voice_general_for_subscription
- is_mo_in_call = is_phone_in_call_on_rat(
- self.log, ad_mo, 'general', only_return_fn=True)
-
- if mt_slot == 0 or mt_slot == 1:
- phone_setup_on_rat(self.log, ad_mt, mt_rat[1-mt_slot], mt_other_sub_id)
- mt_phone_setup_func = phone_setup_on_rat(
- self.log,
- ad_mt,
- mt_rat[mt_slot],
- only_return_fn=True)
- is_mt_in_call = is_phone_in_call_on_rat(
- self.log, ad_mt, mt_rat[mt_slot], only_return_fn=True)
- else:
- phone_setup_on_rat(self.log, ad_mt, 'general')
- mt_phone_setup_func = phone_setup_voice_general_for_subscription
- is_mt_in_call = is_phone_in_call_on_rat(
- self.log, ad_mt, 'general', only_return_fn=True)
-
- self.log.info("Step 3: Set up phones in desired RAT.")
- tasks = [(mo_phone_setup_func, (self.log, ad_mo, mo_sub_id)),
- (mt_phone_setup_func, (self.log, ad_mt, mt_sub_id))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- self.tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
- raise signals.TestFailure("Failed",
- extras={"fail_reason": "Phone Failed to Set Up Properly."})
-
- self.log.info("Step 4: Make voice call.")
- result = two_phone_call_msim_for_slot(
- self.log,
- ad_mo,
- get_slot_index_from_subid(self.log, ad_mo, mo_sub_id),
- None,
- is_mo_in_call,
- ad_mt,
- get_slot_index_from_subid(self.log, ad_mt, mt_sub_id),
- None,
- is_mt_in_call)
- self.tel_logger.set_result(result.result_value)
-
- if not result:
- self.log.error(
- "Failed to make MO call from %s slot %s to %s slot %s",
- ad_mo.serial, mo_slot, ad_mt.serial, mt_slot)
- raise signals.TestFailure("Failed",
- extras={"fail_reason": str(result.result_value)})
-
-
@test_tracker_info(uuid="e252aa07-c377-4e12-8f06-ed1dc8f2b6a6")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_volte_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 0, mo_rat=["volte", "volte"], call_direction="mo")
@test_tracker_info(uuid="7631b805-48b6-4b91-99a3-eef392e5b0fc")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_volte_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 1, mo_rat=["volte", "volte"], call_direction="mo")
@test_tracker_info(uuid="4771e517-08cf-4169-afe7-fe3e41f05c45")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_volte_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 0, mt_rat=["volte", "volte"], call_direction="mt")
@test_tracker_info(uuid="e8f914df-cada-4187-ab53-734624c9c941")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_volte_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 1, mt_rat=["volte", "volte"], call_direction="mt")
@test_tracker_info(uuid="967a665a-9614-4fe4-b293-e20b66637802")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_volte_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 0, mo_rat=["volte", "volte"], call_direction="mo")
@test_tracker_info(uuid="901c7fa3-039f-4888-90eb-82af587fa8dd")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_volte_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 1, mo_rat=["volte", "volte"], call_direction="mo")
@test_tracker_info(uuid="a78f2808-a6c6-4483-b7f5-ad1ec925dd52")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_volte_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 0, mt_rat=["volte", "volte"], call_direction="mt")
@test_tracker_info(uuid="f6994dbd-c5a0-42c7-a43d-67227f5dfb88")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_volte_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 1, mt_rat=["volte", "volte"], call_direction="mt")
@test_tracker_info(uuid="0786d7d3-d272-4233-83dd-0667e844094d")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_volte_csfb_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 0, mo_rat=["volte", "csfb"], call_direction="mo")
@test_tracker_info(uuid="b9dfd46c-752c-4424-83b1-b5749a7018af")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_volte_csfb_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 1, mo_rat=["volte", "csfb"], call_direction="mo")
@test_tracker_info(uuid="8bc57654-a5d9-4c82-b11a-62e76ece9b43")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_volte_csfb_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 0, mt_rat=["volte", "csfb"], call_direction="mt")
@test_tracker_info(uuid="dbe44bf1-4638-4490-a06f-406205681ca5")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_volte_csfb_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 1, mt_rat=["volte", "csfb"], call_direction="mt")
@test_tracker_info(uuid="ffd82db7-eaaa-4f96-9e3b-e0e15d054e62")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_volte_csfb_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 0, mo_rat=["volte", "csfb"], call_direction="mo")
@test_tracker_info(uuid="f7f3f28b-eecf-42e5-ba28-168a38337c80")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_volte_csfb_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 1, mo_rat=["volte", "csfb"], call_direction="mo")
@test_tracker_info(uuid="eb6ae70a-3251-4642-8268-b91b593cecfd")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_volte_csfb_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 0, mt_rat=["volte", "csfb"], call_direction="mt")
@test_tracker_info(uuid="1d927140-34d2-4fc7-8fe4-b23a303fd190")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_volte_csfb_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 1, mt_rat=["volte", "csfb"], call_direction="mt")
@test_tracker_info(uuid="f15f6696-6e11-414b-8e28-9c16793b66b0")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_csfb_volte_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 0, mo_rat=["csfb", "volte"], call_direction="mo")
@test_tracker_info(uuid="ca99d987-0bdb-4034-892f-cc0b1d22f381")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_csfb_volte_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 1, mo_rat=["csfb", "volte"], call_direction="mo")
@test_tracker_info(uuid="692bd3d0-05be-4597-afab-2f837a3f9bd4")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_csfb_volte_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 0, mt_rat=["csfb", "volte"], call_direction="mt")
@test_tracker_info(uuid="87a5fae2-f32c-4b4d-8028-d065b582b117")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_csfb_volte_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 1, mt_rat=["csfb", "volte"], call_direction="mt")
@test_tracker_info(uuid="f6375034-5ecb-4872-bab2-cf9529f20fda")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_csfb_volte_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 0, mo_rat=["csfb", "volte"], call_direction="mo")
@test_tracker_info(uuid="6185bc28-1703-4ca2-a617-171d81adfe9a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_csfb_volte_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 1, mo_rat=["csfb", "volte"], call_direction="mo")
@test_tracker_info(uuid="06bad228-27af-47b4-9b74-aacba81f9da7")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_csfb_volte_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 0, mt_rat=["csfb", "volte"], call_direction="mt")
@test_tracker_info(uuid="5a5f2178-2ac6-4d21-bf6f-b9d8455365f1")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_csfb_volte_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 1, mt_rat=["csfb", "volte"], call_direction="mt")
@test_tracker_info(uuid="216f8569-8120-43c4-a9c5-da3081d168db")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_volte_3g_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 0, mo_rat=["volte", "3g"], call_direction="mo")
@test_tracker_info(uuid="8d15524a-f7f9-4321-a962-b455bfdf4ec9")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_volte_3g_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 1, mo_rat=["volte", "3g"], call_direction="mo")
@test_tracker_info(uuid="c6aa5975-9ea6-4367-a59e-a248fde2c8be")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_volte_3g_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 0, mt_rat=["volte", "3g"], call_direction="mt")
@test_tracker_info(uuid="a99a54e0-46ea-4d35-a3c1-d825c546cc21")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_volte_3g_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 1, mt_rat=["volte", "3g"], call_direction="mt")
@test_tracker_info(uuid="6d128732-8a8e-488b-bb38-fbb764d228dd")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_volte_3g_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 0, mo_rat=["volte", "3g"], call_direction="mo")
@test_tracker_info(uuid="29517d00-5edf-4617-9d29-226d56426abf")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_volte_3g_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 1, mo_rat=["volte", "3g"], call_direction="mo")
@test_tracker_info(uuid="d18ec79e-3bc3-4c7e-89fd-d03519b2e2a6")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_volte_3g_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 0, mt_rat=["volte", "3g"], call_direction="mt")
@test_tracker_info(uuid="6442b85a-b116-4987-b6d5-2d2b9bac7fd5")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_volte_3g_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 1, mt_rat=["volte", "3g"], call_direction="mt")
@test_tracker_info(uuid="82e6f955-5156-4ad3-885d-d1d5ff0526cb")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_3g_volte_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 0, mo_rat=["3g", "volte"], call_direction="mo")
@test_tracker_info(uuid="ffdafbac-026d-4d7d-a1dc-f639c01db818")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_3g_volte_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 1, mo_rat=["3g", "volte"], call_direction="mo")
@test_tracker_info(uuid="b18dc6a7-e4a1-4409-a4aa-4e4add2fee13")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_3g_volte_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 0, mt_rat=["3g", "volte"], call_direction="mt")
@test_tracker_info(uuid="ea6fc855-31b8-4680-b306-51228277e0d3")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_3g_volte_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 1, mt_rat=["3g", "volte"], call_direction="mt")
@test_tracker_info(uuid="fdf9f4ea-a6f6-4434-a912-13711bb33a72")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_3g_volte_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 0, mo_rat=["3g", "volte"], call_direction="mo")
@test_tracker_info(uuid="deb8e2f6-e097-451e-9f19-aadaf1820fea")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_3g_volte_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 1, mo_rat=["3g", "volte"], call_direction="mo")
@test_tracker_info(uuid="6a636c5d-5da9-4916-9751-435ab39aaa00")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_3g_volte_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 0, mt_rat=["3g", "volte"], call_direction="mt")
@test_tracker_info(uuid="0b9d9d5c-e5e7-4c9d-ab8a-0658fadbf450")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_3g_volte_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 1, mt_rat=["3g", "volte"], call_direction="mt")
@test_tracker_info(uuid="fce99df9-8931-4a34-9285-121145fb9b2f")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_csfb_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 0, mo_rat=["csfb", "csfb"], call_direction="mo")
@test_tracker_info(uuid="81d9a087-e494-40e4-a0fb-7e4ef62e566c")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_csfb_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 1, mo_rat=["csfb", "csfb"], call_direction="mo")
@test_tracker_info(uuid="d4520000-9cd1-4aff-9862-bfb6832d51ce")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_csfb_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 0, mt_rat=["csfb", "csfb"], call_direction="mt")
@test_tracker_info(uuid="0eaf1e67-6aec-4a39-8f06-4e49009400e0")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_csfb_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 1, mt_rat=["csfb", "csfb"], call_direction="mt")
@test_tracker_info(uuid="0e6bc15a-e510-4b56-826c-96e0add6b20a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_csfb_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 0, mo_rat=["csfb", "csfb"], call_direction="mo")
@test_tracker_info(uuid="ecead288-424d-4579-bf6a-10a1a78600d5")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_csfb_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 1, mo_rat=["csfb", "csfb"], call_direction="mo")
@test_tracker_info(uuid="3a76076d-808e-45f8-b99c-95b82f2f07de")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_csfb_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 0, mt_rat=["csfb", "csfb"], call_direction="mt")
@test_tracker_info(uuid="af638c75-c0e1-4ac1-83f5-bc0e6cdd913c")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_csfb_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 1, mt_rat=["csfb", "csfb"], call_direction="mt")
@test_tracker_info(uuid="0bf59f38-ddbc-4a88-bc8a-d6985e7d7567")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_csfb_3g_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 0, mo_rat=["csfb", "3g"], call_direction="mo")
@test_tracker_info(uuid="59f5a14a-c7e5-4bca-82dd-cb90b9a7a0e1")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_csfb_3g_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 1, mo_rat=["csfb", "3g"], call_direction="mo")
@test_tracker_info(uuid="79fc4d6f-0915-4717-80ae-db656cf3a82c")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_csfb_3g_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 0, mt_rat=["csfb", "3g"], call_direction="mt")
@test_tracker_info(uuid="b4927ebb-ae36-4ca7-a0b7-ea011b271122")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_csfb_3g_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 1, mt_rat=["csfb", "3g"], call_direction="mt")
@test_tracker_info(uuid="620be8d5-40b7-45f2-abfd-f788c8ce1977")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_csfb_3g_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 0, mo_rat=["csfb", "3g"], call_direction="mo")
@test_tracker_info(uuid="e277e0db-2dfb-4cfc-8d13-7c699f397b9b")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_csfb_3g_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 1, mo_rat=["csfb", "3g"], call_direction="mo")
@test_tracker_info(uuid="f7822fca-a22d-4989-bca8-506e9652cee1")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_csfb_3g_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 0, mt_rat=["csfb", "3g"], call_direction="mt")
@test_tracker_info(uuid="60e5f5cd-a2e1-4a6a-b76b-25a8ce2b037d")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_csfb_3g_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 1, mt_rat=["csfb", "3g"], call_direction="mt")
@test_tracker_info(uuid="ef4b5c61-e9c9-4a29-8ff1-f9920ec9f4dd")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_3g_csfb_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 0, mo_rat=["3g", "csfb"], call_direction="mo")
@test_tracker_info(uuid="0e82934d-391d-46af-9609-f59522140ea9")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_3g_csfb_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 1, mo_rat=["3g", "csfb"], call_direction="mo")
@test_tracker_info(uuid="dab9ea2d-5370-4438-b0ee-67c68ebda024")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_3g_csfb_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 0, mt_rat=["3g", "csfb"], call_direction="mt")
@test_tracker_info(uuid="3ba5816e-11fe-4a39-968d-2e9853e8f47a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_3g_csfb_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 1, mt_rat=["3g", "csfb"], call_direction="mt")
@test_tracker_info(uuid="e8246c60-031d-4362-94c6-ad0882511d21")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_3g_csfb_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 0, mo_rat=["3g", "csfb"], call_direction="mo")
@test_tracker_info(uuid="db66ecb2-b09d-44be-991b-8025c6fab26a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_3g_csfb_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 1, mo_rat=["3g", "csfb"], call_direction="mo")
@test_tracker_info(uuid="008e990c-94e4-4adc-abaa-e328d84079a5")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_3g_csfb_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 0, mt_rat=["3g", "csfb"], call_direction="mt")
@test_tracker_info(uuid="0a87cbb1-96d9-4eed-b92c-745432dc4ba4")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_3g_csfb_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 1, mt_rat=["3g", "csfb"], call_direction="mt")
@test_tracker_info(uuid="5620c3c8-e847-42c1-ae4e-b3370a0b6f98")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_3g_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 0, mo_rat=["3g", "3g"], call_direction="mo")
@test_tracker_info(uuid="a4415a1e-cd91-4a74-8f49-6c8ea428fe8f")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_3g_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
0, None, 1, mo_rat=["3g", "3g"], call_direction="mo")
@test_tracker_info(uuid="35a73981-15d7-491f-bade-42642cabbf76")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_3g_psim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 0, mt_rat=["3g", "3g"], call_direction="mt")
@test_tracker_info(uuid="e38de6bd-8f6b-4a95-8c0f-e685abc3e7ef")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_3g_psim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 0, 1, mt_rat=["3g", "3g"], call_direction="mt")
@test_tracker_info(uuid="1c86a1cb-5bd6-404a-a38f-4619a4b641a2")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_3g_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 0, mo_rat=["3g", "3g"], call_direction="mo")
@test_tracker_info(uuid="665736ff-206f-4c02-ae81-26f2e25d5988")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mo_3g_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
1, None, 1, mo_rat=["3g", "3g"], call_direction="mo")
@test_tracker_info(uuid="5e5c8f33-60e5-44be-bf69-56c7715ead41")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_3g_esim_dds_slot_0(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 0, mt_rat=["3g", "3g"], call_direction="mt")
@test_tracker_info(uuid="2250b4d5-7b34-45cb-8ec2-300f4a4fbc2b")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_call_mt_3g_esim_dds_slot_1(self):
- return self._test_msim_call_voice(
+ return dsds_voice_call_test(
+ self.log, self.tel_logger, self.android_devices,
None, 1, 1, mt_rat=["3g", "3g"], call_direction="mt")
\ No newline at end of file
diff --git a/acts_tests/tests/google/tel/live/TelLiveGFTDSDSWfcSupplementaryServiceTest.py b/acts_tests/tests/google/tel/live/TelLiveGFTDSDSWfcSupplementaryServiceTest.py
index acdb8eb..f88661a 100644
--- a/acts_tests/tests/google/tel/live/TelLiveGFTDSDSWfcSupplementaryServiceTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveGFTDSDSWfcSupplementaryServiceTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright 2020 - Google
+# Copyright 2021 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,90 +14,32 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import re
-import time
-from acts import asserts
from acts import signals
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import \
- TelephonyVoiceTestResult
-from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import \
- TelephonyMetricLogger
+from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
+from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_defines import CALL_CAPABILITY_MANAGE_CONFERENCE
-from acts_contrib.test_utils.tel.tel_defines import CALL_PROPERTY_CONFERENCE
-from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_ACTIVE
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_CONFERENCE
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
-from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
-from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_incoming_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_outgoing_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_0
-from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_1
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_subid_on_same_network_of_host_ad
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls
-from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_wfc_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode_for_subscription
+from acts_contrib.test_utils.tel.tel_dsds_utils import erase_call_forwarding
+from acts_contrib.test_utils.tel.tel_dsds_utils import msim_volte_wfc_call_forwarding
+from acts_contrib.test_utils.tel.tel_dsds_utils import msim_volte_wfc_call_voice_conf
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
from acts_contrib.test_utils.tel.tel_test_utils import get_capability_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import set_call_forwarding_by_mmi
-from acts_contrib.test_utils.tel.tel_test_utils import erase_call_forwarding_by_mmi
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_test_utils import set_call_waiting
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import \
- wait_and_reject_call_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
-from acts_contrib.test_utils.tel.tel_voice_utils import get_cep_conference_call_id
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan_for_subscription
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import \
- phone_setup_csfb_for_subscription
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import \
- phone_setup_voice_3g_for_subscription
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_general
-from acts_contrib.test_utils.tel.tel_voice_utils import \
- phone_setup_voice_general_for_subscription
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import \
- phone_setup_volte_for_subscription
-from acts_contrib.test_utils.tel.tel_voice_utils import \
- three_phone_call_forwarding_short_seq
-from acts_contrib.test_utils.tel.tel_voice_utils import \
- three_phone_call_waiting_short_seq
-from acts_contrib.test_utils.tel.tel_voice_utils import swap_calls
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_on_rat
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_on_rat
CallResult = TelephonyVoiceTestResult.CallResult.Value
+
class TelLiveGFTDSDSWfcSupplementaryServiceTest(TelephonyBaseTest):
def setup_class(self):
TelephonyBaseTest.setup_class(self)
self.message_lengths = (50, 160, 180)
self.tel_logger = TelephonyMetricLogger.for_test_case()
toggle_airplane_mode(self.log, self.android_devices[0], False)
- self.erase_call_forwarding(self.log, self.android_devices[0])
+ erase_call_forwarding(self.log, self.android_devices[0])
if not get_capability_for_subscription(
self.android_devices[0],
CAPABILITY_CONFERENCE,
@@ -110,1106 +52,446 @@
def teardown_test(self):
toggle_airplane_mode(self.log, self.android_devices[0], False)
ensure_phones_idle(self.log, self.android_devices)
- self.erase_call_forwarding(self.log, self.android_devices[0])
-
-
- def _hangup_call(self, ad, device_description='Device'):
- if not hangup_call(self.log, ad):
- ad.log.error("Failed to hang up on %s", device_description)
- return False
- return True
-
- def erase_call_forwarding(self, log, ad):
- slot0_sub_id = get_subid_from_slot_index(log, ad, 0)
- slot1_sub_id = get_subid_from_slot_index(log, ad, 1)
- current_voice_sub_id = get_incoming_voice_sub_id(ad)
- for sub_id in (slot0_sub_id, slot1_sub_id):
- set_voice_sub_id(ad, sub_id)
- get_operator_name(log, ad, sub_id)
- erase_call_forwarding_by_mmi(log, ad)
- set_voice_sub_id(ad, current_voice_sub_id)
-
- def _three_phone_call_mo_add_mt(
- self,
- ads,
- phone_setups,
- verify_funcs,
- reject_once=False):
- """Use 3 phones to make MO call and MT call.
-
- Call from PhoneA to PhoneB, accept on PhoneB.
- Call from PhoneC to PhoneA, accept on PhoneA.
-
- Args:
- ads: list of ad object.
- The list should have three objects.
- phone_setups: list of phone setup functions.
- The list should have three objects.
- verify_funcs: list of phone call verify functions.
- The list should have three objects.
-
- Returns:
- If success, return 'call_AB' id in PhoneA.
- if fail, return None.
- """
-
- class _CallException(Exception):
- pass
-
- try:
- verify_func_a, verify_func_b, verify_func_c = verify_funcs
- tasks = []
- for ad, setup_func in zip(ads, phone_setups):
- if setup_func is not None:
- tasks.append((setup_func, (self.log, ad)))
- if tasks != [] and not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- raise _CallException("Setup failed.")
- for ad in ads:
- ad.droid.telecomCallClearCallList()
- if num_active_calls(self.log, ad) != 0:
- ad.log.error("Phone Call List is not empty.")
- raise _CallException("Clear call list failed.")
-
- self.log.info("Step1: Call From PhoneA to PhoneB.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=verify_func_a,
- verify_callee_func=verify_func_b):
- raise _CallException("PhoneA call PhoneB failed.")
-
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
- if num_active_calls(self.log, ads[0]) != 1:
- raise _CallException("Call list verify failed.")
- call_ab_id = calls[0]
-
- self.log.info("Step2: Call From PhoneC to PhoneA.")
- if reject_once:
- self.log.info("Step2-1: Reject incoming call once.")
- if not initiate_call(
- self.log,
- ads[2],
- ads[0].telephony['subscription'][get_incoming_voice_sub_id(
- ads[0])]['phone_num']):
- ads[2].log.error("Initiate call failed.")
- raise _CallException("Failed to initiate call.")
-
- if not wait_and_reject_call_for_subscription(
- self.log,
- ads[0],
- get_incoming_voice_sub_id(ads[0]),
- incoming_number= \
- ads[2].telephony['subscription'][
- get_incoming_voice_sub_id(
- ads[2])]['phone_num']):
- ads[0].log.error("Reject call fail.")
- raise _CallException("Failed to reject call.")
-
- self._hangup_call(ads[2], "PhoneC")
- time.sleep(15)
-
- if not call_setup_teardown(
- self.log,
- ads[2],
- ads[0],
- ad_hangup=None,
- verify_caller_func=verify_func_c,
- verify_callee_func=verify_func_a):
- raise _CallException("PhoneA call PhoneC failed.")
- if not verify_incall_state(self.log, [ads[0], ads[1], ads[2]],
- True):
- raise _CallException("Not All phones are in-call.")
-
- except Exception as e:
- self.log.error(e)
- setattr(ads[0], "exception", e)
- return None
-
- return call_ab_id
-
- def _test_ims_conference_merge_drop_second_call_from_participant(
- self, call_ab_id, call_ac_id):
- """Test conference merge and drop in IMS (VoLTE or WiFi Calling) call.
- (supporting both cases of CEP enabled and disabled).
-
- PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneB.
- PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneC.
- Merge calls to conference on PhoneA.
- Hangup on PhoneC, check call continues between AB.
- Hangup on PhoneB, check A ends.
-
- Args:
- call_ab_id: call id for call_AB on PhoneA.
- call_ac_id: call id for call_AC on PhoneA.
-
- Returns:
- True if succeed;
- False if failed.
- """
- ads = self.android_devices
-
- call_conf_id = self._merge_ims_conference_call(call_ab_id, call_ac_id)
- if call_conf_id is None:
- return False
-
- self.log.info("Step5: End call on PhoneC and verify call continues.")
- if not self._hangup_call(ads[2], "PhoneC"):
- return False
- time.sleep(WAIT_TIME_IN_CALL)
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
- if not verify_incall_state(self.log, [ads[0], ads[1]], True):
- return False
- if not verify_incall_state(self.log, [ads[2]], False):
- return False
-
- self.log.info("Step6: End call on PhoneB and verify PhoneA end.")
- if not self._hangup_call(ads[1], "PhoneB"):
- return False
- time.sleep(WAIT_TIME_IN_CALL)
- if not verify_incall_state(self.log, [ads[0], ads[1], ads[2]], False):
- return False
- return True
-
-
- def _merge_ims_conference_call(self, call_ab_id, call_ac_id):
- """Merge IMS conference call for both cases of CEP enabled and disabled.
-
- PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneB.
- PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneC.
- Merge calls to conference on PhoneA.
-
- Args:
- call_ab_id: call id for call_AB on PhoneA.
- call_ac_id: call id for call_AC on PhoneA.
-
- Returns:
- call_id for conference
- """
- ads = self.android_devices
- self.log.info("Step4: Merge to Conf Call and verify Conf Call.")
- ads[0].droid.telecomCallJoinCallsInConf(call_ab_id, call_ac_id)
- time.sleep(WAIT_TIME_IN_CALL)
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
-
- call_conf_id = None
- if num_active_calls(self.log, ads[0]) != 1:
- ads[0].log.info("Total number of call ids is not 1.")
- call_conf_id = get_cep_conference_call_id(ads[0])
- if call_conf_id is not None:
- self.log.info("New conference call id is found. CEP enabled.")
- calls.remove(call_conf_id)
- if (set(ads[0].droid.telecomCallGetCallChildren(
- call_conf_id)) != set(calls)):
- ads[0].log.error(
- "Children list %s for conference call is not correct.",
- ads[0].droid.telecomCallGetCallChildren(call_conf_id))
- return None
-
- if (CALL_PROPERTY_CONFERENCE not in ads[0]
- .droid.telecomCallGetProperties(call_conf_id)):
- ads[0].log.error(
- "Conf call id % properties wrong: %s", call_conf_id,
- ads[0].droid.telecomCallGetProperties(call_conf_id))
- return None
-
- if (CALL_CAPABILITY_MANAGE_CONFERENCE not in ads[0]
- .droid.telecomCallGetCapabilities(call_conf_id)):
- ads[0].log.error(
- "Conf call id %s capabilities wrong: %s", call_conf_id,
- ads[0].droid.telecomCallGetCapabilities(call_conf_id))
- return None
-
- if (call_ab_id in calls) or (call_ac_id in calls):
- self.log.error("Previous call ids should not in new call"
- " list after merge.")
- return None
- else:
- for call_id in calls:
- if call_id != call_ab_id and call_id != call_ac_id:
- call_conf_id = call_id
- self.log.info("CEP not enabled.")
-
- if not call_conf_id:
- self.log.error("Merge call fail, no new conference call id.")
- raise signals.TestFailure(
- "Calls were not merged. Failed to merge calls.",
- extras={"fail_reason": "Calls were not merged."
- " Failed to merge calls."})
- if not verify_incall_state(self.log, [ads[0], ads[1], ads[2]], True):
- return False
-
- # Check if Conf Call is currently active
- if ads[0].droid.telecomCallGetCallState(
- call_conf_id) != CALL_STATE_ACTIVE:
- ads[0].log.error(
- "Call_ID: %s, state: %s, expected: STATE_ACTIVE", call_conf_id,
- ads[0].droid.telecomCallGetCallState(call_conf_id))
- return None
-
- return call_conf_id
-
-
- def _test_wcdma_conference_merge_drop(self, call_ab_id, call_ac_id):
- """Test conference merge and drop in WCDMA/CSFB_WCDMA call.
-
- PhoneA in WCDMA (or CSFB_WCDMA) call with PhoneB.
- PhoneA in WCDMA (or CSFB_WCDMA) call with PhoneC.
- Merge calls to conference on PhoneA.
- Hangup on PhoneC, check call continues between AB.
- Hangup on PhoneB, check A ends.
-
- Args:
- call_ab_id: call id for call_AB on PhoneA.
- call_ac_id: call id for call_AC on PhoneA.
-
- Returns:
- True if succeed;
- False if failed.
- """
- ads = self.android_devices
-
- self.log.info("Step4: Merge to Conf Call and verify Conf Call.")
- ads[0].droid.telecomCallJoinCallsInConf(call_ab_id, call_ac_id)
- time.sleep(WAIT_TIME_IN_CALL)
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
- num_calls = num_active_calls(self.log, ads[0])
- if num_calls != 3:
- ads[0].log.error("Total number of call ids is not 3.")
- if num_calls == 2:
- if call_ab_id in calls and call_ac_id in calls:
- ads[0].log.error("Calls were not merged."
- " Failed to merge calls.")
- raise signals.TestFailure(
- "Calls were not merged. Failed to merge calls.",
- extras={"fail_reason": "Calls were not merged."
- " Failed to merge calls."})
- return False
- call_conf_id = None
- for call_id in calls:
- if call_id != call_ab_id and call_id != call_ac_id:
- call_conf_id = call_id
- if not call_conf_id:
- self.log.error("Merge call fail, no new conference call id.")
- return False
- if not verify_incall_state(self.log, [ads[0], ads[1], ads[2]], True):
- return False
-
- # Check if Conf Call is currently active
- if ads[0].droid.telecomCallGetCallState(
- call_conf_id) != CALL_STATE_ACTIVE:
- ads[0].log.error(
- "Call_id: %s, state: %s, expected: STATE_ACTIVE", call_conf_id,
- ads[0].droid.telecomCallGetCallState(call_conf_id))
- return False
-
- self.log.info("Step5: End call on PhoneC and verify call continues.")
- if not self._hangup_call(ads[2], "PhoneC"):
- return False
- time.sleep(WAIT_TIME_IN_CALL)
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
- if num_active_calls(self.log, ads[0]) != 1:
- return False
- if not verify_incall_state(self.log, [ads[0], ads[1]], True):
- return False
- if not verify_incall_state(self.log, [ads[2]], False):
- return False
-
- self.log.info("Step6: End call on PhoneB and verify PhoneA end.")
- if not self._hangup_call(ads[1], "PhoneB"):
- return False
- time.sleep(WAIT_TIME_IN_CALL)
- if not verify_incall_state(self.log, [ads[0], ads[1], ads[2]], False):
- return False
- return True
-
-
- def _test_msim_volte_wfc_call_forwarding(
- self,
- callee_slot,
- dds_slot,
- callee_rat=["wfc", "wfc"],
- call_forwarding_type="unconditional",
- enable_volte=[True, True],
- enable_wfc=[True, True],
- is_airplane_mode=False,
- is_wifi_connected=False,
- wfc_mode=[
- WFC_MODE_CELLULAR_PREFERRED,
- WFC_MODE_CELLULAR_PREFERRED]):
- """Make VoLTE/WFC call to the primary device at specific slot with DDS
- at specific slot, and then forwarded to 3rd device with specific call
- forwarding type.
-
- Test step:
- 1. Get sub IDs of specific slots of both MO and MT devices.
- 2. Set up phones in desired RAT.
- 3. Enable VoLTE/WFC.
- 4. Switch DDS to specific slot.
- 5. Check HTTP connection after DDS switch.
- 6. Register and enable call forwarding with specifc type.
- 7. Make VoLTE/WFC call to the primary device and wait for being
- forwarded to 3rd device.
-
- Args:
- callee_slot: Slot of primary device receiving and forwarding MT call
- (0 or 1)
- dds_slot: Preferred data slot
- callee_rat: RAT for both slots of the primary device
- call_forwarding_type:
- "unconditional"
- "busy"
- "not_answered"
- "not_reachable"
- enable_volte: True for enabling and False for disabling VoLTE for
- each slot on the primary device
- enable_wfc: True for enabling and False for disabling WFC for
- each slot on the primary device
- is_airplane_mode: True of False for WFC setup
- wfc_mode: Cellular preferred or Wi-Fi preferred.
-
- Returns:
- True or False
- """
- ads = self.android_devices
- ad_caller = ads[1]
- ad_callee = ads[0]
- ad_forwarded_callee = ads[2]
- slot_0_subid = get_subid_from_slot_index(self.log, ad_callee, 0)
- slot_1_subid = get_subid_from_slot_index(self.log, ad_callee, 1)
-
- if not toggle_airplane_mode(self.log, ad_callee, False):
- ad_callee.log.error("Failed to disable airplane mode.")
- return False
-
- # Set up callee (primary device)
- callee_sub_id = get_subid_from_slot_index(
- self.log, ad_callee, callee_slot)
- if callee_sub_id == INVALID_SUB_ID:
- self.log.warning(
- "Failed to get sub ID at slot %s.", callee_slot)
- return
- callee_other_sub_id = get_subid_from_slot_index(
- self.log, ad_callee, 1-callee_slot)
- set_voice_sub_id(ad_callee, callee_sub_id)
- ad_callee.log.info(
- "Sub ID for incoming call at slot %s: %s",
- callee_slot, get_incoming_voice_sub_id(ad_callee))
-
- # Set up caller
- _, caller_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
- if caller_sub_id == INVALID_SUB_ID:
- ad_caller.log.warning("Failed to get proper sub ID of the caller")
- return
- set_voice_sub_id(ad_caller, caller_sub_id)
- ad_caller.log.info(
- "Sub ID for outgoing call of the caller: %s",
- get_outgoing_voice_sub_id(ad_caller))
-
- # Set up forwarded callee
- _, _, forwarded_callee_sub_id = get_subid_on_same_network_of_host_ad(
- ads)
- if forwarded_callee_sub_id == INVALID_SUB_ID:
- ad_forwarded_callee.log.warning(
- "Failed to get proper sub ID of the forwarded callee.")
- return
- set_voice_sub_id(ad_forwarded_callee, forwarded_callee_sub_id)
- ad_forwarded_callee.log.info(
- "Sub ID for incoming call of the forwarded callee: %s",
- get_incoming_voice_sub_id(ad_forwarded_callee))
-
- set_call_forwarding_by_mmi(self.log, ad_callee, ad_forwarded_callee)
-
- ad_callee.log.info("Step 0: Set up phones in desired RAT.")
-
- if callee_slot == 1:
- phone_setup_on_rat(
- self.log,
- ad_callee,
- callee_rat[0],
- callee_other_sub_id,
- is_airplane_mode,
- wfc_mode[0],
- self.wifi_network_ssid,
- self.wifi_network_pass)
-
- elif callee_slot == 0:
- phone_setup_on_rat(
- self.log,
- ad_callee,
- callee_rat[1],
- callee_other_sub_id,
- is_airplane_mode,
- wfc_mode[1],
- self.wifi_network_ssid,
- self.wifi_network_pass)
-
- callee_phone_setup_func = phone_setup_on_rat(
- self.log, ad_callee, callee_rat[callee_slot], only_return_fn=True)
-
- if callee_rat[callee_slot] == 'wfc':
- argv = (
- self.log,
- ad_callee,
- callee_sub_id,
- is_airplane_mode,
- wfc_mode[callee_slot],
- self.wifi_network_ssid,
- self.wifi_network_pass)
- else:
- argv = (self.log, ad_callee, callee_sub_id)
-
- tasks = [(phone_setup_voice_general, (self.log, ad_caller)),
- (callee_phone_setup_func, argv),
- (phone_setup_voice_general, (self.log, ad_forwarded_callee))]
-
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- self.tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
- raise signals.TestFailure("Failed",
- extras={"fail_reason": "Phone Failed to Set Up Properly."})
-
- if is_wifi_connected:
- if not ensure_wifi_connected(
- self.log,
- ad_callee,
- self.wifi_network_ssid,
- self.wifi_network_pass,
- apm=is_airplane_mode):
- return False
- time.sleep(5)
-
- ad_callee.log.info("Step 1: Enable/disable VoLTE and WFC.")
- for sub_id, volte in zip([slot_0_subid, slot_1_subid], enable_volte):
- if not toggle_volte_for_subscription(
- self.log,
- ad_callee,
- new_state=volte,
- sub_id=sub_id):
- return False
-
- for sub_id, wfc, mode in \
- zip([slot_0_subid, slot_1_subid], enable_wfc, wfc_mode):
- if not toggle_wfc_for_subscription(
- self.log,
- ad_callee,
- new_state=wfc,
- sub_id=sub_id):
- return False
- if not set_wfc_mode_for_subscription(ad_callee, mode, sub_id=sub_id):
- return False
-
- ad_callee.log.info("Step 2: Switch DDS.")
- if dds_slot:
- if not set_dds_on_slot_1(ad_callee):
- ad_callee.log.warning(
- "Failed to set DDS at eSIM on %s", ad_callee.serial)
- return
- else:
- if not set_dds_on_slot_0(ad_callee):
- ad_callee.log.warning(
- "Failed to set DDS at pSIM on %s", ad_callee.serial)
- return
-
- ad_callee.log.info("Step 3: Check HTTP connection after DDS switch.")
- if not verify_http_connection(self.log, ad_callee):
- ad_callee.log.error("Failed to verify http connection.")
- return False
- else:
- ad_callee.log.info("Verify http connection successfully.")
-
- is_callee_in_call = is_phone_in_call_on_rat(
- self.log, ad_callee, callee_rat[callee_slot], only_return_fn=True)
-
- is_call_waiting = re.search(
- "call_waiting (True (\d)|False)", call_forwarding_type, re.I)
- if is_call_waiting:
- if is_call_waiting.group(1) == "False":
- call_waiting = False
- scenario = None
- else:
- call_waiting = True
- scenario = int(is_call_waiting.group(2))
-
- self.log.info(
- "Step 4: Make voice call with call waiting enabled = %s.",
- call_waiting)
-
- result = three_phone_call_waiting_short_seq(
- self.log,
- ad_callee,
- None,
- is_callee_in_call,
- ad_caller,
- ad_forwarded_callee,
- call_waiting=call_waiting,
- scenario=scenario)
- else:
- self.log.info(
- "Step 4: Make voice call with call forwarding %s.",
- call_forwarding_type)
- result = three_phone_call_forwarding_short_seq(
- self.log,
- ad_callee,
- None,
- is_callee_in_call,
- ad_caller,
- ad_forwarded_callee,
- call_forwarding_type=call_forwarding_type)
-
- if not result:
- if is_call_waiting:
- pass
- else:
- self.log.error(
- "Failed to make MO call from %s to %s slot %s and forward"
- " to %s.",
- ad_caller.serial,
- ad_callee.serial,
- callee_slot,
- ad_forwarded_callee.serial)
- return result
-
-
- def _test_msim_volte_wfc_call_voice_conf(
- self,
- host_slot,
- dds_slot,
- host_rat=["wfc", "wfc"],
- merge=True,
- disable_cw=False,
- enable_volte=[True, True],
- enable_wfc=[True, True],
- is_airplane_mode=False,
- is_wifi_connected=False,
- wfc_mode=[WFC_MODE_CELLULAR_PREFERRED, WFC_MODE_CELLULAR_PREFERRED],
- reject_once=False):
- """Make a VoLTE/WFC conference call at specific slot with DDS at
- specific slot.
-
- Test step:
- 1. Get sub IDs of specific slots of both MO and MT devices.
- 2. Set up phones in desired RAT
- 3. Enable VoLTE/WFC.
- 4. Switch DDS to specific slot.
- 5. Check HTTP connection after DDS switch.
- 6. Make 3-way VoLTE/WFC call.
- 7. Swap calls.
- 8. Merge calls.
-
- Args:
- host_slot: Slot on the primary device to host the comference call.
- 0 or 1 (0 for pSIM or 1 for eSIM)call
- dds_slot: Preferred data slot
- host_rat: RAT for both slots of the primary devicevice
- merge: True for merging 2 calls into the conference call. False for
- not merging 2 separated call.
- disable_cw: True for disabling call waiting and False on the
- contrary.
- enable_volte: True for enabling and False for disabling VoLTE for
- each slot on the primary device
- enable_wfc: True for enabling and False for disabling WFC for
- each slot on the primary device
- is_airplane_mode: True of False for WFC setup
- wfc_mode: Cellular preferred or Wi-Fi preferred.
- reject_once: True for rejecting the 2nd call once from the 3rd
- device (Phone C) to the primary device (Phone A).
-
- Returns:
- True of False
- """
-
- ads = self.android_devices
- ad_host = ads[0]
- ad_p1 = ads[1]
- ad_p2 = ads[2]
- slot_0_subid = get_subid_from_slot_index(ad_host.log, ad_host, 0)
- slot_1_subid = get_subid_from_slot_index(ad_host.log, ad_host, 1)
-
- host_sub_id = get_subid_from_slot_index(self.log, ad_host, host_slot)
- if host_sub_id == INVALID_SUB_ID:
- ad_host.log.warning("Failed to get sub ID at slot.", host_slot)
- return
- host_other_sub_id = get_subid_from_slot_index(
- self.log, ad_host, 1-host_slot)
- set_voice_sub_id(ad_host, host_sub_id)
- ad_host.log.info(
- "Sub ID for outgoing call at slot %s: %s",
- host_slot, get_outgoing_voice_sub_id(ad_host))
-
- _, p1_sub_id, p2_sub_id = get_subid_on_same_network_of_host_ad(ads)
-
- if p1_sub_id == INVALID_SUB_ID:
- ad_p1.log.warning("Failed to get proper sub ID.")
- return
- set_voice_sub_id(ad_p1, p1_sub_id)
- ad_p1.log.info(
- "Sub ID for incoming call: %s",
- get_incoming_voice_sub_id(ad_p1))
-
- if p2_sub_id == INVALID_SUB_ID:
- ad_p2.log.warning("Failed to get proper sub ID.")
- return
- set_voice_sub_id(ad_p2, p2_sub_id)
- ad_p2.log.info(
- "Sub ID for incoming call: %s", get_incoming_voice_sub_id(ad_p2))
-
- ad_host.log.info("Step 0: Set up phones in desired RAT.")
-
- if disable_cw:
- if not set_call_waiting(self.log, ad_host, enable=0):
- return False
-
- if host_slot == 1:
- phone_setup_on_rat(
- self.log,
- ad_host,
- host_rat[0],
- host_other_sub_id,
- is_airplane_mode,
- wfc_mode[0],
- self.wifi_network_ssid,
- self.wifi_network_pass)
-
- elif host_slot == 0:
- phone_setup_on_rat(
- self.log,
- ad_host,
- host_rat[1],
- host_other_sub_id,
- is_airplane_mode,
- wfc_mode[1],
- self.wifi_network_ssid,
- self.wifi_network_pass)
-
- host_phone_setup_func = phone_setup_on_rat(
- self.log, ad_host, host_rat[host_slot], only_return_fn=True)
-
- if host_rat[host_slot].lower() == 'wfc':
- argv = (
- self.log,
- ad_host,
- host_sub_id,
- is_airplane_mode,
- wfc_mode[host_slot],
- self.wifi_network_ssid,
- self.wifi_network_pass)
- else:
- argv = (self.log, ad_host, host_sub_id)
-
- tasks = [(phone_setup_voice_general, (self.log, ad_p1)),
- (host_phone_setup_func, argv),
- (phone_setup_voice_general, (self.log, ad_p2))]
-
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- self.tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
- raise signals.TestFailure("Failed",
- extras={"fail_reason": "Phone Failed to Set Up Properly."})
-
- if is_wifi_connected:
- if not ensure_wifi_connected(
- self.log,
- ad_host,
- self.wifi_network_ssid,
- self.wifi_network_pass,
- apm=is_airplane_mode):
- return False
- time.sleep(5)
-
- ad_host.log.info("Step 1: Enable/disable VoLTE and WFC.")
- for sub_id, volte in zip([slot_0_subid, slot_1_subid], enable_volte):
- if not toggle_volte_for_subscription(
- self.log,
- ad_host,
- new_state=volte,
- sub_id=sub_id):
- return False
-
- for sub_id, wfc, mode in \
- zip([slot_0_subid, slot_1_subid], enable_wfc, wfc_mode):
- if not toggle_wfc_for_subscription(
- self.log,
- ad_host,
- new_state=wfc,
- sub_id=sub_id):
- return False
- if not set_wfc_mode_for_subscription(ad_host, mode, sub_id=sub_id):
- return False
-
- ad_host.log.info("Step 2: Switch DDS.")
- if dds_slot:
- if not set_dds_on_slot_1(ad_host):
- ad_host.log.warning(
- "Failed to set DDS at eSIM on %s", ad_host.serial)
- return
- else:
- if not set_dds_on_slot_0(ad_host):
- ad_host.log.warning(
- "Failed to set DDS at pSIM on %s", ad_host.serial)
- return
-
- ad_host.log.info("Step 3: Check HTTP connection after DDS switch.")
- if not verify_http_connection(self.log, ads[0]):
- ad_host.log.error("Failed to verify http connection.")
- return False
- else:
- ad_host.log.info("Verify http connection successfully.")
-
- self.log.info("Step 4: Make 3-way voice call.")
- is_host_in_call = is_phone_in_call_on_rat(
- self.log, ad_host, host_rat[host_slot], only_return_fn=True)
- call_ab_id = self._three_phone_call_mo_add_mt(
- [ad_host, ad_p1, ad_p2],
- [None, None, None],
- [is_host_in_call, None, None],
- reject_once=reject_once)
-
- if call_ab_id is None:
- if disable_cw:
- set_call_waiting(self.log, ad_host, enable=1)
- if str(getattr(ad_host, "exception", None)) == \
- "PhoneA call PhoneC failed.":
- ads[0].log.info("PhoneA failed to call PhoneC due to call"
- " waiting being disabled.")
- delattr(ad_host, "exception")
- return True
- self.log.error("Failed to get call_ab_id")
- return False
- else:
- if disable_cw:
- set_call_waiting(self.log, ad_host, enable=0)
- return False
-
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
- if num_active_calls(self.log, ads[0]) != 2:
- return False
- if calls[0] == call_ab_id:
- call_ac_id = calls[1]
- else:
- call_ac_id = calls[0]
-
- if call_ac_id is None:
- self.log.error("Failed to get call_ac_id")
- return False
-
- num_swaps = 2
- ad_host.log.info("Step 5: Begin Swap x%s test.", num_swaps)
- if not swap_calls(self.log, ads, call_ab_id, call_ac_id,
- num_swaps):
- ad_host.log.error("Swap test failed.")
- return False
-
- if not merge:
- result = True
- if not self._hangup_call(ads[1], "PhoneB"):
- result = False
- if not self._hangup_call(ads[2], "PhoneC"):
- result = False
- return result
- else:
- ad_host.log.info("Step 6: Merge calls.")
- if host_rat[host_slot] == "volte" or host_rat[host_slot] == "wfc":
- return self._test_ims_conference_merge_drop_second_call_from_participant(
- call_ab_id, call_ac_id)
- else:
- return self._test_wcdma_conference_merge_drop(
- call_ab_id, call_ac_id)
+ erase_call_forwarding(self.log, self.android_devices[0])
@test_tracker_info(uuid="3d328dd0-acb6-48be-9cb2-ffffb15bf2cd")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_wfc_psim_cellular_preferred_apm_on_with_volte_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_forwarding(
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
0,
callee_rat=['wfc', 'general'],
- is_airplane_mode=True)
+ is_airplane_mode=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="aac41970-4fdb-4f22-bf33-2092ce14db6e")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_wfc_psim_wifi_preferred_apm_off_with_volte_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_forwarding(
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
0,
callee_rat=['wfc', 'general'],
- wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED])
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="716a795a-529f-450a-800d-80c1dd7c0e3f")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_wfc_psim_cellular_preferred_apm_on_with_volte_on_dds_slot_1(self):
- return self._test_msim_volte_wfc_call_forwarding(
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
1,
callee_rat=['wfc', 'general'],
- is_airplane_mode=True)
+ is_airplane_mode=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="0743331b-78a4-4721-91e7-4c6b894b4b61")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_wfc_psim_wifi_preferred_apm_off_with_volte_on_dds_slot_1(self):
- return self._test_msim_volte_wfc_call_forwarding(
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
1,
callee_rat=['wfc', 'general'],
- wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED])
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="65e8192f-c8af-454e-a142-0ba95f801fb4")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_volte_psim_cellular_preferred_wifi_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_forwarding(
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
0,
callee_rat=["volte", "general"],
- is_wifi_connected=True)
+ is_wifi_connected=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="29175f3c-0f7b-4baf-8399-a37cc92acce0")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_wfc_esim_cellular_preferred_apm_on_with_volte_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_forwarding(
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
0,
callee_rat=['general', 'wfc'],
- is_airplane_mode=True)
+ is_airplane_mode=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="a652a973-7445-4b3d-83cf-7b3ff2e1b47d")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_wfc_esim_wifi_preferred_apm_off_with_volte_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_forwarding(
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
0,
callee_rat=['general', 'wfc'],
- wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED])
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="8ff9bc8f-8740-4198-b437-19994f07758b")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_wfc_esim_cellular_preferred_apm_on_with_volte_on_dds_slot_1(self):
- return self._test_msim_volte_wfc_call_forwarding(
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
1,
callee_rat=['general', 'wfc'],
- is_airplane_mode=True)
+ is_airplane_mode=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="3341cfec-4720-4c20-97c2-29409c727fab")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_wfc_esim_wifi_preferred_apm_off_with_volte_on_dds_slot_1(self):
- return self._test_msim_volte_wfc_call_forwarding(
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
1,
callee_rat=['general', 'wfc'],
- wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED])
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="7cfea32a-6de2-4285-99b1-1219efaf542b")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_forwarding_unconditional_volte_esim_cellular_preferred_wifi_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_forwarding(
+ return msim_volte_wfc_call_forwarding(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
0,
callee_rat=["general", "volte"],
- is_wifi_connected=True)
+ is_wifi_connected=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="27422851-620c-4009-8e2a-730a97d88cb0")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_waiting_hold_swap_wfc_psim_cellular_preferred_apm_on_with_volte_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
0,
host_rat=['wfc', 'general'],
merge=False,
is_airplane_mode=True,
- reject_once=True)
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="f741f336-7eee-473e-b68f-c3505dbab935")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_waiting_hold_swap_wfc_psim_wifi_preferred_apm_off_with_volte_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
0,
host_rat=['wfc', 'general'],
merge=False,
wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
- reject_once=True)
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="4c2c9896-1cfd-4d4c-9594-97c600ac3f50")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_waiting_hold_swap_wfc_psim_cellular_preferred_apm_on_with_volte_on_dds_slot_1(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
1,
host_rat=['wfc', 'general'],
merge=False,
is_airplane_mode=True,
- reject_once=True)
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="74491391-8ea5-4bad-868b-332218a8b015")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_waiting_hold_swap_wfc_psim_wifi_preferred_apm_off_with_volte_on_dds_slot_1(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
1,
host_rat=['wfc', 'general'],
merge=False,
wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
- reject_once=True)
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="40185d6d-e127-4696-9ed8-53dbe355b1c3")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_waiting_hold_swap_volte_psim_cellular_preferred_wifi_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
0,
host_rat=["volte", "general"],
merge=False,
is_airplane_mode=False,
is_wifi_connected=True,
- reject_once=True)
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="b07a6693-3d1c-496a-b2fc-90711b2bf4f6")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_waiting_hold_swap_wfc_esim_cellular_preferred_apm_on_with_volte_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
0,
host_rat=['general', 'wfc'],
merge=False,
is_airplane_mode=True,
- reject_once=True)
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="c4461963-5d99-4c6a-b2f6-92de2437e0e7")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_waiting_hold_swap_wfc_esim_wifi_preferred_apm_off_with_volte_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
0,
host_rat=['general', 'wfc'],
merge=False,
wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
- reject_once=True)
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="cece707d-fa13-4748-a777-873eaaa27bca")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_waiting_hold_swap_wfc_esim_cellular_preferred_apm_on_with_volte_on_dds_slot_1(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
1,
host_rat=['general', 'wfc'],
merge=False,
is_airplane_mode=True,
- reject_once=True)
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="bae04c51-99eb-43a5-9f30-f16ac369bb71")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_waiting_hold_swap_wfc_esim_wifi_preferred_apm_off_with_volte_on_dds_slot_1(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
1,
host_rat=['general', 'wfc'],
merge=False,
wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
- reject_once=True)
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="c1d2c088-8782-45cd-b320-effecf6838b4")
@TelephonyBaseTest.tel_test_wrap
def test_msim_call_waiting_hold_swap_volte_esim_cellular_preferred_wifi_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
0,
host_rat=["general", "volte"],
merge=False,
is_airplane_mode=False,
is_wifi_connected=True,
- reject_once=True)
+ reject_once=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="bb4119c9-f5bc-4ef1-acbd-e8f4099f2ba9")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_conf_call_wfc_psim_cellular_preferred_apm_on_with_volte_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
0,
host_rat=['wfc', 'general'],
- is_airplane_mode=True)
+ is_airplane_mode=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="2e48ad65-bfa9-43d3-aa3a-62f412d931cc")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_conf_call_wfc_psim_wifi_preferred_apm_off_with_volte_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
0,
host_rat=['wfc', 'general'],
- wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED])
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="39a9c791-16d0-4476-94e9-fc04e9f5f65a")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_conf_call_wfc_psim_cellular_preferred_apm_on_with_volte_on_dds_slot_1(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
1,
host_rat=['wfc', 'general'],
- is_airplane_mode=True)
+ is_airplane_mode=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="daba5874-0aaa-4f47-9548-e484dd72a8c6")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_conf_call_wfc_psim_wifi_preferred_apm_off_with_volte_on_dds_slot_1(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
1,
host_rat=['wfc', 'general'],
- wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED])
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="ef96a46b-8898-4d5e-a494-31b8047fc986")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_conf_call_volte_psim_cellular_preferred_wifi_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
0,
0,
host_rat=["volte", "general"],
- is_wifi_connected=True)
+ is_wifi_connected=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="c565b2af-512c-4097-a4f7-7d920ea78373")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_conf_call_wfc_esim_cellular_preferred_apm_on_with_volte_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
0,
- host_rat=['general', 'wfc'], is_airplane_mode=True)
+ host_rat=['general', 'wfc'],
+ is_airplane_mode=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="078db8f5-eaf9-409c-878b-70c13be18802")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_conf_call_wfc_esim_wifi_preferred_apm_off_with_volte_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
0,
host_rat=['general', 'wfc'],
- wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED])
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="77c70690-6206-43a5-9789-e9ff39235d42")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_conf_call_wfc_esim_cellular_preferred_apm_on_with_volte_on_dds_slot_1(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
1,
- host_rat=['general', 'wfc'], is_airplane_mode=True)
+ host_rat=['general', 'wfc'],
+ is_airplane_mode=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="b48138dd-5c03-4592-a96d-f63833456197")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_conf_call_wfc_esim_wifi_preferred_apm_off_with_volte_on_dds_slot_1(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
1,
host_rat=['general', 'wfc'],
- wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED])
+ wfc_mode=[WFC_MODE_WIFI_PREFERRED, WFC_MODE_WIFI_PREFERRED],
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
@test_tracker_info(uuid="c2e3ff0e-6112-4b79-92e2-2fabeaf87b1f")
@TelephonyBaseTest.tel_test_wrap
def test_msim_voice_conf_call_volte_esim_cellular_preferred_wifi_on_dds_slot_0(self):
- return self._test_msim_volte_wfc_call_voice_conf(
+ return msim_volte_wfc_call_voice_conf(
+ self.log,
+ self.tel_logger,
+ self.android_devices,
1,
0,
host_rat=["general", "volte"],
- is_wifi_connected=True)
\ No newline at end of file
+ is_wifi_connected=True,
+ wifi_network_ssid=self.wifi_network_ssid,
+ wifi_network_pass=self.wifi_network_pass)
\ No newline at end of file
diff --git a/acts_tests/tests/google/tel/live/TelLiveImsSettingsTest.py b/acts_tests/tests/google/tel/live/TelLiveImsSettingsTest.py
index 0e78f40..23b2e0c 100644
--- a/acts_tests/tests/google/tel/live/TelLiveImsSettingsTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveImsSettingsTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3.4
#
-# Copyright 2018 - Google
+# Copyright 2021 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -34,31 +34,30 @@
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.tel.tel_bootloader_utils import fastboot_wipe
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_wifi_data_connection
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_ims_registered
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_enabled
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_network_rat
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_not_network_rat
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
from acts_contrib.test_utils.tel.tel_test_utils import dumpsys_carrier_config
-from acts_contrib.test_utils.tel.tel_test_utils import fastboot_wipe
from acts_contrib.test_utils.tel.tel_test_utils import is_droid_in_rat_family
from acts_contrib.test_utils.tel.tel_test_utils import revert_default_telephony_setting
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_wfc
from acts_contrib.test_utils.tel.tel_test_utils import verify_default_telephony_setting
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_ims_registered
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_not_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wfc_enabled
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wifi_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_reset
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_toggle_state
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_SSID_KEY
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_PWD_KEY
-from acts_contrib.test_utils.tel.tel_ims_utils import change_ims_setting
-from acts_contrib.test_utils.tel.tel_ims_utils import verify_default_ims_setting
+from acts_contrib.test_utils.tel.tel_voice_utils import change_ims_setting
+from acts_contrib.test_utils.tel.tel_voice_utils import verify_default_ims_setting
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_SSID_KEY
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_PWD_KEY
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_reset
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
class TelLiveImsSettingsTest(TelephonyBaseTest):
diff --git a/acts_tests/tests/google/tel/live/TelLiveLockedSimTest.py b/acts_tests/tests/google/tel/live/TelLiveLockedSimTest.py
index 83c192a..fd4418b 100644
--- a/acts_tests/tests/google/tel/live/TelLiveLockedSimTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveLockedSimTest.py
@@ -26,18 +26,17 @@
from acts_contrib.test_utils.tel.tel_defines import GEN_3G
from acts_contrib.test_utils.tel.tel_defines import GEN_4G
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
-from acts_contrib.test_utils.tel.tel_lookup_tables import \
- network_preference_for_generation
+from acts_contrib.test_utils.tel.tel_bootloader_utils import fastboot_wipe
+from acts_contrib.test_utils.tel.tel_bootloader_utils import reset_device_password
+from acts_contrib.test_utils.tel.tel_lookup_tables import network_preference_for_generation
from acts_contrib.test_utils.tel.tel_lookup_tables import operator_capabilities
-from acts_contrib.test_utils.tel.tel_test_utils import fastboot_wipe
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
from acts_contrib.test_utils.tel.tel_test_utils import get_sim_state
from acts_contrib.test_utils.tel.tel_test_utils import is_sim_lock_enabled
from acts_contrib.test_utils.tel.tel_test_utils import is_sim_locked
from acts_contrib.test_utils.tel.tel_test_utils import reboot_device
-from acts_contrib.test_utils.tel.tel_test_utils import reset_device_password
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
from acts_contrib.test_utils.tel.tel_test_utils import unlock_sim
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
from TelLiveEmergencyBase import TelLiveEmergencyBase
EXPECTED_CALL_TEST_RESULT = False
diff --git a/acts_tests/tests/google/tel/live/TelLiveMobilityStressTest.py b/acts_tests/tests/google/tel/live/TelLiveMobilityStressTest.py
index 0319763..b608584 100644
--- a/acts_tests/tests/google/tel/live/TelLiveMobilityStressTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveMobilityStressTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3.4
#
-# Copyright 2017 - Google
+# Copyright 2022 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -26,42 +26,21 @@
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_atten_utils import set_rssi
from acts_contrib.test_utils.tel.tel_defines import CELL_WEAK_RSSI_VALUE
-from acts_contrib.test_utils.tel.tel_defines import CELL_STRONG_RSSI_VALUE
from acts_contrib.test_utils.tel.tel_defines import MAX_RSSI_RESERVED_VALUE
from acts_contrib.test_utils.tel.tel_defines import MIN_RSSI_RESERVED_VALUE
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
-from acts_contrib.test_utils.tel.tel_defines import WIFI_WEAK_RSSI_VALUE
-from acts_contrib.test_utils.tel.tel_test_utils import active_file_download_test
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_default_state
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import is_voice_attached
-from acts_contrib.test_utils.tel.tel_test_utils import run_multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
-from acts_contrib.test_utils.tel.tel_test_utils import sms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
-from acts_contrib.test_utils.tel.tel_test_utils import mms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_message_utils import mms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_test
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
from acts_contrib.test_utils.tel.tel_voice_utils import get_current_voice_rat
-
-from acts.logger import epoch_to_log_line_timestamp
from acts.utils import get_current_epoch_time
from acts.utils import rand_ascii_str
+from acts.libs.utils.multithread import run_multithread_func
from TelWifiVoiceTest import TelWifiVoiceTest
from TelWifiVoiceTest import ATTEN_NAME_FOR_WIFI_2G
@@ -69,13 +48,11 @@
from TelWifiVoiceTest import ATTEN_NAME_FOR_CELL_3G
from TelWifiVoiceTest import ATTEN_NAME_FOR_CELL_4G
-import socket
from acts.controllers.sl4a_lib.rpc_client import Sl4aProtocolError
IGNORE_EXCEPTIONS = (BrokenPipeError, Sl4aProtocolError)
EXCEPTION_TOLERANCE = 20
-
class TelLiveMobilityStressTest(TelWifiVoiceTest):
def setup_class(self):
super().setup_class()
diff --git a/acts_tests/tests/google/tel/live/TelLiveNoQXDMLogTest.py b/acts_tests/tests/google/tel/live/TelLiveNoQXDMLogTest.py
index 3bafb61..c51b779 100644
--- a/acts_tests/tests/google/tel/live/TelLiveNoQXDMLogTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveNoQXDMLogTest.py
@@ -43,8 +43,11 @@
from acts_contrib.test_utils.tel.tel_defines import CARRIER_ID_METADATA_URL_P
from acts_contrib.test_utils.tel.tel_defines import CARRIER_ID_CONTENT_URL_P
from acts_contrib.test_utils.tel.tel_defines import CARRIER_ID_VERSION_P
+from acts_contrib.test_utils.tel.tel_bootloader_utils import fastboot_wipe
from acts_contrib.test_utils.tel.tel_lookup_tables import device_capabilities
from acts_contrib.test_utils.tel.tel_lookup_tables import operator_capabilities
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_cbrs_and_default_sub_id
from acts_contrib.test_utils.tel.tel_test_utils import lock_lte_band_by_mds
from acts_contrib.test_utils.tel.tel_test_utils import get_model_name
from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
@@ -52,7 +55,6 @@
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
from acts_contrib.test_utils.tel.tel_test_utils import trigger_modem_crash_by_modem
from acts_contrib.test_utils.tel.tel_test_utils import bring_up_sl4a
-from acts_contrib.test_utils.tel.tel_test_utils import fastboot_wipe
from acts_contrib.test_utils.tel.tel_test_utils import get_carrier_config_version
from acts_contrib.test_utils.tel.tel_test_utils import get_carrier_id_version
from acts_contrib.test_utils.tel.tel_test_utils import get_er_db_id_version
@@ -61,15 +63,14 @@
from acts_contrib.test_utils.tel.tel_test_utils import add_whitelisted_account
from acts_contrib.test_utils.tel.tel_test_utils import adb_disable_verity
from acts_contrib.test_utils.tel.tel_test_utils import install_carriersettings_apk
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
from acts_contrib.test_utils.tel.tel_test_utils import cleanup_configupdater
from acts_contrib.test_utils.tel.tel_test_utils import pull_carrier_id_files
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_toggle_state
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_subscription_utils import get_cbrs_and_default_sub_id
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
from acts.utils import get_current_epoch_time
from acts.keys import Config
+
class TelLiveNoQXDMLogTest(TelephonyBaseTest):
def setup_class(self):
super().setup_class()
diff --git a/acts_tests/tests/google/tel/live/TelLiveNoSimTest.py b/acts_tests/tests/google/tel/live/TelLiveNoSimTest.py
index 9e4cc07..60bd7ac 100644
--- a/acts_tests/tests/google/tel/live/TelLiveNoSimTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveNoSimTest.py
@@ -26,11 +26,10 @@
from acts_contrib.test_utils.tel.tel_defines import GEN_4G
from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_ABSENT
from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_UNKNOWN
-from acts_contrib.test_utils.tel.tel_test_utils import fastboot_wipe
+from acts_contrib.test_utils.tel.tel_bootloader_utils import fastboot_wipe
+from acts_contrib.test_utils.tel.tel_bootloader_utils import reset_device_password
+from acts_contrib.test_utils.tel.tel_lookup_tables import network_preference_for_generation
from acts_contrib.test_utils.tel.tel_test_utils import get_sim_state
-from acts_contrib.test_utils.tel.tel_lookup_tables import \
- network_preference_for_generation
-from acts_contrib.test_utils.tel.tel_test_utils import reset_device_password
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
from TelLiveEmergencyBase import TelLiveEmergencyBase
diff --git a/acts_tests/tests/google/tel/live/TelLivePreflightTest.py b/acts_tests/tests/google/tel/live/TelLivePreflightTest.py
index 134255e..17dd7f6 100644
--- a/acts_tests/tests/google/tel/live/TelLivePreflightTest.py
+++ b/acts_tests/tests/google/tel/live/TelLivePreflightTest.py
@@ -23,29 +23,29 @@
from acts.controllers.android_device import get_info
from acts.libs.ota import ota_updater
from acts.test_decorators import test_tracker_info
+from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_WLAN
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_wifi_data_connection
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_enabled
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_default_state
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan_cellular_preferred
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_network_rat
from acts_contrib.test_utils.tel.tel_test_utils import abort_all_tests
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_default_state
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
from acts_contrib.test_utils.tel.tel_test_utils import get_user_config_profile
from acts_contrib.test_utils.tel.tel_test_utils import is_sim_locked
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
from acts_contrib.test_utils.tel.tel_test_utils import unlock_sim
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wfc_enabled
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wifi_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_toggle_state
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan_cellular_preferred
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
class TelLivePreflightTest(TelephonyBaseTest):
diff --git a/acts_tests/tests/google/tel/live/TelLiveProjectFiTest.py b/acts_tests/tests/google/tel/live/TelLiveProjectFiTest.py
index 5bf765e..950b0fc 100644
--- a/acts_tests/tests/google/tel/live/TelLiveProjectFiTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveProjectFiTest.py
@@ -20,17 +20,16 @@
import time
from acts.test_decorators import test_tracker_info
+from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import CARRIER_SPT
from acts_contrib.test_utils.tel.tel_defines import CARRIER_TMO
from acts_contrib.test_utils.tel.tel_defines import CARRIER_USCC
+from acts_contrib.test_utils.tel.tel_logging_utils import log_screen_shot
from acts_contrib.test_utils.tel.tel_lookup_tables import operator_name_from_plmn_id
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_subscription
from acts_contrib.test_utils.tel.tel_test_utils import abort_all_tests
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
from acts_contrib.test_utils.tel.tel_test_utils import is_sim_ready
-from acts_contrib.test_utils.tel.tel_test_utils import log_screen_shot
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
from acts_contrib.test_utils.tel.tel_test_utils import reboot_device
from acts_contrib.test_utils.tel.tel_test_utils import refresh_droid_config
from acts_contrib.test_utils.tel.tel_test_utils import send_dialer_secret_code
@@ -38,6 +37,7 @@
from acts_contrib.test_utils.tel.tel_test_utils import wait_for_state
from acts_contrib.test_utils.tel.tel_test_utils import add_google_account
from acts_contrib.test_utils.tel.tel_test_utils import remove_google_account
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
CARRIER_AUTO = "auto"
diff --git a/acts_tests/tests/google/tel/live/TelLiveRcsTest.py b/acts_tests/tests/google/tel/live/TelLiveRcsTest.py
new file mode 100644
index 0000000..fab619c
--- /dev/null
+++ b/acts_tests/tests/google/tel/live/TelLiveRcsTest.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python3.4
+#
+# Copyright 2016 - Google
+#
+# 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.
+"""
+ Test Script for RCS.
+"""
+from time import sleep
+
+from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+
+
+class TelLiveRcsTest(TelephonyBaseTest):
+ def setup_class(self):
+ super().setup_class()
+
+ def setup_test(self):
+ TelephonyBaseTest.setup_test(self)
+
+ def teardown_class(self):
+ TelephonyBaseTest.teardown_class(self)
+
+ def test_verify_provisioning(self):
+ ad = self.android_devices[0]
+ ad.log.info("Start RCS provisioning")
+ ad.droid.startRCSProvisioning("UP_1.0", "6.0", "Goog", "RCSAndrd-1.0")
+ sleep(20)
+ isRcsVolteSingleRegistrationCapable = ad.droid.isRcsVolteSingleRegistrationCapable()
+ configXml = ad.droid.getRCSConfigXml()
+ ad.log.info("isRcsVolteSingleRegistrationCapable: %r", isRcsVolteSingleRegistrationCapable)
+ ad.log.info("RCS Config XML: %s", configXml)
+ result = configXml.find("<parm name=\"rcsVolteSingleRegistration\" value=\"1\"/>")
+ return result != -1
+
+ def test_is_single_reg_capable(self, ad):
+ """ Test single registration provisioning.
+
+ """
+
+ return ad.droid.isRcsVolteSingleRegistrationCapable()
+
+ def test_unregister(self):
+ ad = self.android_devices[0]
+ return ad.droid.unregister()
+
diff --git a/acts_tests/tests/google/tel/live/TelLiveRebootStressTest.py b/acts_tests/tests/google/tel/live/TelLiveRebootStressTest.py
index 4d90bdb..2071ef7 100644
--- a/acts_tests/tests/google/tel/live/TelLiveRebootStressTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveRebootStressTest.py
@@ -39,42 +39,40 @@
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_subscription
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_wifi_data_connection
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_message_utils import mms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_enabled
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_subid
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_network_generation
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_network_rat
from acts_contrib.test_utils.tel.tel_test_utils import get_model_name
from acts_contrib.test_utils.tel.tel_test_utils import get_outgoing_voice_sub_id
-from acts_contrib.test_utils.tel.tel_test_utils import get_slot_index_from_subid
from acts_contrib.test_utils.tel.tel_test_utils import is_droid_in_network_generation
from acts_contrib.test_utils.tel.tel_test_utils import is_sim_locked
-from acts_contrib.test_utils.tel.tel_test_utils import mms_send_receive_verify
from acts_contrib.test_utils.tel.tel_test_utils import power_off_sim
from acts_contrib.test_utils.tel.tel_test_utils import power_on_sim
from acts_contrib.test_utils.tel.tel_test_utils import reboot_device
-from acts_contrib.test_utils.tel.tel_test_utils import sms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
from acts_contrib.test_utils.tel.tel_test_utils import trigger_modem_crash
from acts_contrib.test_utils.tel.tel_test_utils import trigger_modem_crash_by_modem
from acts_contrib.test_utils.tel.tel_test_utils import unlock_sim
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wfc_enabled
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_cell_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_generation
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wifi_data_connection
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
from acts_contrib.test_utils.tel.tel_test_utils import wait_for_state
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
from acts_contrib.test_utils.tel.tel_video_utils import video_call_setup_teardown
from acts_contrib.test_utils.tel.tel_video_utils import phone_setup_video
-from acts_contrib.test_utils.tel.tel_video_utils import \
- is_phone_in_call_video_bidirectional
+from acts_contrib.test_utils.tel.tel_video_utils import is_phone_in_call_video_bidirectional
from acts.utils import get_current_epoch_time
from acts.utils import rand_ascii_str
@@ -577,7 +575,7 @@
self.dut.log.info("======== Power cycle SIM slot ========")
self.user_params["check_crash"] = True
sub_id = get_outgoing_voice_sub_id(self.dut)
- slot_index = get_slot_index_from_subid(self.log, self.dut, sub_id)
+ slot_index = get_slot_index_from_subid(self.dut, sub_id)
if not power_off_sim(self.dut, slot_index):
self.dut.log.warning("Fail to power off SIM")
raise signals.TestSkip("Power cycle SIM not working")
diff --git a/acts_tests/tests/google/tel/live/TelLiveRilDataKpiTest.py b/acts_tests/tests/google/tel/live/TelLiveRilDataKpiTest.py
new file mode 100644
index 0000000..ce6e6fa
--- /dev/null
+++ b/acts_tests/tests/google/tel/live/TelLiveRilDataKpiTest.py
@@ -0,0 +1,388 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - Google
+#
+# 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 datetime import datetime, timedelta
+
+from acts import signals
+from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.tel.tel_data_utils import activate_and_verify_cellular_data
+from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_test
+from acts_contrib.test_utils.tel.tel_data_utils import deactivate_and_verify_cellular_data
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_wfc
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_enabled
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_disabled
+from acts_contrib.test_utils.tel.tel_parse_utils import print_nested_dict
+from acts_contrib.test_utils.tel.tel_parse_utils import parse_setup_data_call
+from acts_contrib.test_utils.tel.tel_parse_utils import parse_deactivate_data_call
+from acts_contrib.test_utils.tel.tel_parse_utils import parse_setup_data_call_on_iwlan
+from acts_contrib.test_utils.tel.tel_parse_utils import parse_deactivate_data_call_on_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_4g_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_0
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_1
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_data_sub_id
+from acts.utils import get_current_epoch_time
+from acts.libs.utils.multithread import multithread_func
+
+CALCULATE_EVERY_N_CYCLES = 10
+
+
+class TelLiveRilDataKpiTest(TelephonyBaseTest):
+ def setup_class(self):
+ TelephonyBaseTest.setup_class(self)
+ self.cycle_cellular_data_cycle = self.user_params.get(
+ "cycle_cellular_data_cycle", 1)
+ self.cycle_wfc_cycle = self.user_params.get("cycle_wfc_cycle", 1)
+ self.dds_switch_test_cycle = self.user_params.get(
+ "dds_switch_test_cycle", 1)
+ self.http_download_duration = self.user_params.get(
+ "http_download_duration", 3600)
+
+ def cycle_cellular_data(self, ad):
+ """ Toggle off and then toggle on again cellular data.
+
+ Args:
+ ad: Android object
+
+ Returns:
+ True if cellular data is cycled successfully. Otherwise False.
+ """
+ if not deactivate_and_verify_cellular_data(self.log, ad):
+ return False
+
+ if not activate_and_verify_cellular_data(self.log, ad):
+ return False
+
+ return True
+
+ def cycle_wfc(self, ad):
+ """ Toggle off and then toggle on again WFC.
+
+ Args:
+ ad: Android object
+
+ Returns:
+ True if WFC is cycled successfully. Otherwise False.
+ """
+ if not toggle_wfc(self.log, ad, new_state=False):
+ return False
+
+ if not wait_for_wfc_disabled(self.log, ad):
+ return False
+
+ if not toggle_wfc(self.log, ad, new_state=True):
+ return False
+
+ if not wait_for_wfc_enabled(self.log, ad):
+ return False
+
+ return True
+
+ def switch_dds(self, ad):
+ """Switch DDS to the other sub ID.
+
+ Args:
+ ad: Android object
+
+ Returns:
+ True if DDS is switched successfully. Otherwise False.
+ """
+ current_dds_slot = get_slot_index_from_data_sub_id(ad)
+
+ if current_dds_slot == 0:
+ if set_dds_on_slot_1(ad):
+ return True
+ else:
+ if set_dds_on_slot_0(ad):
+ return True
+
+ return False
+
+ @test_tracker_info(uuid="27424b59-efa9-47c3-89b4-4b5415003a58")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_cycle_cellular_data_4g(self):
+ """Cycle cellular data on LTE to measure data call setup time,
+ deactivate time and LTE validation time.
+
+ Test steps:
+ 1. Set up UE on LTE and ensure cellular data is connected.
+ 2. Cycle cellular data.
+ 3. Parse logcat to calculate data call setup time, deactivate time
+ and LTE validation time.
+ """
+ ad = self.android_devices[0]
+
+ cycle = self.cycle_cellular_data_cycle
+
+ tasks = [(
+ phone_setup_4g_for_subscription,
+ (self.log, ad, get_default_data_sub_id(ad)))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+
+ cycle_cellular_data_summary = []
+ for attempt in range(cycle):
+ ad.log.info(
+ '======> Cycling cellular data %s/%s <======',
+ attempt+1, cycle)
+ res = self.cycle_cellular_data(ad)
+ cycle_cellular_data_summary.append(res)
+ if not res:
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+
+ if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or attempt == cycle - 1:
+ (
+ res,
+ lst,
+ avg_data_call_setup_time,
+ avg_validation_time_on_lte) = parse_setup_data_call(ad)
+
+ ad.log.info('====== Setup data call list ======')
+ print_nested_dict(ad, res)
+
+ ad.log.info('====== Data call setup time list ======')
+ for item in lst:
+ print_nested_dict(ad, item)
+ ad.log.info('------------------')
+
+ (
+ res,
+ lst,
+ avg_deactivate_data_call_time) = parse_deactivate_data_call(ad)
+
+ ad.log.info('====== Deactivate data call list ======')
+ print_nested_dict(ad, res)
+
+ ad.log.info('====== Data call deactivate time list ======')
+ for item in lst:
+ print_nested_dict(ad, item)
+ ad.log.info('------------------')
+
+ ad.log.info(
+ 'Average data call setup time on LTE: %.2f sec.',
+ avg_data_call_setup_time)
+ ad.log.info(
+ 'Average validation time on LTE: %.2f sec.',
+ avg_validation_time_on_lte)
+ ad.log.info(
+ 'Average deactivate data call time on LTE: %.2f sec.',
+ avg_deactivate_data_call_time)
+
+ try:
+ fail_rate = cycle_cellular_data_summary.count(False)/len(
+ cycle_cellular_data_summary)
+ self.log.info(
+ 'Fail rate of cycling cellular data on LTE: %s/%s (%.2f)',
+ cycle_cellular_data_summary.count(False),
+ len(cycle_cellular_data_summary),
+ fail_rate)
+ except Exception as e:
+ self.log.error(
+ 'Fail rate of cycling cellular data on LTE: ERROR (%s)',
+ e)
+
+ @test_tracker_info(uuid="9f4ab929-176d-4f26-8e14-12bd6c25e80a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_cycle_wfc(self):
+ """Cycle WFC to measure data call setup time and deactivate time on
+ iwlan.
+
+ Test steps:
+ 1. Set up UE on iwlan and ensure WFC is registered in Wi-Fi-preferred
+ mode.
+ 2. Cycle WFC.
+ 3. Parse logcat to calculate data call setup time and deactivate time
+ on iwlan.
+ """
+ ad = self.android_devices[0]
+
+ cycle = self.cycle_wfc_cycle
+
+ tasks = [(phone_setup_iwlan, (
+ self.log,
+ ad,
+ False,
+ WFC_MODE_WIFI_PREFERRED,
+ self.wifi_network_ssid,
+ self.wifi_network_pass))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+
+ cycle_wfc_summary = []
+ for attempt in range(cycle):
+ ad.log.info(
+ '==================> Cycling WFC %s/%s <==================',
+ attempt+1, cycle)
+ res = self.cycle_wfc(ad)
+ cycle_wfc_summary.append(res)
+ if not res:
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+
+ if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or attempt == cycle - 1:
+ (
+ res,
+ lst,
+ avg_data_call_setup_time) = parse_setup_data_call_on_iwlan(ad)
+
+ ad.log.info('====== Setup data call list ======')
+ print_nested_dict(ad, res)
+
+ ad.log.info('====== Data call setup time list ======')
+ for item in lst:
+ print_nested_dict(ad, item)
+ ad.log.info('------------------')
+
+ (
+ res,
+ lst,
+ avg_deactivate_data_call_time) = parse_deactivate_data_call_on_iwlan(ad)
+
+ ad.log.info('====== Deactivate data call list ======')
+ print_nested_dict(ad, res)
+
+ ad.log.info('====== Data call deactivate time list ======')
+ for item in lst:
+ print_nested_dict(ad, item)
+ ad.log.info('------------------')
+
+ ad.log.info(
+ 'Average WFC data call setup time: %.2f sec.',
+ avg_data_call_setup_time)
+ ad.log.info(
+ 'Average WFC deactivate data call time: %.2f sec.',
+ avg_deactivate_data_call_time)
+
+ try:
+ fail_rate = cycle_wfc_summary.count(False)/len(
+ cycle_wfc_summary)
+ self.log.info(
+ 'Fail rate of cycling WFC: %s/%s (%.2f)',
+ cycle_wfc_summary.count(False),
+ len(cycle_wfc_summary),
+ fail_rate)
+ except Exception as e:
+ self.log.error('Fail rate of cycling WFC: ERROR (%s)', e)
+
+ @test_tracker_info(uuid="77388597-d764-4db3-be6f-656e56dc253a")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_dds_switch(self):
+ """ Switch DDS to measure DDS switch time and LTE validation time.
+
+ Test steps:
+ 1. Switch DDS.
+ 2. Parse logcat to calculate DDS switch time and LTE validation time.
+ """
+ ad = self.android_devices[0]
+ cycle = self.dds_switch_test_cycle
+
+ if not getattr(ad, 'dsds', False):
+ raise signals.TestSkip("UE is in single mode. Test will be skipped.")
+
+ dds_switch_summary = []
+ for attempt in range(cycle):
+ self.log.info(
+ '======> DDS switch on LTE %s/%s <======',
+ attempt+1,
+ cycle)
+ if self.switch_dds(ad):
+ dds_switch_summary.append(True)
+ else:
+ dds_switch_summary.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+
+ if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or attempt == cycle - 1:
+ (
+ res,
+ lst,
+ avg_data_call_setup_time,
+ avg_validation_time_on_lte) = parse_setup_data_call(
+ ad, dds_switch=True)
+
+ ad.log.info('====== Setup data call list ======')
+ print_nested_dict(ad, res)
+
+ ad.log.info('====== Data call setup time list ======')
+ for item in lst:
+ print_nested_dict(ad, item)
+ ad.log.info('------------------')
+
+ try:
+ ad.log.info(
+ 'Average data call setup time on LTE: %.2f sec.',
+ avg_data_call_setup_time)
+ except Exception as e:
+ ad.log.error(
+ 'Average data call setup time on LTE: ERROR (%s)', e)
+
+ try:
+ ad.log.info(
+ 'Average validation time on LTE: %.2f sec.',
+ avg_validation_time_on_lte)
+ except Exception as e:
+ ad.log.error('Average validation tim on LTE: ERROR (%s)', e)
+
+ try:
+ fail_rate = dds_switch_summary.count(False)/len(dds_switch_summary)
+ self.log.info(
+ 'Fail rate of cycling cellular data on LTE: %s/%s (%.2f)',
+ dds_switch_summary.count(False),
+ len(dds_switch_summary),
+ fail_rate)
+ except Exception as e:
+ self.log.error(
+ 'Fail rate of cycling cellular data on LTE: ERROR (%s)',
+ e)
+
+ @test_tracker_info(uuid="ac0b6541-d900-4413-8ccb-839ae998804e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_http_download(self, method='sl4a'):
+ """HTTP download large file for a long time to ensure there is no issue
+ related to the stability.
+
+ Test steps:
+ 1. HTTP download a large file (e.g., 512MB) for a long time
+
+ Returns:
+ False if the download is interrupted. Otherwise True.
+ """
+ ad = self.android_devices[0]
+
+ duration = self.http_download_duration
+
+ start_time = datetime.now()
+
+ result = True
+ while datetime.now() - start_time <= timedelta(seconds=duration):
+ if not active_file_download_test(
+ self.log, ad, file_name='512MB', method=method):
+ result = False
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ return result
\ No newline at end of file
diff --git a/acts_tests/tests/google/tel/live/TelLiveRilImsKpiTest.py b/acts_tests/tests/google/tel/live/TelLiveRilImsKpiTest.py
new file mode 100644
index 0000000..f7bb1ca
--- /dev/null
+++ b/acts_tests/tests/google/tel/live/TelLiveRilImsKpiTest.py
@@ -0,0 +1,1355 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - Google
+#
+# 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 datetime import datetime
+
+from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.tel_data_utils import airplane_mode_test
+from acts_contrib.test_utils.tel.tel_data_utils import reboot_test
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_network_service
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WIFI_CONNECTION
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
+from acts_contrib.test_utils.tel.tel_logging_utils import start_pixellogger_always_on_logging
+from acts_contrib.test_utils.tel.tel_logging_utils import wait_for_log
+from acts_contrib.test_utils.tel.tel_parse_utils import print_nested_dict
+from acts_contrib.test_utils.tel.tel_parse_utils import parse_ims_reg
+from acts_contrib.test_utils.tel.tel_parse_utils import ON_IMS_MM_TEL_CONNECTED_4G_SLOT0
+from acts_contrib.test_utils.tel.tel_parse_utils import ON_IMS_MM_TEL_CONNECTED_4G_SLOT1
+from acts_contrib.test_utils.tel.tel_parse_utils import ON_IMS_MM_TEL_CONNECTED_IWLAN_SLOT0
+from acts_contrib.test_utils.tel.tel_parse_utils import ON_IMS_MM_TEL_CONNECTED_IWLAN_SLOT1
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_iwlan
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_voice_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_all_sub_id
+from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
+from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_short_seq
+from acts_contrib.test_utils.tel.tel_wifi_utils import check_is_wifi_connected
+from acts.utils import get_current_epoch_time
+
+SETUP_PHONE_FAIL = 'SETUP_PHONE_FAIL'
+VERIFY_NETWORK_FAIL = 'VERIFY_NETWORK_FAIL'
+VERIFY_INTERNET_FAIL = 'VERIFY_INTERNET_FAIL'
+TOGGLE_OFF_APM_FAIL = 'TOGGLE_OFF_APM_FAIL'
+
+CALCULATE_EVERY_N_CYCLES = 10
+
+
+def test_result(result_list, cycle, min_fail=0, failrate=0):
+ failure_count = len(list(filter(lambda x: (x != True), result_list)))
+ if failure_count >= min_fail:
+ if failure_count >= cycle * failrate:
+ return False
+ return True
+
+def wait_for_wifi_disconnected(ad, wifi_ssid):
+ """Wait until Wifi is disconnected.
+
+ Args:
+ ad: Android object
+ wifi_ssid: to specify the Wifi AP which should be disconnected.
+
+ Returns:
+ True if Wifi is disconnected before time-out. Otherwise False.
+ """
+ wait_time = 0
+ while wait_time < MAX_WAIT_TIME_WIFI_CONNECTION:
+ if check_is_wifi_connected(ad.log, ad, wifi_ssid):
+ ad.droid.wifiToggleState(False)
+ time.sleep(3)
+ wait_time = wait_time + 3
+ else:
+ ad.log.info('Wifi is disconnected.')
+ return True
+
+ if check_is_wifi_connected(ad.log, ad, wifi_ssid):
+ ad.log.error('Wifi still is connected to %s.', wifi_ssid)
+ return False
+ else:
+ ad.log.info('Wifi is disconnected.')
+ return True
+
+class TelLiveRilImsKpiTest(TelephonyBaseTest):
+ def setup_class(self):
+ TelephonyBaseTest.setup_class(self)
+ start_pixellogger_always_on_logging(self.android_devices[0])
+ self.tel_logger = TelephonyMetricLogger.for_test_case()
+ self.user_params["telephony_auto_rerun"] = 0
+ self.reboot_4g_test_cycle = self.user_params.get(
+ 'reboot_4g_test_cycle', 1)
+ self.reboot_iwlan_test_cycle = self.user_params.get(
+ 'reboot_iwlan_test_cycle', 1)
+ self.cycle_apm_4g_test_cycle = self.user_params.get(
+ 'cycle_apm_4g_test_cycle', 1)
+ self.cycle_wifi_in_apm_mode_test_cycle = self.user_params.get(
+ 'cycle_wifi_in_apm_mode_test_cycle', 1)
+ self.ims_handover_4g_to_iwlan_with_voice_call_wfc_wifi_preferred_test_cycle = self.user_params.get(
+ 'ims_handover_4g_to_iwlan_with_voice_call_wfc_wifi_preferred_test_cycle', 1)
+ self.ims_handover_4g_to_iwlan_wfc_wifi_preferred_test_cycle = self.user_params.get(
+ 'ims_handover_4g_to_iwlan_wfc_wifi_preferred_test_cycle', 1)
+ self.ims_handover_iwlan_to_4g_wfc_wifi_preferred_test_cycle = self.user_params.get(
+ 'ims_handover_iwlan_to_4g_wfc_wifi_preferred_test_cycle', 1)
+ self.ims_handover_iwlan_to_4g_with_voice_call_wfc_wifi_preferred_test_cycle = self.user_params.get(
+ 'ims_handover_iwlan_to_4g_with_voice_call_wfc_wifi_preferred_test_cycle', 1)
+ self.ims_handover_iwlan_to_4g_wfc_cellular_preferred_test_cycle = self.user_params.get(
+ 'ims_handover_iwlan_to_4g_wfc_cellular_preferred_test_cycle', 1)
+ self.ims_handover_iwlan_to_4g_with_voice_call_wfc_cellular_preferred_test_cycle = self.user_params.get(
+ 'ims_handover_iwlan_to_4g_with_voice_call_wfc_cellular_preferred_test_cycle', 1)
+
+ def teardown_test(self):
+ for ad in self.android_devices:
+ toggle_airplane_mode(self.log, ad, False)
+
+ @test_tracker_info(uuid="d6a59a3c-2bbc-4ed3-a41e-4492b4ab8a50")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_reboot_4g(self):
+ """Reboot UE and measure bootup IMS registration time on LTE.
+
+ Test steps:
+ 1. Enable VoLTE at all slots and ensure IMS is registered over LTE
+ cellular network at all slots.
+ 2. Reboot UE.
+ 3. Parse logcat to calculate IMS registration time on LTE after
+ bootup.
+ """
+ ad = self.android_devices[0]
+ cycle = self.reboot_4g_test_cycle
+ voice_slot = get_slot_index_from_voice_sub_id(ad)
+
+ if getattr(ad, 'dsds', False):
+ the_other_slot = 1 - voice_slot
+ else:
+ the_other_slot = None
+
+ result = []
+ search_intervals = []
+ exit_due_to_high_fail_rate = False
+ for attempt in range(cycle):
+ _continue = True
+ self.log.info(
+ '==================> Reboot on LTE %s/%s <==================',
+ attempt+1,
+ cycle)
+
+ sub_id_list = get_all_sub_id(ad)
+ for sub_id in sub_id_list:
+ if not phone_setup_volte_for_subscription(self.log, ad, sub_id):
+ result.append(SETUP_PHONE_FAIL)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if not wait_for_network_service(self.log, ad):
+ result.append(VERIFY_NETWORK_FAIL)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ begin_time = datetime.now()
+ if reboot_test(self.log, ad):
+ result.append(True)
+ else:
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ end_time = datetime.now()
+ search_intervals.append([begin_time, end_time])
+
+ if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or (
+ attempt == cycle - 1) or exit_due_to_high_fail_rate:
+
+ ad.log.info(
+ '====== Test result of IMS bootup registration at slot %s '
+ '======',
+ voice_slot)
+ ad.log.info(result)
+
+ for slot in [voice_slot, the_other_slot]:
+ if slot is None:
+ continue
+
+ ims_reg, parsing_fail, avg_ims_reg_duration = parse_ims_reg(
+ ad, search_intervals, '4g', 'reboot', slot=slot)
+ ad.log.info(
+ '====== IMS bootup registration at slot %s ======', slot)
+ for msg in ims_reg:
+ print_nested_dict(ad, msg)
+
+ ad.log.info(
+ '====== Attempt of parsing fail at slot %s ======' % slot)
+ for msg in parsing_fail:
+ ad.log.info(msg)
+
+ ad.log.warning('====== Summary ======')
+ ad.log.warning(
+ '%s/%s cycles failed.',
+ (len(result) - result.count(True)),
+ len(result))
+ for attempt, value in enumerate(result):
+ if value is not True:
+ ad.log.warning('Cycle %s: %s', attempt+1, value)
+ try:
+ fail_rate = (
+ len(result) - result.count(True))/len(result)
+ ad.log.info(
+ 'Fail rate of IMS bootup registration at slot %s: %s',
+ slot,
+ fail_rate)
+ except Exception as e:
+ ad.log.error(
+ 'Fail rate of IMS bootup registration at slot %s: '
+ 'ERROR (%s)',
+ slot,
+ e)
+
+ ad.log.info(
+ 'Number of trials with valid parsed logs: %s',
+ len(ims_reg))
+ ad.log.info(
+ 'Average IMS bootup registration time at slot %s: %s',
+ slot,
+ avg_ims_reg_duration)
+
+ if exit_due_to_high_fail_rate:
+ break
+
+ return test_result(result, cycle)
+
+ @test_tracker_info(uuid="c97dd2f2-9e8a-43d4-9352-b53abe5ac6a4")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_reboot_iwlan(self):
+ """Reboot UE and measure bootup IMS registration time over iwlan.
+
+ Test steps:
+ 1. Enable VoLTE at all slots; enable WFC and set WFC mode to
+ Wi-Fi-preferred mode; connect Wi-Fi and ensure IMS is registered
+ at all slots over iwlan.
+ 2. Reboot UE.
+ 3. Parse logcat to calculate IMS registration time over iwlan after
+ bootup.
+ """
+ ad = self.android_devices[0]
+ cycle = self.reboot_iwlan_test_cycle
+ voice_slot = get_slot_index_from_voice_sub_id(ad)
+
+ if getattr(ad, 'dsds', False):
+ the_other_slot = 1 - voice_slot
+ else:
+ the_other_slot = None
+
+ result = []
+ search_intervals = []
+ exit_due_to_high_fail_rate = False
+ for attempt in range(cycle):
+ _continue = True
+ self.log.info(
+ '==================> Reboot on iwlan %s/%s <==================',
+ attempt+1,
+ cycle)
+
+ sub_id_list = get_all_sub_id(ad)
+ for sub_id in sub_id_list:
+ if not phone_setup_iwlan_for_subscription(
+ self.log,
+ ad,
+ sub_id,
+ False,
+ WFC_MODE_WIFI_PREFERRED,
+ self.wifi_network_ssid,
+ self.wifi_network_pass):
+
+ result.append(SETUP_PHONE_FAIL)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ wait_for_wifi_disconnected(ad, self.wifi_network_ssid)
+
+ if _continue:
+ if not verify_internet_connection(self.log, ad):
+ result.append(VERIFY_INTERNET_FAIL)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ begin_time = datetime.now()
+ if reboot_test(self.log, ad, wifi_ssid=self.wifi_network_ssid):
+ result.append(True)
+ else:
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ end_time = datetime.now()
+ search_intervals.append([begin_time, end_time])
+
+ if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or (
+ attempt == cycle - 1) or exit_due_to_high_fail_rate:
+
+ ad.log.info(
+ '====== Test result of IMS bootup registration at slot %s '
+ '======',
+ voice_slot)
+ ad.log.info(result)
+
+ for slot in [voice_slot, the_other_slot]:
+ if slot is None:
+ continue
+
+ ims_reg, parsing_fail, avg_ims_reg_duration = parse_ims_reg(
+ ad, search_intervals, 'iwlan', 'reboot', slot=slot)
+ ad.log.info(
+ '====== IMS bootup registration at slot %s ======', slot)
+ for msg in ims_reg:
+ print_nested_dict(ad, msg)
+
+ ad.log.info(
+ '====== Attempt of parsing fail at slot %s ======' % slot)
+ for msg in parsing_fail:
+ ad.log.info(msg)
+
+ ad.log.warning('====== Summary ======')
+ ad.log.warning(
+ '%s/%s cycles failed.',
+ (len(result) - result.count(True)),
+ len(result))
+ for attempt, value in enumerate(result):
+ if value is not True:
+ ad.log.warning('Cycle %s: %s', attempt+1, value)
+
+ try:
+ fail_rate = (
+ len(result) - result.count(True))/len(result)
+ ad.log.info(
+ 'Fail rate of IMS bootup registration at slot %s: %s',
+ slot,
+ fail_rate)
+ except Exception as e:
+ ad.log.error(
+ 'Fail rate of IMS bootup registration at slot %s: '
+ 'ERROR (%s)',
+ slot,
+ e)
+
+ ad.log.info(
+ 'Number of trials with valid parsed logs: %s',
+ len(ims_reg))
+ ad.log.info(
+ 'Average IMS bootup registration time at slot %s: %s',
+ slot, avg_ims_reg_duration)
+ if exit_due_to_high_fail_rate:
+ break
+
+ return test_result(result, cycle)
+
+ @test_tracker_info(uuid="45ed4572-7de9-4e1b-b2ec-58dea722fa3e")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_cycle_airplane_mode_4g(self):
+ """Cycle airplane mode and measure IMS registration time on LTE
+
+ Test steps:
+ 1. Enable VoLTE at all slots and ensure IMS is registered on LTE at
+ all slots.
+ 2. Cycle airplane mode.
+ 3. Parse logcat to calculate IMS registration time right after
+ recovery of cellular service.
+ """
+ ad = self.android_devices[0]
+ cycle = self.cycle_apm_4g_test_cycle
+ voice_slot = get_slot_index_from_voice_sub_id(ad)
+
+ if getattr(ad, 'dsds', False):
+ the_other_slot = 1 - voice_slot
+ else:
+ the_other_slot = None
+
+ result = []
+ search_intervals = []
+ exit_due_to_high_fail_rate = False
+ for attempt in range(cycle):
+ _continue = True
+ self.log.info(
+ '============> Cycle airplane mode on LTE %s/%s <============',
+ attempt+1,
+ cycle)
+
+ sub_id_list = get_all_sub_id(ad)
+ for sub_id in sub_id_list:
+ if not phone_setup_volte_for_subscription(self.log, ad, sub_id):
+ result.append(SETUP_PHONE_FAIL)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if not wait_for_network_service(self.log, ad):
+ result.append(VERIFY_NETWORK_FAIL)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ begin_time = datetime.now()
+ if airplane_mode_test(self.log, ad):
+ result.append(True)
+ else:
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ end_time = datetime.now()
+ search_intervals.append([begin_time, end_time])
+
+ if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or (
+ attempt == cycle - 1) or exit_due_to_high_fail_rate:
+
+ ad.log.info(
+ '====== Test result of IMS registration at slot %s ======',
+ voice_slot)
+ ad.log.info(result)
+
+ for slot in [voice_slot, the_other_slot]:
+ if slot is None:
+ continue
+
+ ims_reg, parsing_fail, avg_ims_reg_duration = parse_ims_reg(
+ ad, search_intervals, '4g', 'apm', slot=slot)
+ ad.log.info(
+ '====== IMS registration at slot %s ======', slot)
+ for msg in ims_reg:
+ print_nested_dict(ad, msg)
+
+ ad.log.info(
+ '====== Attempt of parsing fail at slot %s ======' % slot)
+ for msg in parsing_fail:
+ ad.log.info(msg)
+
+ ad.log.warning('====== Summary ======')
+ ad.log.warning('%s/%s cycles failed.', (len(result) - result.count(True)), len(result))
+ for attempt, value in enumerate(result):
+ if value is not True:
+ ad.log.warning('Cycle %s: %s', attempt+1, value)
+
+ try:
+ fail_rate = (
+ len(result) - result.count(True))/len(result)
+ ad.log.info(
+ 'Fail rate of IMS registration at slot %s: %s',
+ slot,
+ fail_rate)
+ except Exception as e:
+ ad.log.error(
+ 'Fail rate of IMS registration at slot %s: '
+ 'ERROR (%s)',
+ slot,
+ e)
+
+ ad.log.info(
+ 'Number of trials with valid parsed logs: %s',
+ len(ims_reg))
+ ad.log.info(
+ 'Average IMS registration time at slot %s: %s',
+ slot, avg_ims_reg_duration)
+
+ if exit_due_to_high_fail_rate:
+ break
+
+ return test_result(result, cycle)
+
+ @test_tracker_info(uuid="915c9403-8bbc-45c7-be53-8b0de4191716")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_cycle_wifi_in_apm_mode(self):
+ """Cycle Wi-Fi in airplane mode and measure IMS registration time over
+ iwlan.
+
+ Test steps:
+ 1. Enable VoLTE; enable WFC and set WFC mode to Wi-Fi-preferred mode;
+ turn on airplane mode and connect Wi-Fi to ensure IMS is
+ registered over iwlan.
+ 2. Cycle Wi-Fi.
+ 3. Parse logcat to calculate IMS registration time right after
+ recovery of Wi-Fi connection in airplane mode.
+ """
+ ad = self.android_devices[0]
+ cycle = self.cycle_wifi_in_apm_mode_test_cycle
+ voice_slot = get_slot_index_from_voice_sub_id(ad)
+
+ result = []
+ search_intervals = []
+ exit_due_to_high_fail_rate = False
+ for attempt in range(cycle):
+ _continue = True
+ self.log.info(
+ '============> Cycle WiFi in airplane mode %s/%s <============',
+ attempt+1,
+ cycle)
+
+ begin_time = datetime.now()
+
+ if not wait_for_wifi_disconnected(ad, self.wifi_network_ssid):
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if not phone_setup_iwlan(
+ self.log,
+ ad,
+ True,
+ WFC_MODE_WIFI_PREFERRED,
+ self.wifi_network_ssid,
+ self.wifi_network_pass):
+
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if not verify_internet_connection(self.log, ad):
+ result.append(VERIFY_INTERNET_FAIL)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if not wait_for_wifi_disconnected(
+ ad, self.wifi_network_ssid):
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ result.append(True)
+ end_time = datetime.now()
+ search_intervals.append([begin_time, end_time])
+
+ if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or (
+ attempt == cycle - 1) or exit_due_to_high_fail_rate:
+
+ ad.log.info(
+ '====== Test result of IMS registration at slot %s ======',
+ voice_slot)
+ ad.log.info(result)
+
+ ims_reg, parsing_fail, avg_ims_reg_duration = parse_ims_reg(
+ ad, search_intervals, 'iwlan', 'apm')
+ ad.log.info(
+ '====== IMS registration at slot %s ======', voice_slot)
+ for msg in ims_reg:
+ ad.log.info(msg)
+
+ ad.log.info(
+ '====== Attempt of parsing fail at slot %s ======' % voice_slot)
+ for msg in parsing_fail:
+ ad.log.info(msg)
+
+ ad.log.warning('====== Summary ======')
+ ad.log.warning(
+ '%s/%s cycles failed.',
+ (len(result) - result.count(True)),
+ len(result))
+ for attempt, value in enumerate(result):
+ if value is not True:
+ ad.log.warning('Cycle %s: %s', attempt+1, value)
+
+ try:
+ fail_rate = (len(result) - result.count(True))/len(result)
+ ad.log.info(
+ 'Fail rate of IMS registration at slot %s: %s',
+ voice_slot,
+ fail_rate)
+ except Exception as e:
+ ad.log.error(
+ 'Fail rate of IMS registration at slot %s: ERROR (%s)',
+ voice_slot,
+ e)
+
+ ad.log.info(
+ 'Number of trials with valid parsed logs: %s', len(ims_reg))
+ ad.log.info(
+ 'Average IMS registration time at slot %s: %s',
+ voice_slot, avg_ims_reg_duration)
+
+ if exit_due_to_high_fail_rate:
+ break
+ toggle_airplane_mode(self.log, ad, False)
+ return test_result(result, cycle)
+
+ def ims_handover_4g_to_iwlan_wfc_wifi_preferred(self, voice_call=False):
+ """Connect WFC to make IMS registration hand over from LTE to iwlan in
+ Wi-Fi-preferred mode. Measure IMS handover time.
+
+ Test steps:
+ 1. Enable WFC and set WFC mode to Wi-Fi-preferred mode.
+ 2. Ensure Wi-Fi are disconnected and all cellular services are
+ available.
+ 3. (Optional) Make a VoLTE call and keep the call active.
+ 4. Connect Wi-Fi. The IMS registration should hand over from LTE
+ to iwlan.
+ 5. Parse logcat to calculate the IMS handover time.
+
+ Args:
+ voice_call: True if an active VoLTE call is desired in the background
+ during IMS handover procedure. Otherwise False.
+ """
+ ad = self.android_devices[0]
+ if voice_call:
+ cycle = self.ims_handover_4g_to_iwlan_with_voice_call_wfc_wifi_preferred_test_cycle
+ else:
+ cycle = self.ims_handover_4g_to_iwlan_wfc_wifi_preferred_test_cycle
+
+ voice_slot = get_slot_index_from_voice_sub_id(ad)
+
+ result = []
+ search_intervals = []
+ exit_due_to_high_fail_rate = False
+
+ if not set_wfc_mode(self.log, ad, WFC_MODE_WIFI_PREFERRED):
+ return False
+
+ for attempt in range(cycle):
+ _continue = True
+ self.log.info(
+ '======> IMS handover from LTE to iwlan in WFC wifi-preferred '
+ 'mode %s/%s <======',
+ attempt+1,
+ cycle)
+
+ begin_time = datetime.now()
+
+ if not wait_for_wifi_disconnected(ad, self.wifi_network_ssid):
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if not wait_for_network_service(
+ self.log,
+ ad,
+ wifi_connected=False,
+ ims_reg=True):
+
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if voice_call:
+ ad_mt = self.android_devices[1]
+ call_params = [(
+ ad,
+ ad_mt,
+ None,
+ is_phone_in_call_volte,
+ None)]
+ call_result = two_phone_call_short_seq(
+ self.log,
+ ad,
+ phone_idle_volte,
+ is_phone_in_call_volte,
+ ad_mt,
+ None,
+ None,
+ wait_time_in_call=30,
+ call_params=call_params)
+ self.tel_logger.set_result(call_result.result_value)
+ if not call_result:
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if not phone_setup_iwlan(
+ self.log,
+ ad,
+ False,
+ WFC_MODE_WIFI_PREFERRED,
+ self.wifi_network_ssid,
+ self.wifi_network_pass):
+
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if voice_slot == 0:
+ ims_pattern = ON_IMS_MM_TEL_CONNECTED_IWLAN_SLOT0
+ else:
+ ims_pattern = ON_IMS_MM_TEL_CONNECTED_IWLAN_SLOT1
+
+ if wait_for_log(ad, ims_pattern, begin_time=begin_time):
+ ad.log.info(
+ 'IMS registration is handed over from LTE to iwlan.')
+ else:
+ ad.log.error(
+ 'IMS registration is NOT yet handed over from LTE to '
+ 'iwlan.')
+
+ if voice_call:
+ hangup_call(self.log, ad)
+
+ if _continue:
+ if not verify_internet_connection(self.log, ad):
+ result.append(VERIFY_INTERNET_FAIL)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if not wait_for_wifi_disconnected(
+ ad, self.wifi_network_ssid):
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if voice_slot == 0:
+ ims_pattern = ON_IMS_MM_TEL_CONNECTED_4G_SLOT0
+ else:
+ ims_pattern = ON_IMS_MM_TEL_CONNECTED_4G_SLOT1
+
+ if wait_for_log(ad, ims_pattern, begin_time=begin_time):
+ ad.log.info(
+ 'IMS registration is handed over from iwlan to LTE.')
+ else:
+ ad.log.error(
+ 'IMS registration is NOT yet handed over from iwlan to '
+ 'LTE.')
+
+ if _continue:
+ result.append(True)
+ end_time = datetime.now()
+ search_intervals.append([begin_time, end_time])
+
+ if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or (
+ attempt == cycle - 1) or exit_due_to_high_fail_rate:
+
+ ad.log.info(
+ '====== Test result of IMS registration at slot %s ======',
+ voice_slot)
+ ad.log.info(result)
+
+ ims_reg, parsing_fail, avg_ims_reg_duration = parse_ims_reg(
+ ad, search_intervals, 'iwlan', 'apm')
+ ad.log.info(
+ '====== IMS registration at slot %s ======', voice_slot)
+ for msg in ims_reg:
+ ad.log.info(msg)
+
+ ad.log.info(
+ '====== Attempt of parsing fail at slot %s ======' % voice_slot)
+ for msg in parsing_fail:
+ ad.log.info(msg)
+
+ ad.log.warning('====== Summary ======')
+ ad.log.warning(
+ '%s/%s cycles failed.',
+ (len(result) - result.count(True)),
+ len(result))
+ for attempt, value in enumerate(result):
+ if value is not True:
+ ad.log.warning('Cycle %s: %s', attempt+1, value)
+
+ try:
+ fail_rate = (len(result) - result.count(True))/len(result)
+ ad.log.info(
+ 'Fail rate of IMS registration at slot %s: %s',
+ voice_slot,
+ fail_rate)
+ except Exception as e:
+ ad.log.error(
+ 'Fail rate of IMS registration at slot %s: ERROR (%s)',
+ voice_slot,
+ e)
+
+ ad.log.info(
+ 'Number of trials with valid parsed logs: %s',len(ims_reg))
+ ad.log.info(
+ 'Average IMS registration time at slot %s: %s',
+ voice_slot, avg_ims_reg_duration)
+
+ if exit_due_to_high_fail_rate:
+ break
+
+ return test_result(result, cycle)
+
+ @test_tracker_info(uuid="e3d1aaa8-f673-4a2b-adb1-cfa525a4edbd")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_ims_handover_4g_to_iwlan_with_voice_call_wfc_wifi_preferred(self):
+ """Connect WFC to make IMS registration hand over from LTE to iwlan in
+ Wi-Fi-preferred mode. Measure IMS handover time.
+
+ Test steps:
+ 1. Enable WFC and set WFC mode to Wi-Fi-preferred mode.
+ 2. Ensure Wi-Fi are disconnected and all cellular services are
+ available.
+ 3. Make a VoLTE call and keep the call active.
+ 4. Connect Wi-Fi. The IMS registration should hand over from LTE
+ to iwlan.
+ 5. Parse logcat to calculate the IMS handover time.
+ """
+ return self.ims_handover_4g_to_iwlan_wfc_wifi_preferred(True)
+
+ @test_tracker_info(uuid="bd86fb46-04bd-4642-923a-747e6c9d4282")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_ims_handover_4g_to_iwlan_wfc_wifi_preferred(self):
+ """Connect WFC to make IMS registration hand over from LTE to iwlan in
+ Wi-Fi-preferred mode. Measure IMS handover time.
+
+ Test steps:
+ 1. Enable WFC and set WFC mode to Wi-Fi-preferred mode.
+ 2. Ensure Wi-Fi are disconnected and all cellular services are
+ available.
+ 3. Connect Wi-Fi. The IMS registration should hand over from LTE
+ to iwlan.
+ 4. Parse logcat to calculate the IMS handover time.
+ """
+ return self.ims_handover_4g_to_iwlan_wfc_wifi_preferred(False)
+
+ def ims_handover_iwlan_to_4g_wfc_wifi_preferred(self, voice_call=False):
+ """Disconnect Wi-Fi to make IMS registration hand over from iwlan to LTE
+ in Wi-Fi-preferred mode. Measure IMS handover time.
+
+ Test steps:
+ 1. Enable WFC, set WFC mode to Wi-Fi-preferred mode, and then
+ connect Wi-Fi to let IMS register over iwlan.
+ 2. (Optional) Make a WFC call and keep the call active.
+ 3. Disconnect Wi-Fi. The IMS registration should hand over from iwlan
+ to LTE.
+ 4. Parse logcat to calculate the IMS handover time.
+
+ Args:
+ voice_call: True if an active WFC call is desired in the background
+ during IMS handover procedure. Otherwise False.
+ """
+ ad = self.android_devices[0]
+ if voice_call:
+ cycle = self.ims_handover_iwlan_to_4g_with_voice_call_wfc_wifi_preferred_test_cycle
+ else:
+ cycle = self.ims_handover_iwlan_to_4g_wfc_wifi_preferred_test_cycle
+ voice_slot = get_slot_index_from_voice_sub_id(ad)
+
+ result = []
+ search_intervals = []
+ exit_due_to_high_fail_rate = False
+ for attempt in range(cycle):
+ _continue = True
+ self.log.info(
+ '======> IMS handover from iwlan to LTE in WFC wifi-preferred '
+ 'mode %s/%s <======',
+ attempt+1,
+ cycle)
+
+ begin_time = datetime.now()
+
+ if not phone_setup_iwlan(
+ self.log,
+ ad,
+ False,
+ WFC_MODE_WIFI_PREFERRED,
+ self.wifi_network_ssid,
+ self.wifi_network_pass):
+
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ wait_for_wifi_disconnected(ad, self.wifi_network_ssid)
+
+ if _continue:
+ if voice_slot == 0:
+ ims_pattern = ON_IMS_MM_TEL_CONNECTED_IWLAN_SLOT0
+ else:
+ ims_pattern = ON_IMS_MM_TEL_CONNECTED_IWLAN_SLOT1
+
+ if wait_for_log(ad, ims_pattern, begin_time=begin_time):
+ ad.log.info(
+ 'IMS registration is handed over from LTE to iwlan.')
+ else:
+ ad.log.error(
+ 'IMS registration is NOT yet handed over from LTE to '
+ 'iwlan.')
+
+ if _continue:
+ if not verify_internet_connection(self.log, ad):
+ result.append(VERIFY_INTERNET_FAIL)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if voice_call:
+ ad_mt = self.android_devices[1]
+ call_params = [(
+ ad,
+ ad_mt,
+ None,
+ is_phone_in_call_iwlan,
+ None)]
+ call_result = two_phone_call_short_seq(
+ self.log,
+ ad,
+ phone_idle_iwlan,
+ is_phone_in_call_iwlan,
+ ad_mt,
+ None,
+ None,
+ wait_time_in_call=30,
+ call_params=call_params)
+ self.tel_logger.set_result(call_result.result_value)
+ if not call_result:
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if not wait_for_wifi_disconnected(
+ ad, self.wifi_network_ssid):
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if voice_slot == 0:
+ ims_pattern = ON_IMS_MM_TEL_CONNECTED_4G_SLOT0
+ else:
+ ims_pattern = ON_IMS_MM_TEL_CONNECTED_4G_SLOT1
+
+ if wait_for_log(ad, ims_pattern, begin_time=begin_time):
+ ad.log.info(
+ 'IMS registration is handed over from iwlan to LTE.')
+ else:
+ ad.log.error(
+ 'IMS registration is NOT yet handed over from iwlan to '
+ 'LTE.')
+
+ if voice_call:
+ hangup_call(self.log, ad)
+
+ if _continue:
+ if not wait_for_network_service(
+ self.log,
+ ad,
+ wifi_connected=False,
+ ims_reg=True):
+
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ result.append(True)
+ end_time = datetime.now()
+ search_intervals.append([begin_time, end_time])
+
+ if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or (
+ attempt == cycle - 1) or exit_due_to_high_fail_rate:
+
+ ad.log.info(
+ '====== Test result of IMS registration at slot %s ======',
+ voice_slot)
+ ad.log.info(result)
+
+ ims_reg, parsing_fail, avg_ims_reg_duration = parse_ims_reg(
+ ad, search_intervals, '4g', 'wifi_off')
+ ad.log.info(
+ '====== IMS registration at slot %s ======', voice_slot)
+ for msg in ims_reg:
+ ad.log.info(msg)
+
+ ad.log.info(
+ '====== Attempt of parsing fail at slot %s ======' % voice_slot)
+ for msg in parsing_fail:
+ ad.log.info(msg)
+
+ ad.log.warning('====== Summary ======')
+ ad.log.warning(
+ '%s/%s cycles failed.',
+ (len(result) - result.count(True)),
+ len(result))
+ for attempt, value in enumerate(result):
+ if value is not True:
+ ad.log.warning('Cycle %s: %s', attempt+1, value)
+
+ try:
+ fail_rate = (len(result) - result.count(True))/len(result)
+ ad.log.info(
+ 'Fail rate of IMS registration at slot %s: %s',
+ voice_slot,
+ fail_rate)
+ except Exception as e:
+ ad.log.error(
+ 'Fail rate of IMS registration at slot %s: ERROR (%s)',
+ voice_slot,
+ e)
+
+ ad.log.info(
+ 'Number of trials with valid parsed logs: %s', len(ims_reg))
+ ad.log.info(
+ 'Average IMS registration time at slot %s: %s',
+ voice_slot, avg_ims_reg_duration)
+
+ if exit_due_to_high_fail_rate:
+ break
+
+ return test_result(result, cycle)
+
+ @test_tracker_info(uuid="6ce623a6-7ef9-42db-8099-d5c449e70bff")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_ims_handover_iwlan_to_4g_wfc_wifi_preferred(self):
+ """Disconnect Wi-Fi to make IMS registration hand over from iwlan to LTE
+ in Wi-Fi-preferred mode. Measure IMS handover time.
+
+ Test steps:
+ 1. Enable WFC, set WFC mode to Wi-Fi-preferred mode, and then
+ connect Wi-Fi to let IMS register over iwlan.
+ 2. Disconnect Wi-Fi. The IMS registration should hand over from iwlan
+ to LTE.
+ 3. Parse logcat to calculate the IMS handover time.
+ """
+ return self.ims_handover_iwlan_to_4g_wfc_wifi_preferred(False)
+
+ @test_tracker_info(uuid="b965ab09-d8b1-423f-bb98-2cdd43babbe3")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_ims_handover_iwlan_to_4g_with_voice_call_wfc_wifi_preferred(self):
+ """Disconnect Wi-Fi to make IMS registration hand over from iwlan to LTE
+ in Wi-Fi-preferred mode. Measure IMS handover time.
+
+ Test steps:
+ 1. Enable WFC, set WFC mode to Wi-Fi-preferred mode, and then
+ connect Wi-Fi to let IMS register over iwlan.
+ 2. Make a WFC call and keep the call active.
+ 3. Disconnect Wi-Fi. The IMS registration should hand over from iwlan
+ to LTE.
+ 4. Parse logcat to calculate the IMS handover time.
+ """
+ return self.ims_handover_iwlan_to_4g_wfc_wifi_preferred(True)
+
+ def ims_handover_iwlan_to_4g_wfc_cellular_preferred(self, voice_call=False):
+ """Turn off airplane mode to make IMS registration hand over from iwlan to LTE
+ in WFC cellular-preferred mode. Measure IMS handover time.
+
+ Test steps:
+ 1. Enable WFC, set WFC mode to cellular-preferred mode, turn on
+ airplane mode and then connect Wi-Fi to let IMS register over
+ iwlan.
+ 2. (Optional) Make a WFC call and keep the call active.
+ 3. Turn off airplane mode. The IMS registration should hand over
+ from iwlan to LTE.
+ 4. Parse logcat to calculate the IMS handover time.
+
+ Args:
+ voice_call: True if an active WFC call is desired in the background
+ during IMS handover procedure. Otherwise False.
+ """
+ ad = self.android_devices[0]
+ if voice_call:
+ cycle = self.ims_handover_iwlan_to_4g_with_voice_call_wfc_cellular_preferred_test_cycle
+ else:
+ cycle = self.ims_handover_iwlan_to_4g_wfc_cellular_preferred_test_cycle
+
+ voice_slot = get_slot_index_from_voice_sub_id(ad)
+
+ result = []
+ search_intervals = []
+ exit_due_to_high_fail_rate = False
+ for attempt in range(cycle):
+ _continue = True
+
+ self.log.info(
+ '======> IMS handover from iwlan to LTE in WFC '
+ 'cellular-preferred mode %s/%s <======',
+ attempt+1,
+ cycle)
+
+ begin_time = datetime.now()
+
+ if not phone_setup_iwlan(
+ self.log,
+ ad,
+ True,
+ WFC_MODE_CELLULAR_PREFERRED,
+ self.wifi_network_ssid,
+ self.wifi_network_pass):
+
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ toggle_airplane_mode(self.log, ad, False)
+
+ if _continue:
+ if voice_slot == 0:
+ ims_pattern = ON_IMS_MM_TEL_CONNECTED_IWLAN_SLOT0
+ else:
+ ims_pattern = ON_IMS_MM_TEL_CONNECTED_IWLAN_SLOT1
+
+ if wait_for_log(ad, ims_pattern, begin_time=begin_time):
+ ad.log.info(
+ 'IMS registration is handed over from LTE to iwlan.')
+ else:
+ ad.log.error(
+ 'IMS registration is NOT yet handed over from LTE to '
+ 'iwlan.')
+
+ if _continue:
+ if not verify_internet_connection(self.log, ad):
+ result.append(VERIFY_INTERNET_FAIL)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if voice_call:
+ ad_mt = self.android_devices[1]
+ call_params = [(
+ ad,
+ ad_mt,
+ None,
+ is_phone_in_call_iwlan,
+ None)]
+ call_result = two_phone_call_short_seq(
+ self.log,
+ ad,
+ phone_idle_iwlan,
+ is_phone_in_call_iwlan,
+ ad_mt,
+ None,
+ None,
+ wait_time_in_call=30,
+ call_params=call_params)
+ self.tel_logger.set_result(call_result.result_value)
+ if not call_result:
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if not toggle_airplane_mode(self.log, ad, False):
+ result.append(TOGGLE_OFF_APM_FAIL)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ if voice_slot == 0:
+ ims_pattern = ON_IMS_MM_TEL_CONNECTED_4G_SLOT0
+ else:
+ ims_pattern = ON_IMS_MM_TEL_CONNECTED_4G_SLOT1
+
+ if wait_for_log(ad, ims_pattern, begin_time=begin_time):
+ ad.log.info(
+ 'IMS registration is handed over from iwlan to LTE.')
+ else:
+ ad.log.error(
+ 'IMS registration is NOT yet handed over from iwlan to '
+ 'LTE.')
+
+ if voice_call:
+ hangup_call(self.log, ad)
+
+ if _continue:
+ if not wait_for_network_service(
+ self.log,
+ ad,
+ wifi_connected=True,
+ wifi_ssid=self.wifi_network_ssid,
+ ims_reg=True):
+
+ result.append(False)
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ _continue = False
+ if not test_result(result, cycle, 10, 0.1):
+ exit_due_to_high_fail_rate = True
+
+ if _continue:
+ result.append(True)
+ end_time = datetime.now()
+ search_intervals.append([begin_time, end_time])
+
+ if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or (
+ attempt == cycle - 1) or exit_due_to_high_fail_rate:
+
+ ad.log.info(
+ '====== Test result of IMS registration at slot %s ======',
+ voice_slot)
+ ad.log.info(result)
+
+ ims_reg, parsing_fail, avg_ims_reg_duration = parse_ims_reg(
+ ad, search_intervals, '4g', 'apm')
+ ad.log.info(
+ '====== IMS registration at slot %s ======', voice_slot)
+ for msg in ims_reg:
+ ad.log.info(msg)
+
+ ad.log.info(
+ '====== Attempt of parsing fail at slot %s ======' % voice_slot)
+ for msg in parsing_fail:
+ ad.log.info(msg)
+
+ ad.log.warning('====== Summary ======')
+ ad.log.warning(
+ '%s/%s cycles failed.',
+ (len(result) - result.count(True)),
+ len(result))
+ for attempt, value in enumerate(result):
+ if value is not True:
+ ad.log.warning('Cycle %s: %s', attempt+1, value)
+
+ try:
+ fail_rate = (len(result) - result.count(True))/len(result)
+ ad.log.info(
+ 'Fail rate of IMS registration at slot %s: %s',
+ voice_slot,
+ fail_rate)
+ except Exception as e:
+ ad.log.error(
+ 'Fail rate of IMS registration at slot %s: ERROR (%s)',
+ voice_slot,
+ e)
+
+ ad.log.info(
+ 'Number of trials with valid parsed logs: %s', len(ims_reg))
+ ad.log.info(
+ 'Average IMS registration time at slot %s: %s',
+ voice_slot, avg_ims_reg_duration)
+
+ if exit_due_to_high_fail_rate:
+ break
+
+ return test_result(result, cycle)
+
+ @test_tracker_info(uuid="ce69fac3-931b-4177-82ea-dbae50b2b310")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_ims_handover_iwlan_to_4g_wfc_cellular_preferred(self):
+ """Turn off airplane mode to make IMS registration hand over from iwlan to LTE
+ in WFC cellular-preferred mode. Measure IMS handover time.
+
+ Test steps:
+ 1. Enable WFC, set WFC mode to cellular-preferred mode, turn on
+ airplane mode and then connect Wi-Fi to let IMS register over
+ iwlan.
+ 2. Turn off airplane mode. The IMS registration should hand over
+ from iwlan to LTE.
+ 3. Parse logcat to calculate the IMS handover time.
+ """
+ return self.ims_handover_iwlan_to_4g_wfc_cellular_preferred(False)
+
+ @test_tracker_info(uuid="0ac7d43e-34e6-4ea3-92f4-e413e90a8bc1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_ims_handover_iwlan_to_4g_with_voice_call_wfc_cellular_preferred(self):
+ """Turn off airplane mode to make IMS registration hand over from iwlan to LTE
+ in WFC cellular-preferred mode. Measure IMS handover time.
+
+ Test steps:
+ 1. Enable WFC, set WFC mode to cellular-preferred mode, turn on
+ airplane mode and then connect Wi-Fi to let IMS register over
+ iwlan.
+ 2. Make a WFC call and keep the call active.
+ 3. Turn off airplane mode. The IMS registration should hand over
+ from iwlan to LTE.
+ 4. Parse logcat to calculate the IMS handover time.
+ """
+ return self.ims_handover_iwlan_to_4g_wfc_cellular_preferred(True)
\ No newline at end of file
diff --git a/acts_tests/tests/google/tel/live/TelLiveRilMessageKpiTest.py b/acts_tests/tests/google/tel/live/TelLiveRilMessageKpiTest.py
new file mode 100644
index 0000000..aa1c5d3
--- /dev/null
+++ b/acts_tests/tests/google/tel/live/TelLiveRilMessageKpiTest.py
@@ -0,0 +1,442 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 - Google
+#
+# 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.libs.utils.multithread import multithread_func
+from acts.test_decorators import test_tracker_info
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
+from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
+from acts_contrib.test_utils.tel.tel_message_utils import mms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_parse_utils import parse_mms
+from acts_contrib.test_utils.tel.tel_parse_utils import parse_sms_delivery_time
+from acts_contrib.test_utils.tel.tel_parse_utils import print_nested_dict
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan_for_subscription
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_message_subid
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad
+from acts.utils import get_current_epoch_time
+from acts.utils import rand_ascii_str
+
+CALCULATE_EVERY_N_CYCLES = 10
+MAX_FAIL_COUNT = 10
+
+
+class TelLiveRilMessageKpiTest(TelephonyBaseTest):
+ def setup_class(self):
+ TelephonyBaseTest.setup_class(self)
+ self.sms_4g_over_sgs_test_cycle = self.user_params.get(
+ 'sms_4g_over_sgs_test_cycle', 1)
+ self.sms_4g_over_ims_test_cycle = self.user_params.get(
+ 'sms_4g_over_ims_test_cycle', 1)
+ self.sms_iwlan_test_cycle = self.user_params.get(
+ 'sms_iwlan_test_cycle', 1)
+ self.mms_4g_test_cycle = self.user_params.get('mms_4g_test_cycle', 1)
+ self.mms_iwlan_test_cycle = self.user_params.get(
+ 'mms_iwlan_test_cycle', 1)
+
+ def sms_test(self, ads):
+ """Send and receive a short SMS with random length and content between
+ two UEs.
+
+ Args:
+ ads: list containing Android objects
+
+ Returns:
+ True if both sending and receiving are successful. Otherwise False.
+ """
+ msg_length = random.randint(5, 160)
+ msg_body = rand_ascii_str(msg_length)
+
+ if not sms_send_receive_verify(self.log, ads[0], ads[1], [msg_body]):
+ ads[0].log.warning('SMS of length %s test failed', msg_length)
+ return False
+ else:
+ ads[0].log.info('SMS of length %s test succeeded', msg_length)
+ return True
+
+ def mms_test(self, ads, expected_result=True):
+ """Send and receive a MMS with random text length and content between
+ two UEs.
+
+ Args:
+ ads: list containing Android objects
+ expected_result: True to expect successful MMS sending and reception.
+ Otherwise False.
+
+ Returns:
+ True if both sending and reception are successful. Otherwise False.
+ """
+ message_length = random.randint(5, 160)
+ message_array = [('Test Message', rand_ascii_str(message_length), None)]
+ if not mms_send_receive_verify(
+ self.log,
+ ads[0],
+ ads[1],
+ message_array,
+ expected_result=expected_result):
+ self.log.warning('MMS of body length %s test failed', message_length)
+ return False
+ else:
+ self.log.info('MMS of body length %s test succeeded', message_length)
+ self.log.info('MMS test of body lengths %s succeeded', message_length)
+ return True
+
+
+ def _test_sms_4g(self, over_iwlan=False, over_ims=False):
+ """ Send/receive SMS over SGs/IMS to measure MO SMS setup time and SMS
+ delivery time.
+
+ Test steps:
+ 1. Enable VoLTE when over IMS. Otherwise disable VoLTE.
+ 2. Send a SMS from MO UE and receive it by MT UE.
+ 3. Parse logcat of both MO and MT UEs to calculate MO SMS setup time
+ and SMS delivery time.
+
+ Args:
+ over_iwlan: True for over Wi-Fi and False for over cellular network
+ over_ims: True for over IMS and False for over SGs
+
+ Returns:
+ True if both sending and reception are successful. Otherwise False.
+ """
+ ad_mo = self.android_devices[0]
+ ad_mt = self.android_devices[1]
+
+ mo_sub_id, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(
+ [ad_mo, ad_mt],
+ host_sub_id=None,
+ type="sms")
+ set_message_subid(ad_mt, mt_sub_id)
+
+ cycle = self.sms_4g_over_sgs_test_cycle
+ phone_setup_func = phone_setup_csfb_for_subscription
+ mo_param = (self.log, ad_mo, mo_sub_id)
+ mt_param = (self.log, ad_mt, mt_sub_id)
+ wording = "SGs"
+ parsing = '4g'
+ if over_ims:
+ cycle = self.sms_4g_over_ims_test_cycle
+ phone_setup_func = phone_setup_volte_for_subscription
+ wording = "IMS"
+ parsing = 'iwlan'
+
+ if over_iwlan:
+ cycle = self.sms_iwlan_test_cycle
+ phone_setup_func = phone_setup_iwlan_for_subscription
+
+ mo_param = (
+ self.log,
+ ad_mo,
+ mo_sub_id,
+ True,
+ WFC_MODE_CELLULAR_PREFERRED,
+ self.wifi_network_ssid,
+ self.wifi_network_pass)
+
+ mt_param = (
+ self.log,
+ ad_mt,
+ mt_sub_id,
+ True,
+ WFC_MODE_CELLULAR_PREFERRED,
+ self.wifi_network_ssid,
+ self.wifi_network_pass)
+
+ wording = 'iwlan'
+ parsing = 'iwlan'
+
+ tasks = [
+ (phone_setup_func, mo_param),
+ (phone_setup_func, mt_param)]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+
+ sms_test_summary = []
+ result = True
+ continuous_fail = 0
+ for attempt in range(cycle):
+ self.log.info(
+ '======> MO/MT SMS over %s %s/%s <======',
+ wording,
+ attempt+1,
+ cycle)
+ res = self.sms_test([ad_mo, ad_mt])
+ sms_test_summary.append(res)
+
+ if not res:
+ continuous_fail += 1
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ result = False
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ else:
+ time.sleep(random.randint(3,10))
+
+ if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or (
+ attempt == cycle - 1) or continuous_fail >= MAX_FAIL_COUNT:
+ parse_sms_delivery_time(self.log, ad_mo, ad_mt, rat=parsing)
+ try:
+ sms_test_fail_rate = sms_test_summary.count(
+ False)/len(sms_test_summary)
+ self.log.info(
+ 'Fail rate of SMS test over %s: %s/%s (%.2f)',
+ wording,
+ sms_test_summary.count(False),
+ len(sms_test_summary),
+ sms_test_fail_rate)
+ except Exception as e:
+ self.log.error(
+ 'Fail rate of SMS test over %s: ERROR (%s)',
+ wording,
+ e)
+
+ if continuous_fail >= MAX_FAIL_COUNT:
+ self.log.error(
+ 'Failed more than %s times in succession. Test is terminated '
+ 'forcedly.',
+ MAX_FAIL_COUNT)
+ break
+
+ return result
+
+
+ @test_tracker_info(uuid="13d1a53b-66be-4ac1-b5ee-dfe4c5e4e4e1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_sms_4g_over_sgs(self):
+ """ Send/receive SMS over SGs to measure MO SMS setup time and SMS
+ delivery time.
+
+ Test steps:
+ 1. Disable VoLTE.
+ 2. Send a SMS from MO UE and receive it by MT UE.
+ 3. Parse logcat of both MO and MT UEs to calculate MO SMS setup time
+ and SMS delivery time.
+ """
+ return self._test_sms_4g()
+
+
+ @test_tracker_info(uuid="293e2955-b38b-4329-b686-fb31d9e46868")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_sms_4g_over_ims(self):
+ """ Send/receive SMS over IMS to measure MO SMS setup time and SMS
+ delivery time.
+
+ Test steps:
+ 1. Enable VoLTE.
+ 2. Send a SMS from MO UE and receive it by MT UE.
+ 3. Parse logcat of both MO and MT UEs to calculate MO SMS setup time
+ and SMS delivery time.
+ """
+ return self._test_sms_4g(over_ims=True)
+
+
+ @test_tracker_info(uuid="862fec2d-8e23-482e-b45c-a42cad134022")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_sms_iwlan(self):
+ """ Send/receive SMS on iwlan to measure MO SMS setup time and SMS
+ delivery time.
+
+ Test steps:
+ 1. Send a SMS from MO UE and receive it by MT UE.
+ 2. Parse logcat of both MO and MT UEs to calculate MO SMS setup time
+ and SMS delivery time.
+ """
+ return self._test_sms_4g(over_iwlan=True, over_ims=True)
+
+
+ def _test_mms_4g(self, over_iwlan=False):
+ """ Send/receive MMS on LTE to measure MO and MT MMS setup time
+
+ Test steps:
+ 1. Enable VoLTE when over Wi-Fi (iwlan). Otherwise disable VoLTE.
+ 2. Send a MMS from MO UE and receive it by MT UE.
+ 3. Parse logcat of both MO and MT UEs to calculate MO and MT MMS
+ setup time.
+
+ Args:
+ over_iwlan: True for over Wi-Fi and False for over cellular network
+
+ Returns:
+ True if both sending and reception are successful. Otherwise False.
+ """
+ ad_mo = self.android_devices[0]
+ ad_mt = self.android_devices[1]
+
+ mo_sub_id, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(
+ [ad_mo, ad_mt],
+ host_sub_id=None,
+ type="sms")
+ set_message_subid(ad_mt, mt_sub_id)
+
+ cycle = self.mms_4g_test_cycle
+ phone_setup_func = phone_setup_csfb_for_subscription
+ mo_param = (self.log, ad_mo, mo_sub_id)
+ mt_param = (self.log, ad_mt, mt_sub_id)
+ wording = "LTE"
+ if over_iwlan:
+ cycle = self.mms_iwlan_test_cycle
+ phone_setup_func = phone_setup_iwlan_for_subscription
+ wording = "iwlan"
+
+ mo_param = (
+ self.log,
+ ad_mo,
+ mo_sub_id,
+ True,
+ WFC_MODE_CELLULAR_PREFERRED,
+ self.wifi_network_ssid,
+ self.wifi_network_pass)
+
+ mt_param = (
+ self.log,
+ ad_mt,
+ mt_sub_id,
+ True,
+ WFC_MODE_CELLULAR_PREFERRED,
+ self.wifi_network_ssid,
+ self.wifi_network_pass)
+
+ phone_setup_tasks = [
+ (phone_setup_func, mo_param),
+ (phone_setup_func, mt_param)]
+ if not multithread_func(self.log, phone_setup_tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ if not over_iwlan:
+ wait_for_cell_data_connection_tasks = [
+ (wait_for_cell_data_connection, (self.log, ad_mo, True)),
+ (wait_for_cell_data_connection, (self.log, ad_mt, True))]
+ if not multithread_func(self.log, wait_for_cell_data_connection_tasks):
+ return False
+
+ time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
+
+ mms_test_summary = []
+ result = True
+ continuous_fail = 0
+ for attempt in range(cycle):
+ self.log.info(
+ '==================> MO/MT MMS on %s %s/%s <==================',
+ wording,
+ attempt+1,
+ cycle)
+ res = self.mms_test([ad_mo, ad_mt])
+ mms_test_summary.append(res)
+
+ if not res:
+ continuous_fail += 1
+ if not multithread_func(self.log, phone_setup_tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ result = False
+ break
+
+ if not over_iwlan:
+ if not multithread_func(
+ self.log, wait_for_cell_data_connection_tasks):
+ result = False
+ break
+ self._take_bug_report(
+ self.test_name, begin_time=get_current_epoch_time())
+ else:
+ time.sleep(random.randint(3,10))
+
+ if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or (
+ attempt == cycle - 1) or continuous_fail >= MAX_FAIL_COUNT:
+ (
+ mo_res,
+ mo_avg_setup_time,
+ mt_res, mt_avg_setup_time) = parse_mms(ad_mo, ad_mt)
+
+ ad_mo.log.info('================== Sent MMS ==================')
+ print_nested_dict(ad_mo, mo_res)
+ ad_mt.log.info('================== Received MMS ==================')
+ print_nested_dict(ad_mt, mt_res)
+
+ try:
+ ad_mo.log.info(
+ 'Average setup time of MO MMS on %s: %.2f sec.',
+ wording, mo_avg_setup_time)
+ except Exception as e:
+ ad_mo.log.error(
+ 'Average setup time of MO MMS on %s: ERROR (%s)',
+ wording, e)
+
+ try:
+ ad_mt.log.info(
+ 'Average setup time of MT MMS on %s: %.2f sec.',
+ wording, mt_avg_setup_time)
+ except Exception as e:
+ ad_mt.log.error(
+ 'Average setup time of MT MMS on %s: ERROR (%s)',
+ wording, e)
+
+ try:
+ mms_test_fail_rate = mms_test_summary.count(
+ False)/len(mms_test_summary)
+ self.log.info(
+ 'Fail rate of MMS test on LTE: %s/%s (%.2f)',
+ mms_test_summary.count(False),
+ len(mms_test_summary),
+ mms_test_fail_rate)
+ except Exception as e:
+ self.log.error(
+ 'Fail rate of MMS test on %s: ERROR (%s)', wording, e)
+
+ if continuous_fail >= MAX_FAIL_COUNT:
+ self.log.error(
+ 'Failed more than %s times in succession. Test is terminated '
+ 'forcedly.',
+ MAX_FAIL_COUNT)
+ break
+
+ return result
+
+
+ @test_tracker_info(uuid="33d11da8-71f1-40d7-8fc7-86fdc83ce266")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_mms_4g(self):
+ """ Send/receive MMS on LTE to measure MO and MT MMS setup time
+
+ Test steps:
+ 1. Send a MMS from MO UE and receive it by MT UE.
+ 2. Parse logcat of both MO and MT UEs to calculate MO and MT MMS
+ setup time.
+ """
+ return self._test_mms_4g()
+
+
+ @test_tracker_info(uuid="b8a8affa-6559-41d8-9de7-f74406da9ed5")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_mms_iwlan(self):
+ """ Send/receive MMS on iwlan to measure MO and MT MMS setup time
+
+ Test steps:
+ 1. Send a MMS from MO UE and receive it by MT UE.
+ 2. Parse logcat of both MO and MT UEs to calculate MO and MT MMS
+ setup time.
+ """
+ return self._test_mms_4g(over_iwlan=True)
\ No newline at end of file
diff --git a/acts_tests/tests/google/tel/live/TelLiveSettingsTest.py b/acts_tests/tests/google/tel/live/TelLiveSettingsTest.py
index 879353e..6f60282 100644
--- a/acts_tests/tests/google/tel/live/TelLiveSettingsTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveSettingsTest.py
@@ -26,22 +26,22 @@
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_FOR_STATE_CHANGE
+from acts_contrib.test_utils.tel.tel_bootloader_utils import flash_radio
+from acts_contrib.test_utils.tel.tel_logging_utils import set_qxdm_logger_command
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_subid
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_subscription
from acts_contrib.test_utils.tel.tel_test_utils import dumpsys_carrier_config
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import flash_radio
from acts_contrib.test_utils.tel.tel_test_utils import get_outgoing_voice_sub_id
-from acts_contrib.test_utils.tel.tel_test_utils import get_slot_index_from_subid
from acts_contrib.test_utils.tel.tel_test_utils import is_sim_locked
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
from acts_contrib.test_utils.tel.tel_test_utils import power_off_sim
from acts_contrib.test_utils.tel.tel_test_utils import power_on_sim
from acts_contrib.test_utils.tel.tel_test_utils import print_radio_info
from acts_contrib.test_utils.tel.tel_test_utils import revert_default_telephony_setting
-from acts_contrib.test_utils.tel.tel_test_utils import set_qxdm_logger_command
from acts_contrib.test_utils.tel.tel_test_utils import system_file_push
from acts_contrib.test_utils.tel.tel_test_utils import unlock_sim
from acts_contrib.test_utils.tel.tel_test_utils import verify_default_telephony_setting
from acts.utils import set_mobile_data_always_on
+from acts.libs.utils.multithread import multithread_func
class TelLiveSettingsTest(TelephonyBaseTest):
@@ -258,7 +258,7 @@
old_carrier_id, old_carrier_name)
self.dut.log.info(self.result_detail)
sub_id = get_outgoing_voice_sub_id(self.dut)
- slot_index = get_slot_index_from_subid(self.log, self.dut, sub_id)
+ slot_index = get_slot_index_from_subid(self.dut, sub_id)
if self.dut.model in ("angler", "bullhead", "marlin", "sailfish"):
msg = "Power off SIM slot is not supported"
diff --git a/acts_tests/tests/google/tel/live/TelLiveSmokeTest.py b/acts_tests/tests/google/tel/live/TelLiveSmokeTest.py
index 0b8ce5d..5b9263b 100644
--- a/acts_tests/tests/google/tel/live/TelLiveSmokeTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveSmokeTest.py
@@ -30,25 +30,25 @@
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL_FOR_IMS
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_lookup_tables import is_rat_svd_capable
-from acts_contrib.test_utils.tel.tel_test_utils import stop_wifi_tethering
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_default_state
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_default_state
from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import sms_send_receive_verify
from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_cell_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import stop_wifi_tethering
from acts.utils import rand_ascii_str
+from acts.libs.utils.multithread import multithread_func
SKIP = 'Skip'
diff --git a/acts_tests/tests/google/tel/live/TelLiveSmsTest.py b/acts_tests/tests/google/tel/live/TelLiveSmsTest.py
index b9ce084..d03d42a 100644
--- a/acts_tests/tests/google/tel/live/TelLiveSmsTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveSmsTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3.4
#
-# Copyright 2016 - Google
+# Copyright 2022 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -21,246 +21,57 @@
from acts import signals
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_defines import PHONE_TYPE_GSM
-from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL
+from acts_contrib.test_utils.tel.tel_defines import CARRIER_VZW
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
-from acts_contrib.test_utils.tel.tel_defines import SMS_OVER_WIFI_PROVIDERS
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_default_state
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import get_mobile_data_usage
+from acts_contrib.test_utils.tel.tel_data_utils import get_mobile_data_usage
+from acts_contrib.test_utils.tel.tel_data_utils import remove_mobile_data_usage_limit
+from acts_contrib.test_utils.tel.tel_data_utils import set_mobile_data_usage_limit
+from acts_contrib.test_utils.tel.tel_message_utils import sms_in_collision_send_receive_verify
+from acts_contrib.test_utils.tel.tel_message_utils import sms_rx_power_off_multiple_send_receive_verify
+from acts_contrib.test_utils.tel.tel_message_utils import message_test
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_default_state
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
-from acts_contrib.test_utils.tel.tel_test_utils import remove_mobile_data_usage_limit
-from acts_contrib.test_utils.tel.tel_test_utils import mms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import mms_receive_verify_after_call_hangup
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import set_mobile_data_usage_limit
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
-from acts_contrib.test_utils.tel.tel_test_utils import \
- sms_in_collision_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import \
- sms_rx_power_off_multiple_send_receive_verify
-from acts_contrib.test_utils.tel.tel_video_utils import phone_setup_video
-from acts_contrib.test_utils.tel.tel_video_utils import is_phone_in_call_video_bidirectional
-from acts_contrib.test_utils.tel.tel_video_utils import video_call_setup_teardown
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_not_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan_cellular_preferred
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_general
-from acts_contrib.test_utils.tel.tel_sms_utils import _sms_test_mo
-from acts_contrib.test_utils.tel.tel_sms_utils import _sms_test_mt
-from acts_contrib.test_utils.tel.tel_sms_utils import _long_sms_test_mo
-from acts_contrib.test_utils.tel.tel_sms_utils import _long_sms_test_mt
-from acts_contrib.test_utils.tel.tel_mms_utils import _mms_test_mo
-from acts_contrib.test_utils.tel.tel_mms_utils import _mms_test_mt
-from acts_contrib.test_utils.tel.tel_mms_utils import _long_mms_test_mo
-from acts_contrib.test_utils.tel.tel_mms_utils import _long_mms_test_mt
-from acts_contrib.test_utils.tel.tel_mms_utils import _mms_test_mo_after_call_hangup
-from acts_contrib.test_utils.tel.tel_mms_utils import _mms_test_mt_after_call_hangup
-from acts_contrib.test_utils.tel.tel_mms_utils import test_mms_mo_in_call
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_both_devices_for_volte
+from acts_contrib.test_utils.tel.tel_test_utils import install_message_apk
from acts.utils import rand_ascii_str
-
+from acts.libs.utils.multithread import multithread_func
class TelLiveSmsTest(TelephonyBaseTest):
def setup_class(self):
TelephonyBaseTest.setup_class(self)
-
- # Try to put SMS and call on different help device
- # If it is a three phone test bed, use the first one as dut,
- # use the second one as sms/mms help device, use the third one
- # as the active call help device.
- self.caller = self.android_devices[0]
- self.callee = self.android_devices[1]
self.message_lengths = (50, 160, 180)
- is_roaming = False
- for ad in self.android_devices:
- ad.sms_over_wifi = False
- # verizon supports sms over wifi. will add more carriers later
- for sub in ad.telephony["subscription"].values():
- if sub["operator"] in SMS_OVER_WIFI_PROVIDERS:
- ad.sms_over_wifi = True
- if getattr(ad, 'roaming', False):
- is_roaming = True
- if is_roaming:
- # roaming device does not allow message of length 180
- self.message_lengths = (50, 160)
+ self.message_util = self.user_params.get("message_apk", None)
+ if isinstance(self.message_util, list):
+ self.message_util = self.message_util[0]
+
+ if self.message_util:
+ ads = self.android_devices
+ for ad in ads:
+ install_message_apk(ad, self.message_util)
def teardown_test(self):
ensure_phones_idle(self.log, self.android_devices)
- def _mo_sms_in_3g_call(self, ads):
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- self.caller,
- self.callee,
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_3g,
- verify_callee_func=None):
- return False
-
- if not _sms_test_mo(self.log, ads):
- self.log.error("SMS test fail.")
- return False
-
- return True
-
- def _mt_sms_in_3g_call(self, ads):
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- self.caller,
- self.callee,
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_3g,
- verify_callee_func=None):
- return False
-
- if not _sms_test_mt(self.log, ads):
- self.log.error("SMS test fail.")
- return False
-
- return True
-
- def _mo_mms_in_3g_call(self, ads, wifi=False):
- return test_mms_mo_in_call(self.log, ads, wifi=wifi, caller_func=is_phone_in_call_3g)
-
- def _mt_mms_in_3g_call(self, ads, wifi=False):
- self.log.info("Begin In Call MMS Test.")
- if not call_setup_teardown(
- self.log,
- self.caller,
- self.callee,
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_3g,
- verify_callee_func=None):
- return False
-
- if ads[0].sms_over_wifi and wifi:
- return _mms_test_mt(self.log, ads)
+ def _get_wfc_mode(self, ad):
+ # Verizon doesn't supports wfc mode as WFC_MODE_WIFI_PREFERRED
+ carrier = ad.adb.getprop("gsm.sim.operator.alpha")
+ if carrier == CARRIER_VZW:
+ wfc = WFC_MODE_CELLULAR_PREFERRED
else:
- return _mms_test_mt_after_call_hangup(self.log, ads)
+ wfc = WFC_MODE_WIFI_PREFERRED
+ return wfc
- def _mo_sms_in_2g_call(self, ads):
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- self.caller,
- self.callee,
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_2g,
- verify_callee_func=None):
- return False
+ def check_band_support(self,ad):
+ carrier = ad.adb.getprop("gsm.sim.operator.alpha")
- if not _sms_test_mo(self.log, ads):
- self.log.error("SMS test fail.")
- return False
-
- return True
-
- def _mt_sms_in_2g_call(self, ads):
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- self.caller,
- self.callee,
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_2g,
- verify_callee_func=None):
- return False
-
- if not _sms_test_mt(self.log, ads):
- self.log.error("SMS test fail.")
- return False
-
- return True
-
- def _mo_mms_in_2g_call(self, ads, wifi=False):
- return test_mms_mo_in_call(self.log, ads, wifi=wifi, caller_func=is_phone_in_call_2g)
-
- def _mt_mms_in_2g_call(self, ads, wifi=False):
- self.log.info("Begin In Call MMS Test.")
- if not call_setup_teardown(
- self.log,
- self.caller,
- self.callee,
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_2g,
- verify_callee_func=None):
- return False
-
- if ads[0].sms_over_wifi and wifi:
- return _mms_test_mt(self.log, ads)
- else:
- return _mms_test_mt_after_call_hangup(self.log, ads)
-
- def _mo_sms_in_csfb_call(self, ads):
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- self.caller,
- self.callee,
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_csfb,
- verify_callee_func=None):
- return False
-
- if not _sms_test_mo(self.log, ads):
- self.log.error("SMS test fail.")
- return False
-
- return True
-
- def _mt_sms_in_csfb_call(self, ads):
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- self.caller,
- self.callee,
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_csfb,
- verify_callee_func=None):
- return False
-
- if not _sms_test_mt(self.log, ads):
- self.log.error("SMS test fail.")
- return False
-
- return True
-
- def _mo_mms_in_csfb_call(self, ads, wifi=False):
- return test_mms_mo_in_call(self.log, ads, wifi, caller_func=is_phone_in_call_csfb)
-
- def _mt_mms_in_csfb_call(self, ads, wifi=False):
- self.log.info("Begin In Call MMS Test.")
- if not call_setup_teardown(
- self.log,
- self.caller,
- self.callee,
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_csfb,
- verify_callee_func=None):
- return False
-
- if ads[0].sms_over_wifi and wifi:
- return _mms_test_mt(self.log, ads)
- else:
- return _mms_test_mt_after_call_hangup(self.log, ads)
+ if int(ad.adb.getprop("ro.product.first_api_level")) > 30 and (
+ carrier == CARRIER_VZW):
+ raise signals.TestSkip(
+ "Device Doesn't Support 2g/3G Band.")
def _sms_in_collision_test(self, ads):
for length in self.message_lengths:
@@ -326,16 +137,12 @@
True if success.
False if failed.
"""
- ads = self.android_devices
-
- tasks = [(ensure_phone_default_state, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _sms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='default',
+ mt_rat='default')
@test_tracker_info(uuid="aa87fe73-8236-44c7-865c-3fe3b733eeb4")
@TelephonyBaseTest.tel_test_wrap
@@ -350,15 +157,12 @@
True if success.
False if failed.
"""
- ads = self.android_devices
-
- tasks = [(ensure_phone_default_state, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- return _sms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='default')
@test_tracker_info(uuid="bb8e1a06-a4b5-4f9b-9ab2-408ace9a1deb")
@TelephonyBaseTest.tel_test_wrap
@@ -373,16 +177,13 @@
True if success.
False if failed.
"""
- ads = self.android_devices
-
- tasks = [(ensure_phone_default_state, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _mms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='default',
+ mt_rat='default',
+ msg_type='mms')
@test_tracker_info(uuid="f2779e1e-7d09-43f0-8b5c-87eae5d146be")
@TelephonyBaseTest.tel_test_wrap
@@ -397,15 +198,13 @@
True if success.
False if failed.
"""
- ads = self.android_devices
-
- tasks = [(ensure_phone_default_state, (self.log, ads[0])),
- (ensure_phone_default_state, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- return _mms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='default',
+ mt_rat='default',
+ msg_type='mms')
@test_tracker_info(uuid="2c229a4b-c954-4ba3-94ba-178dc7784d03")
@TelephonyBaseTest.tel_test_wrap
@@ -420,16 +219,13 @@
True if success.
False if failed.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _sms_test_mo(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='2g',
+ mt_rat='general')
@test_tracker_info(uuid="17fafc41-7e12-47ab-a4cc-fb9bd94e79b9")
@TelephonyBaseTest.tel_test_wrap
@@ -444,16 +240,13 @@
True if success.
False if failed.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _sms_test_mt(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='2g')
@test_tracker_info(uuid="b4919317-18b5-483c-82f4-ced37a04f28d")
@TelephonyBaseTest.tel_test_wrap
@@ -468,16 +261,14 @@
True if success.
False if failed.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _mms_test_mo(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='2g',
+ mt_rat='general',
+ msg_type='mms')
@test_tracker_info(uuid="cd56bb8a-0794-404d-95bd-c5fd00f4b35a")
@TelephonyBaseTest.tel_test_wrap
@@ -492,16 +283,14 @@
True if success.
False if failed.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _mms_test_mt(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='2g',
+ msg_type='mms')
@test_tracker_info(uuid="b39fbc30-9cc2-4d86-a9f4-6f0c1dd0a905")
@TelephonyBaseTest.tel_test_wrap
@@ -517,16 +306,16 @@
True if success.
False if failed.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone failed to set up 2G.")
- return False
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
- return _mms_test_mo(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='2g',
+ mt_rat='general',
+ msg_type='mms',
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="b158a0a7-9697-4b3b-8d5b-f9b6b6bc1c03")
@TelephonyBaseTest.tel_test_wrap
@@ -542,17 +331,16 @@
True if success.
False if failed.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone failed to set up 2G.")
- return False
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
-
- return _mms_test_mt(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='2g',
+ msg_type='mms',
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="f094e3da-2523-4f92-a1f3-7cf9edcff850")
@TelephonyBaseTest.tel_test_wrap
@@ -567,16 +355,13 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- return _sms_test_mo(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='3g',
+ mt_rat='general')
@test_tracker_info(uuid="2186e152-bf83-4d6e-93eb-b4bf9ae2d76e")
@TelephonyBaseTest.tel_test_wrap
@@ -591,17 +376,13 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _sms_test_mt(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='3g')
@test_tracker_info(uuid="e716c678-eee9-4a0d-a9cd-ca9eae4fea51")
@TelephonyBaseTest.tel_test_wrap
@@ -616,17 +397,14 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _mms_test_mo(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='3g',
+ mt_rat='general',
+ msg_type='mms')
@test_tracker_info(uuid="e864a99e-d935-4bd9-95f6-8183cdd3d760")
@TelephonyBaseTest.tel_test_wrap
@@ -641,17 +419,14 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _mms_test_mt(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='3g',
+ msg_type='mms')
@test_tracker_info(uuid="07cdfe26-9021-4af3-8bf6-1abd0cb9e932")
@TelephonyBaseTest.tel_test_wrap
@@ -666,16 +441,14 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- return _long_sms_test_mo(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='3g',
+ mt_rat='general',
+ long_msg=True)
@test_tracker_info(uuid="740efe0d-fef9-42bc-a732-fe79a3485426")
@TelephonyBaseTest.tel_test_wrap
@@ -690,17 +463,14 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_sms_test_mt(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='3g',
+ long_msg=True)
@test_tracker_info(uuid="b0d27de3-1a98-48da-a9c9-c20c8587f256")
@TelephonyBaseTest.tel_test_wrap
@@ -715,17 +485,15 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_mms_test_mo(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='3g',
+ mt_rat='general',
+ msg_type='mms',
+ long_msg=True)
@test_tracker_info(uuid="fd5a1583-94d2-4b3a-b613-a0a9745daa25")
@TelephonyBaseTest.tel_test_wrap
@@ -740,17 +508,15 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_mms_test_mt(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='3g',
+ msg_type='mms',
+ long_msg=True)
@test_tracker_info(uuid="c6cfba55-6cde-41cd-93bb-667c317a0127")
@TelephonyBaseTest.tel_test_wrap
@@ -766,18 +532,16 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
-
- return _mms_test_mo(self.log, ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='3g',
+ mt_rat='general',
+ msg_type='mms',
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="83c5dd99-f2fe-433d-9775-80a36d0d493b")
@TelephonyBaseTest.tel_test_wrap
@@ -793,19 +557,16 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])), (phone_setup_3g,
- (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
-
- return _mms_test_mt(self.log, ads)
-
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='3g',
+ msg_type='mms',
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="54a68d6a-dae7-4fe6-b2bb-7c73151a4a73")
@TelephonyBaseTest.tel_test_wrap
@@ -820,17 +581,12 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_volte, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _sms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='volte',
+ mt_rat='general')
@test_tracker_info(uuid="d0adcd69-37fc-49d1-8dd3-c03dd163fb25")
@TelephonyBaseTest.tel_test_wrap
@@ -845,17 +601,12 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_volte, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _sms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='volte')
@test_tracker_info(uuid="8d454a25-a1e5-4872-8193-d435a84d54fa")
@TelephonyBaseTest.tel_test_wrap
@@ -870,17 +621,13 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_volte, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _mms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='volte',
+ mt_rat='general',
+ msg_type='mms')
@test_tracker_info(uuid="79b8239e-9e6a-4781-942b-2df5b060718d")
@TelephonyBaseTest.tel_test_wrap
@@ -895,17 +642,13 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_volte, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _mms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='volte',
+ msg_type='mms')
@test_tracker_info(uuid="5b9e1195-1e42-4405-890f-631e8c58d0c2")
@TelephonyBaseTest.tel_test_wrap
@@ -920,17 +663,13 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_volte, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_sms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='volte',
+ mt_rat='general',
+ long_msg=True)
@test_tracker_info(uuid="c328cbe7-1899-4ca8-af1c-5eb05683a322")
@TelephonyBaseTest.tel_test_wrap
@@ -945,17 +684,13 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_volte, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_sms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='volte',
+ long_msg=True)
@test_tracker_info(uuid="a843c2f7-e4de-4b99-b3a9-f05ecda5fe73")
@TelephonyBaseTest.tel_test_wrap
@@ -970,17 +705,14 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_volte, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_mms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='volte',
+ mt_rat='general',
+ msg_type='mms',
+ long_msg=True)
@test_tracker_info(uuid="26dcba4d-7ddb-438d-84e7-0e754178b5ef")
@TelephonyBaseTest.tel_test_wrap
@@ -995,17 +727,14 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_volte, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_mms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='volte',
+ msg_type='mms',
+ long_msg=True)
@test_tracker_info(uuid="c97687e2-155a-4cf3-9f51-22543b89d53e")
@TelephonyBaseTest.tel_test_wrap
@@ -1020,16 +749,12 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _sms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='csfb',
+ mt_rat='general')
@test_tracker_info(uuid="e2e01a47-2b51-4d00-a7b2-dbd3c8ffa6ae")
@TelephonyBaseTest.tel_test_wrap
@@ -1044,15 +769,12 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
-
- return _sms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='csfb')
@test_tracker_info(uuid="90fc6775-de19-49d1-8b8e-e3bc9384c733")
@TelephonyBaseTest.tel_test_wrap
@@ -1067,17 +789,13 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _mms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='csfb',
+ mt_rat='general',
+ msg_type='mms')
@test_tracker_info(uuid="274572bb-ec9f-4c30-aab4-1f4c3f16b372")
@TelephonyBaseTest.tel_test_wrap
@@ -1092,17 +810,13 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _mms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='csfb',
+ msg_type='mms')
@test_tracker_info(uuid="44392814-98dd-406a-ae82-5c39e2d082f3")
@TelephonyBaseTest.tel_test_wrap
@@ -1117,16 +831,13 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_sms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='csfb',
+ mt_rat='general',
+ long_msg=True)
@test_tracker_info(uuid="0f8358a5-a7d5-4dfa-abe0-99fb8b10d48d")
@TelephonyBaseTest.tel_test_wrap
@@ -1141,15 +852,13 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
-
- return _long_sms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='csfb',
+ long_msg=True)
@test_tracker_info(uuid="18edde2b-7db9-40f4-96c4-3286a56d090b")
@TelephonyBaseTest.tel_test_wrap
@@ -1164,17 +873,14 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_mms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='csfb',
+ mt_rat='general',
+ msg_type='mms',
+ long_msg=True)
@test_tracker_info(uuid="49805d08-6f1f-4c90-9bf4-e9acd6f63640")
@TelephonyBaseTest.tel_test_wrap
@@ -1189,17 +895,14 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_mms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='csfb',
+ msg_type='mms',
+ long_msg=True)
@test_tracker_info(uuid="c7349fdf-a376-4846-b466-1f329bd1557f")
@TelephonyBaseTest.tel_test_wrap
@@ -1215,18 +918,15 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
- return _mms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='csfb',
+ mt_rat='general',
+ msg_type='mms',
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="1affab34-e03c-49dd-9062-e9ed8eac406b")
@TelephonyBaseTest.tel_test_wrap
@@ -1242,19 +942,15 @@
True if success.
False if failed.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
-
- return _mms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='csfb',
+ msg_type='mms',
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="7ee57edb-2962-4d20-b6eb-79cebce91fff")
@TelephonyBaseTest.tel_test_wrap
@@ -1268,27 +964,13 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- if not provision_both_devices_for_volte(self.log, ads):
- return False
-
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_volte,
- verify_callee_func=None):
- return False
-
- if not _sms_test_mo(self.log, ads):
- self.log.error("SMS test fail.")
- return False
-
- return True
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='volte',
+ mt_rat='general',
+ msg_in_call=True)
@test_tracker_info(uuid="5576276b-4ca1-41cc-bb74-31ccd71f9f96")
@TelephonyBaseTest.tel_test_wrap
@@ -1302,26 +984,13 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- if not provision_both_devices_for_volte(self.log, ads):
- return False
-
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_volte,
- verify_callee_func=None):
- return False
-
- if not _sms_test_mt(self.log, ads):
- self.log.error("SMS test fail.")
- return False
- return True
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='volte',
+ msg_in_call=True)
@test_tracker_info(uuid="3bf8ff74-baa6-4dc6-86eb-c13816fa9bc8")
@TelephonyBaseTest.tel_test_wrap
@@ -1335,27 +1004,14 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- if not provision_both_devices_for_volte(self.log, ads):
- return False
-
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_volte,
- verify_callee_func=None):
- return False
-
- if not _mms_test_mo(self.log, ads):
- self.log.error("MMS test fail.")
- return False
-
- return True
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='volte',
+ mt_rat='general',
+ msg_type='mms',
+ msg_in_call=True)
@test_tracker_info(uuid="289e6516-5f66-403a-b292-50d067151730")
@TelephonyBaseTest.tel_test_wrap
@@ -1369,27 +1025,14 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- if not provision_both_devices_for_volte(self.log, ads):
- return False
-
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- self.log.info("Begin In Call MMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_volte,
- verify_callee_func=None):
- return False
-
- if not _mms_test_mt(self.log, ads):
- self.log.error("MMS test fail.")
- return False
-
- return True
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='volte',
+ msg_type='mms',
+ msg_in_call=True)
@test_tracker_info(uuid="5654d974-3c32-4cce-9d07-0c96213dacc5")
@TelephonyBaseTest.tel_test_wrap
@@ -1404,29 +1047,16 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- if not provision_both_devices_for_volte(self.log, ads):
- return False
-
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_volte,
- verify_callee_func=None):
- return False
-
- if not _mms_test_mo(self.log, ads):
- self.log.error("MMS test fail.")
- return False
-
- return True
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='volte',
+ mt_rat='general',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="cbd5ab3d-d76a-4ece-ac09-62efeead7550")
@TelephonyBaseTest.tel_test_wrap
@@ -1441,29 +1071,16 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- if not provision_both_devices_for_volte(self.log, ads):
- return False
-
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
- self.log.info("Begin In Call MMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_volte,
- verify_callee_func=None):
- return False
-
- if not _mms_test_mt(self.log, ads):
- self.log.error("MMS test fail.")
- return False
-
- return True
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='volte',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="b6e9ce80-8577-48e5-baa7-92780932f278")
@TelephonyBaseTest.tel_test_wrap
@@ -1477,16 +1094,13 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return self._mo_sms_in_csfb_call(ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='csfb',
+ mt_rat='general',
+ msg_in_call=True)
@test_tracker_info(uuid="93f0b58a-01e9-4bc9-944f-729d455597dd")
@TelephonyBaseTest.tel_test_wrap
@@ -1500,16 +1114,13 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return self._mt_sms_in_csfb_call(ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='csfb',
+ msg_in_call=True)
@test_tracker_info(uuid="bd8e9e80-1955-429f-b122-96b127771bbb")
@TelephonyBaseTest.tel_test_wrap
@@ -1523,16 +1134,14 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return self._mo_mms_in_csfb_call(ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='csfb',
+ mt_rat='general',
+ msg_type='mms',
+ msg_in_call=True)
@test_tracker_info(uuid="89d65fd2-fc75-4fc5-a018-2d05a4364304")
@TelephonyBaseTest.tel_test_wrap
@@ -1546,16 +1155,14 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return self._mt_mms_in_csfb_call(ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='csfb',
+ msg_type='mms',
+ msg_in_call=True)
@test_tracker_info(uuid="9c542b5d-3b8f-4d4a-80de-fb804f066c3d")
@TelephonyBaseTest.tel_test_wrap
@@ -1570,18 +1177,16 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
-
- return self._mo_mms_in_csfb_call(ads, wifi=True)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='csfb',
+ mt_rat='general',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="c1bed6f5-f65c-4f4d-aa06-0e9f5c867819")
@TelephonyBaseTest.tel_test_wrap
@@ -1596,18 +1201,16 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_csfb, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
-
- return self._mt_mms_in_csfb_call(ads, wifi=True)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='csfb',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="60996028-b4b2-4a16-9e4b-eb6ef80179a7")
@TelephonyBaseTest.tel_test_wrap
@@ -1621,16 +1224,14 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return self._mo_sms_in_3g_call(ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='3g',
+ mt_rat='general',
+ msg_in_call=True)
@test_tracker_info(uuid="6b352aac-9b4e-4062-8980-3b1c0e61015b")
@TelephonyBaseTest.tel_test_wrap
@@ -1644,16 +1245,14 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return self._mt_sms_in_3g_call(ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='3g',
+ msg_in_call=True)
@test_tracker_info(uuid="cfae3613-c490-4ce0-b00b-c13286d85027")
@TelephonyBaseTest.tel_test_wrap
@@ -1668,16 +1267,15 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return self._mo_mms_in_3g_call(ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='3g',
+ mt_rat='general',
+ msg_type='mms',
+ msg_in_call=True)
@test_tracker_info(uuid="42fc8c16-4a30-4f63-9728-2639f2b79c4c")
@TelephonyBaseTest.tel_test_wrap
@@ -1691,16 +1289,15 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return self._mt_mms_in_3g_call(ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='3g',
+ msg_type='mms',
+ msg_in_call=True)
@test_tracker_info(uuid="18093f87-aab5-4d86-b178-8085a1651828")
@TelephonyBaseTest.tel_test_wrap
@@ -1715,18 +1312,17 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
-
- return self._mo_mms_in_3g_call(ads, wifi=True)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='3g',
+ mt_rat='general',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="8fe3359a-0857-401f-a043-c47a2a2acb47")
@TelephonyBaseTest.tel_test_wrap
@@ -1740,25 +1336,24 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_3g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
-
- return self._mt_mms_in_3g_call(ads, wifi=True)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='3g',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="ed720013-e366-448b-8901-bb09d26cea05")
@TelephonyBaseTest.tel_test_wrap
def test_sms_mo_iwlan(self):
""" Test MO SMS, Phone in APM, WiFi connected, WFC Cell Preferred mode.
- Make sure PhoneA APM, WiFi connected, WFC Cell preferred mode.
+ Make sure PhoneA APM, WiFi connected, WFC cellular preferred mode.
Make sure PhoneA report iwlan as data rat.
Make sure PhoneB is able to make/receive call/sms.
Send SMS on PhoneA.
@@ -1766,26 +1361,23 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], True, WFC_MODE_CELLULAR_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _sms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='wfc',
+ mt_rat='general',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="4d4b0b7b-bf00-44f6-a0ed-23b438c30fc2")
@TelephonyBaseTest.tel_test_wrap
def test_sms_mt_iwlan(self):
""" Test MT SMS, Phone in APM, WiFi connected, WFC Cell Preferred mode.
- Make sure PhoneA APM, WiFi connected, WFC WiFi preferred mode.
+ Make sure PhoneA APM, WiFi connected, WFC cellular preferred mode.
Make sure PhoneA report iwlan as data rat.
Make sure PhoneB is able to make/receive call/sms.
Receive SMS on PhoneA.
@@ -1793,19 +1385,16 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], True, WFC_MODE_CELLULAR_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _sms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='wfc',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="264e2557-e18c-41c0-8d99-49cee3fe6f07")
@TelephonyBaseTest.tel_test_wrap
@@ -1820,19 +1409,17 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], True, WFC_MODE_CELLULAR_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _mms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='wfc',
+ mt_rat='general',
+ msg_type='mms',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="330db618-f074-4bfc-bf5e-78939fbee532")
@TelephonyBaseTest.tel_test_wrap
@@ -1847,19 +1434,17 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], True, WFC_MODE_CELLULAR_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _mms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='wfc',
+ msg_type='mms',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="875ce520-7a09-4032-8e88-965ce143c1f5")
@TelephonyBaseTest.tel_test_wrap
@@ -1874,19 +1459,18 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], True, WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_sms_test_mo(self.log, ads)
+ _wfc_mode = self._get_wfc_mode(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='wfc',
+ mt_rat='general',
+ long_msg=True,
+ is_airplane_mode=True,
+ wfc_mode=_wfc_mode,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="a317a1b3-16c8-4c2d-bbfd-aebcc0897499")
@TelephonyBaseTest.tel_test_wrap
@@ -1901,19 +1485,18 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], True, WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_sms_test_mt(self.log, ads)
+ _wfc_mode = self._get_wfc_mode(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='wfc',
+ long_msg=True,
+ is_airplane_mode=True,
+ wfc_mode=_wfc_mode,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="d692c439-6e96-45a6-be0f-1ff81226416c")
@TelephonyBaseTest.tel_test_wrap
@@ -1928,19 +1511,19 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], True, WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_mms_test_mo(self.log, ads)
+ _wfc_mode = self._get_wfc_mode(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='wfc',
+ mt_rat='general',
+ msg_type='mms',
+ long_msg=True,
+ is_airplane_mode=True,
+ wfc_mode=_wfc_mode,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="a0958a1b-23ea-4353-9af6-7bc5d6a0a3d2")
@TelephonyBaseTest.tel_test_wrap
@@ -1955,19 +1538,19 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], True, WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _long_mms_test_mt(self.log, ads)
+ _wfc_mode = self._get_wfc_mode(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='wfc',
+ msg_type='mms',
+ long_msg=True,
+ is_airplane_mode=True,
+ wfc_mode=_wfc_mode,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="94bb8297-f646-4793-9d97-6f82a706127a")
@TelephonyBaseTest.tel_test_wrap
@@ -1982,19 +1565,16 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], False, WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _sms_test_mo(self.log, ads)
+ _wfc_mode = self._get_wfc_mode(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='wfc',
+ mt_rat='general',
+ wfc_mode=_wfc_mode,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="e4acce6a-75ae-45c1-be85-d3a2eb2da7c2")
@TelephonyBaseTest.tel_test_wrap
@@ -2009,19 +1589,16 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], False, WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _sms_test_mt(self.log, ads)
+ _wfc_mode = self._get_wfc_mode(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='wfc',
+ wfc_mode=_wfc_mode,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="6c003c28-5712-4456-89cb-64d417ab2ce4")
@TelephonyBaseTest.tel_test_wrap
@@ -2036,19 +1613,17 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], False, WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _mms_test_mo(self.log, ads)
+ _wfc_mode = self._get_wfc_mode(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='wfc',
+ mt_rat='general',
+ msg_type='mms',
+ wfc_mode=_wfc_mode,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="0ac5c8ff-83e5-49f2-ba71-ebb283feed9e")
@TelephonyBaseTest.tel_test_wrap
@@ -2063,18 +1638,17 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], False, WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- return _mms_test_mt(self.log, ads)
+ _wfc_mode = self._get_wfc_mode(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='wfc',
+ msg_type='mms',
+ wfc_mode=_wfc_mode,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="075933a2-df7f-4374-a405-92f96bcc7770")
@TelephonyBaseTest.tel_test_wrap
@@ -2088,21 +1662,16 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
- if not set_wfc_mode(self.log, ads[0], WFC_MODE_DISABLED):
- return False
- phone_setup_voice_general(self.log, ads[0])
- tasks = [(ensure_wifi_connected,
- (self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass, 3, True)), (phone_setup_voice_general,
- (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _sms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='wfc',
+ mt_rat='general',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_DISABLED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="637af228-29fc-4b74-a963-883f66ddf080")
@TelephonyBaseTest.tel_test_wrap
@@ -2116,21 +1685,16 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
- if not set_wfc_mode(self.log, ads[0], WFC_MODE_DISABLED):
- return False
- phone_setup_voice_general(self.log, ads[0])
- tasks = [(ensure_wifi_connected,
- (self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass, 3, True)), (phone_setup_voice_general,
- (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _sms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='wfc',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_DISABLED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="502aba0d-8895-4807-b394-50a44208ecf7")
@TelephonyBaseTest.tel_test_wrap
@@ -2144,21 +1708,17 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
- if not set_wfc_mode(self.log, ads[0], WFC_MODE_DISABLED):
- return False
- phone_setup_voice_general(self.log, ads[0])
- tasks = [(ensure_wifi_connected,
- (self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass, 3, True)), (phone_setup_voice_general,
- (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return _mms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='wfc',
+ mt_rat='general',
+ msg_type='mms',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_DISABLED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="235bfdbf-4275-4d89-99f5-41b5b7de8345")
@TelephonyBaseTest.tel_test_wrap
@@ -2172,20 +1732,17 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
- if not set_wfc_mode(self.log, ads[0], WFC_MODE_DISABLED):
- return False
- phone_setup_voice_general(self.log, ads[0])
- tasks = [(ensure_wifi_connected,
- (self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass, 3, True)), (phone_setup_voice_general,
- (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- return _mms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='wfc',
+ msg_type='mms',
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_DISABLED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="e5a31b94-1cb6-4770-a2bc-5a0ddba51502")
@TelephonyBaseTest.tel_test_wrap
@@ -2201,29 +1758,18 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], True, WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_iwlan,
- verify_callee_func=None):
- return False
-
- return _sms_test_mo(self.log, ads)
+ _wfc_mode = self._get_wfc_mode(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='wfc',
+ mt_rat='general',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=_wfc_mode,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="d6d30cc5-f75b-42df-b517-401456ee8466")
@TelephonyBaseTest.tel_test_wrap
@@ -2239,29 +1785,18 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], True, WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_iwlan,
- verify_callee_func=None):
- return False
-
- return _sms_test_mt(self.log, ads)
+ _wfc_mode = self._get_wfc_mode(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='wfc',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=_wfc_mode,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="a98a5a97-3864-4ff8-9085-995212eada20")
@TelephonyBaseTest.tel_test_wrap
@@ -2277,29 +1812,19 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], True, WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- self.log.info("Begin In Call MMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_iwlan,
- verify_callee_func=None):
- return False
-
- return _mms_test_mo(self.log, ads)
+ _wfc_mode = self._get_wfc_mode(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='wfc',
+ mt_rat='general',
+ msg_type='mms',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=_wfc_mode,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="0464a87b-d45b-4b03-9895-17ece360a796")
@TelephonyBaseTest.tel_test_wrap
@@ -2315,29 +1840,19 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan,
- (self.log, ads[0], True, WFC_MODE_WIFI_PREFERRED,
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- self.log.info("Begin In Call MMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_iwlan,
- verify_callee_func=None):
- return False
-
- return _mms_test_mt(self.log, ads)
+ _wfc_mode = self._get_wfc_mode(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='wfc',
+ msg_type='mms',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=_wfc_mode,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="029e05cd-df6b-4a82-8402-77fc6eadf66f")
@TelephonyBaseTest.tel_test_wrap
@@ -2353,29 +1868,17 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan_cellular_preferred,
- (self.log, ads[0],
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_not_iwlan,
- verify_callee_func=None):
- return False
-
- return _sms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='wfc',
+ mt_rat='general',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="c3c47a68-a839-4470-87f6-e85496cfab23")
@TelephonyBaseTest.tel_test_wrap
@@ -2391,29 +1894,17 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan_cellular_preferred,
- (self.log, ads[0],
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_not_iwlan,
- verify_callee_func=None):
- return False
-
- return _sms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='wfc',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="4c6cd913-4aca-4f2b-b33b-1efe0a7dc11d")
@TelephonyBaseTest.tel_test_wrap
@@ -2429,29 +1920,18 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan_cellular_preferred,
- (self.log, ads[0],
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- self.log.info("Begin In Call MMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_not_iwlan,
- verify_callee_func=None):
- return False
-
- return _mms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='wfc',
+ mt_rat='general',
+ msg_type='mms',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="5b667ca1-cafd-47d4-86dc-8b87232ddcfa")
@TelephonyBaseTest.tel_test_wrap
@@ -2467,29 +1947,18 @@
Returns:
True if pass; False if fail.
"""
-
- ads = self.android_devices
-
- tasks = [(phone_setup_iwlan_cellular_preferred,
- (self.log, ads[0],
- self.wifi_network_ssid, self.wifi_network_pass)),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- self.log.info("Begin In Call MMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_not_iwlan,
- verify_callee_func=None):
- return False
-
- return _mms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='wfc',
+ msg_type='mms',
+ msg_in_call=True,
+ is_airplane_mode=True,
+ wfc_mode=WFC_MODE_CELLULAR_PREFERRED,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="9f1933bb-c4cb-4655-8655-327c1f38e8ee")
@TelephonyBaseTest.tel_test_wrap
@@ -2503,27 +1972,14 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_video, (self.log, ads[0])), (phone_setup_video,
- (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not video_call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- None,
- video_state=VT_STATE_BIDIRECTIONAL,
- verify_caller_func=is_phone_in_call_video_bidirectional,
- verify_callee_func=is_phone_in_call_video_bidirectional):
- self.log.error("Failed to setup a call")
- return False
-
- return _sms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='volte',
+ mt_rat='volte',
+ msg_in_call=True,
+ video_or_voice='video')
@test_tracker_info(uuid="0a07e737-4862-4492-9b48-8d94799eab91")
@TelephonyBaseTest.tel_test_wrap
@@ -2537,27 +1993,14 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_video, (self.log, ads[0])), (phone_setup_video,
- (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not video_call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- None,
- video_state=VT_STATE_BIDIRECTIONAL,
- verify_caller_func=is_phone_in_call_video_bidirectional,
- verify_callee_func=is_phone_in_call_video_bidirectional):
- self.log.error("Failed to setup a call")
- return False
-
- return _sms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='volte',
+ mt_rat='volte',
+ msg_in_call=True,
+ video_or_voice='video')
@test_tracker_info(uuid="55d70548-6aee-40e9-b94d-d10de84fb50f")
@TelephonyBaseTest.tel_test_wrap
@@ -2571,27 +2014,15 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_video, (self.log, ads[0])), (phone_setup_video,
- (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not video_call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- None,
- video_state=VT_STATE_BIDIRECTIONAL,
- verify_caller_func=is_phone_in_call_video_bidirectional,
- verify_callee_func=is_phone_in_call_video_bidirectional):
- self.log.error("Failed to setup a call")
- return False
-
- return _mms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='volte',
+ mt_rat='volte',
+ msg_type='mms',
+ msg_in_call=True,
+ video_or_voice='video')
@test_tracker_info(uuid="75f97c9a-4397-42f1-bb00-8fc6d04fdf6d")
@TelephonyBaseTest.tel_test_wrap
@@ -2605,27 +2036,15 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
-
- tasks = [(phone_setup_video, (self.log, ads[0])), (phone_setup_video,
- (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- if not video_call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- None,
- video_state=VT_STATE_BIDIRECTIONAL,
- verify_caller_func=is_phone_in_call_video_bidirectional,
- verify_callee_func=is_phone_in_call_video_bidirectional):
- self.log.error("Failed to setup a call")
- return False
-
- return _mms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='volte',
+ mt_rat='volte',
+ msg_type='mms',
+ msg_in_call=True,
+ video_or_voice='video')
@test_tracker_info(uuid="2a72ecc6-702d-4add-a7a2-8c1001628bb6")
@TelephonyBaseTest.tel_test_wrap
@@ -2639,33 +2058,14 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
- # Make sure PhoneA is GSM phone before proceed.
- if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
- raise signals.TestSkip("Not GSM phone, abort this GSM SMS test.")
-
- tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_2g,
- verify_callee_func=None):
- return False
-
- if not _sms_test_mo(self.log, ads):
- self.log.error("SMS test fail.")
- return False
-
- return True
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='2g',
+ mt_rat='general',
+ msg_in_call=True)
@test_tracker_info(uuid="facd1814-8d69-42a2-9f80-b6a28cc0c9d2")
@TelephonyBaseTest.tel_test_wrap
@@ -2679,33 +2079,14 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
- # Make sure PhoneA is GSM phone before proceed.
- if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
- raise signals.TestSkip("Not GSM phone, abort this GSM SMS test.")
-
- tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- self.log.info("Begin In Call SMS Test.")
- if not call_setup_teardown(
- self.log,
- ads[0],
- ads[1],
- ad_hangup=None,
- verify_caller_func=is_phone_in_call_2g,
- verify_callee_func=None):
- return False
-
- if not _sms_test_mt(self.log, ads):
- self.log.error("SMS test fail.")
- return False
-
- return True
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='2g',
+ msg_in_call=True)
@test_tracker_info(uuid="2bd94d69-3621-4b94-abc7-bd24c4325485")
@TelephonyBaseTest.tel_test_wrap
@@ -2719,19 +2100,15 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
- # Make sure PhoneA is GSM phone before proceed.
- if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
- raise signals.TestSkip("Not GSM phone, abort this GSM SMS test.")
-
- tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return self._mo_mms_in_2g_call(ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='2g',
+ mt_rat='general',
+ msg_type='mms',
+ msg_in_call=True)
@test_tracker_info(uuid="e20be70d-99d6-4344-a742-f69581b66d8f")
@TelephonyBaseTest.tel_test_wrap
@@ -2745,19 +2122,15 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
- # Make sure PhoneA is GSM phone before proceed.
- if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
- raise signals.TestSkip("Not GSM phone, abort this GSM MMS test.")
-
- tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
-
- return self._mt_mms_in_2g_call(ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='2g',
+ msg_type='mms',
+ msg_in_call=True)
@test_tracker_info(uuid="3510d368-4b16-4716-92a3-9dd01842ba79")
@TelephonyBaseTest.tel_test_wrap
@@ -2771,21 +2144,17 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
- # Make sure PhoneA is GSM phone before proceed.
- if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
- raise signals.TestSkip("Not GSM phone, abort this GSM MMS test.")
-
- tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
-
- return self._mo_mms_in_2g_call(ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[0],
+ self.android_devices[1],
+ mo_rat='2g',
+ mt_rat='general',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="060def89-01bd-4b44-a49b-a4536fe39165")
@TelephonyBaseTest.tel_test_wrap
@@ -2799,21 +2168,17 @@
Returns:
True if pass; False if fail.
"""
- ads = self.android_devices
- # Make sure PhoneA is GSM phone before proceed.
- if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
- raise signals.TestSkip("Not GSM phone, abort this GSM MMS test.")
-
- tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- ensure_wifi_connected(self.log, ads[0], self.wifi_network_ssid,
- self.wifi_network_pass)
-
- return self._mt_mms_in_2g_call(ads)
+ self.check_band_support(self.android_devices[0])
+ return message_test(
+ self.log,
+ self.android_devices[1],
+ self.android_devices[0],
+ mo_rat='general',
+ mt_rat='2g',
+ msg_type='mms',
+ msg_in_call=True,
+ wifi_ssid=self.wifi_network_ssid,
+ wifi_pwd=self.wifi_network_pass)
@test_tracker_info(uuid="7de95a56-8055-4c0c-9438-f249403c6078")
@TelephonyBaseTest.tel_test_wrap
@@ -2835,13 +2200,10 @@
data_usage = get_mobile_data_usage(ads[0], subscriber_id)
set_mobile_data_usage_limit(ads[0], data_usage, subscriber_id)
- tasks = [(phone_setup_voice_general, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- return _sms_test_mo(self.log, ads)
+ return message_test(
+ self.log,
+ ads[0],
+ ads[1])
finally:
remove_mobile_data_usage_limit(ads[0], subscriber_id)
@@ -2865,13 +2227,10 @@
data_usage = get_mobile_data_usage(ads[0], subscriber_id)
set_mobile_data_usage_limit(ads[0], data_usage, subscriber_id)
- tasks = [(phone_setup_voice_general, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
- time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
- return _sms_test_mt(self.log, ads)
+ return message_test(
+ self.log,
+ ads[1],
+ ads[0])
finally:
remove_mobile_data_usage_limit(ads[0], subscriber_id)
@@ -2896,17 +2255,19 @@
ads[0].log.info("Expected Result is %s", expected_result)
try:
- tasks = [(phone_setup_voice_general, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
subscriber_id = ads[0].droid.telephonyGetSubscriberId()
data_usage = get_mobile_data_usage(ads[0], subscriber_id)
set_mobile_data_usage_limit(ads[0], data_usage, subscriber_id)
log_msg = "expecting successful mms receive" if (
expected_result) else "expecting mms receive failure"
- if not _mms_test_mo(self.log, ads, expected_result=expected_result):
+
+ if not message_test(
+ self.log,
+ ads[0],
+ ads[1],
+ msg_type='mms',
+ mms_expected_result=expected_result):
+
ads[0].log.error("Mms test failed, %s", log_msg)
return False
else:
@@ -2933,18 +2294,22 @@
expected_result = False
if get_operator_name(self.log, ads[0]) in ["vzw", "Verizon", "att", "AT&T"]:
expected_result = True
+ ads[0].log.info("Expected Result is %s", expected_result)
+
try:
- tasks = [(phone_setup_voice_general, (self.log, ads[0])),
- (phone_setup_voice_general, (self.log, ads[1]))]
- if not multithread_func(self.log, tasks):
- self.log.error("Phone Failed to Set Up Properly.")
- return False
subscriber_id = ads[0].droid.telephonyGetSubscriberId()
data_usage = get_mobile_data_usage(ads[0], subscriber_id)
set_mobile_data_usage_limit(ads[0], data_usage, subscriber_id)
log_msg = "expecting successful mms receive" if (
expected_result) else "expecting mms receive failure"
- if not _mms_test_mt(self.log, ads, expected_result=expected_result):
+
+ if not message_test(
+ self.log,
+ ads[1],
+ ads[0],
+ msg_type='mms',
+ mms_expected_result=expected_result):
+
ads[0].log.error("Mms test failed, %s", log_msg)
return False
else:
@@ -3004,4 +2369,3 @@
time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
return self._sms_in_collision_when_power_off_test(ads)
-
diff --git a/acts_tests/tests/google/tel/live/TelLiveStressCallTest.py b/acts_tests/tests/google/tel/live/TelLiveStressCallTest.py
index dc7a62e..573ca60 100644
--- a/acts_tests/tests/google/tel/live/TelLiveStressCallTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveStressCallTest.py
@@ -22,38 +22,35 @@
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
-from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import last_call_drop_reason
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
-from acts_contrib.test_utils.tel.tel_test_utils import sms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_logging_utils import start_sdm_loggers
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_2g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts_contrib.test_utils.tel.tel_video_utils import phone_setup_video
+from acts_contrib.test_utils.tel.tel_video_utils import video_call_setup
+from acts_contrib.test_utils.tel.tel_video_utils import is_phone_in_call_video_bidirectional
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_iwlan
-from acts_contrib.test_utils.tel.tel_video_utils import phone_setup_video
-from acts_contrib.test_utils.tel.tel_video_utils import video_call_setup
-from acts_contrib.test_utils.tel.tel_video_utils import \
- is_phone_in_call_video_bidirectional
-from acts.logger import epoch_to_log_line_timestamp
+from acts_contrib.test_utils.tel.tel_voice_utils import last_call_drop_reason
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
from acts.utils import get_current_epoch_time
from acts.utils import rand_ascii_str
+from acts.libs.utils.multithread import multithread_func
class TelLiveStressCallTest(TelephonyBaseTest):
@@ -237,7 +234,10 @@
if not iteration_result:
self._take_bug_report("%s_CallNo_%s" % (self.test_name, i),
begin_time)
- start_qxdm_loggers(self.log, self.android_devices)
+ if self.sdm_log:
+ start_sdm_loggers(self.log, self.android_devices)
+ else:
+ start_qxdm_loggers(self.log, self.android_devices)
if self.sleep_time_between_test_iterations:
self.caller.droid.goToSleepNow()
diff --git a/acts_tests/tests/google/tel/live/TelLiveStressDataTest.py b/acts_tests/tests/google/tel/live/TelLiveStressDataTest.py
index 81e3ece..3eb9d91 100644
--- a/acts_tests/tests/google/tel/live/TelLiveStressDataTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveStressDataTest.py
@@ -16,10 +16,15 @@
"""
Test Script for Telephony Stress data Test
"""
+import collections
+import time
+
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_test_utils import iperf_test_by_adb
from acts_contrib.test_utils.tel.tel_test_utils import iperf_udp_test_by_adb
+from acts.logger import epoch_to_log_line_timestamp
+from acts.utils import get_current_epoch_time
class TelLiveStressDataTest(TelephonyBaseTest):
@@ -28,13 +33,126 @@
self.ad = self.android_devices[0]
self.iperf_server_address = self.user_params.get("iperf_server",
'0.0.0.0')
- self.iperf_srv_tcp_port = self.user_params.get("iperf_server_tcp_port",
- 0)
- self.iperf_srv_udp_port = self.user_params.get("iperf_server_udp_port",
- 0)
- self.test_duration = self.user_params.get("data_stress_duration", 60)
+ self.iperf_tcp_port = int(
+ self.user_params.get("iperf_tcp_port", 0))
+ self.iperf_udp_port = int(
+ self.user_params.get("iperf_udp_port", 0))
+ self.iperf_duration = int(
+ self.user_params.get("iperf_duration", 60))
+ self.iperf_iteration = int(
+ self.user_params.get("iperf_iteration", 10))
+ self.sleep_time_between_iperf_iterations = int(
+ self.user_params.get("sleep_time_between_iperf_iterations", 2))
- return True
+ def stress_test_upload(self, test_tcp=True):
+ """Start the upload iperf stress test.
+
+ Args:
+ test_tcp: True for using TCP, using UDP otherwise.
+
+ Returns:
+ True if success, False if fail.
+ """
+ fail_count = collections.defaultdict(int)
+ for i in range(1, self.iperf_iteration + 1):
+ msg = "Stress Throughput Test %s Iteration: <%s> / <%s>" % (
+ self.test_name, i, self.iperf_iteration)
+ begin_time = get_current_epoch_time()
+ self.log.info(msg)
+ iteration_result = True
+ if test_tcp:
+ if not iperf_test_by_adb(self.log,
+ self.ad,
+ self.iperf_server_address,
+ self.iperf_tcp_port,
+ False,
+ self.iperf_duration):
+ fail_count["upload"] += 1
+ iteration_result = False
+ self.log.error("%s upload failure.", msg)
+ else:
+ if not iperf_udp_test_by_adb(self.log,
+ self.ad,
+ self.iperf_server_address,
+ self.iperf_udp_port,
+ False,
+ self.iperf_duration):
+ fail_count["upload"] += 1
+ iteration_result = False
+ self.log.error("%s upload failure.", msg)
+
+ self.log.info("%s %s", msg, iteration_result)
+ if not iteration_result:
+ self._take_bug_report("%s_UploadNo_%s" % (self.test_name, i),
+ begin_time)
+
+ if self.sleep_time_between_iperf_iterations:
+ self.ad.droid.goToSleepNow()
+ time.sleep(self.sleep_time_between_iperf_iterations)
+
+ test_result = True
+ for failure, count in fail_count.items():
+ if count:
+ self.log.error("%s: %s %s failures in %s iterations",
+ self.test_name, count, failure,
+ self.iperf_iteration)
+ test_result = False
+ return test_result
+
+ def stress_test_download(self, test_tcp=True):
+ """Start the download iperf stress test.
+
+ Args:
+ test_tcp: True for using TCP, using UDP otherwise.
+
+ Returns:
+ True if success, False if fail.
+ """
+ fail_count = collections.defaultdict(int)
+ for i in range(1, self.iperf_iteration + 1):
+ msg = "Stress Throughput Test %s Iteration: <%s> / <%s>" % (
+ self.test_name, i, self.iperf_iteration)
+ begin_time = get_current_epoch_time()
+ self.log.info(msg)
+ iteration_result = True
+ if test_tcp:
+ if not iperf_test_by_adb(self.log,
+ self.ad,
+ self.iperf_server_address,
+ self.iperf_tcp_port,
+ True,
+ self.iperf_duration):
+ fail_count["download"] += 1
+ iteration_result = False
+ self.log.error("%s download failure.", msg)
+ else:
+ if not iperf_udp_test_by_adb(self.log,
+ self.ad,
+ self.iperf_server_address,
+ self.iperf_udp_port,
+ True,
+ self.iperf_duration):
+ fail_count["download"] += 1
+ iteration_result = False
+ self.log.error("%s download failure.", msg)
+
+ self.log.info("%s %s", msg, iteration_result)
+ if not iteration_result:
+ self._take_bug_report("%s_DownloadNo_%s" % (self.test_name, i),
+ begin_time)
+
+ if self.sleep_time_between_iperf_iterations:
+ self.ad.droid.goToSleepNow()
+ time.sleep(self.sleep_time_between_iperf_iterations)
+
+ test_result = True
+ for failure, count in fail_count.items():
+ if count:
+ self.log.error("%s: %s %s failures in %s iterations",
+ self.test_name, count, failure,
+ self.iperf_iteration)
+ test_result = False
+ return test_result
@test_tracker_info(uuid="190fdeb1-541e-455f-9f37-762a8e55c07f")
@TelephonyBaseTest.tel_test_wrap
@@ -42,9 +160,9 @@
return iperf_test_by_adb(self.log,
self.ad,
self.iperf_server_address,
- self.iperf_srv_tcp_port,
+ self.iperf_tcp_port,
False,
- self.test_duration)
+ self.iperf_duration)
@test_tracker_info(uuid="af9805f8-6ed5-4e05-823e-d88dcef45637")
@TelephonyBaseTest.tel_test_wrap
@@ -52,9 +170,9 @@
return iperf_test_by_adb(self.log,
self.ad,
self.iperf_server_address,
- self.iperf_srv_tcp_port,
+ self.iperf_tcp_port,
True,
- self.test_duration)
+ self.iperf_duration)
@test_tracker_info(uuid="55bf5e09-dc7b-40bc-843f-31fed076ffe4")
@TelephonyBaseTest.tel_test_wrap
@@ -62,9 +180,9 @@
return iperf_udp_test_by_adb(self.log,
self.ad,
self.iperf_server_address,
- self.iperf_srv_udp_port,
+ self.iperf_udp_port,
False,
- self.test_duration)
+ self.iperf_duration)
@test_tracker_info(uuid="02ae88b2-d597-45df-ab5a-d701d1125a0f")
@TelephonyBaseTest.tel_test_wrap
@@ -72,6 +190,26 @@
return iperf_udp_test_by_adb(self.log,
self.ad,
self.iperf_server_address,
- self.iperf_srv_udp_port,
+ self.iperf_udp_port,
True,
- self.test_duration)
+ self.iperf_duration)
+
+ @test_tracker_info(uuid="79aaa7ec-5046-4ffe-b27a-ca93e404e9e0")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_tcp_upload_data_stress(self):
+ return self.stress_test_upload()
+
+ @test_tracker_info(uuid="6a1e5032-9498-4d23-8ae9-db36f1a238c1")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_tcp_download_data_stress(self):
+ return self.stress_test_download()
+
+ @test_tracker_info(uuid="22400c16-dbbb-41c9-afd0-86b525a0bcee")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_udp_upload_data_stress(self):
+ return self.stress_test_upload(test_tcp=False)
+
+ @test_tracker_info(uuid="9f3b2818-5265-422e-9e6f-9ee08dfcc696")
+ @TelephonyBaseTest.tel_test_wrap
+ def test_udp_download_data_stress(self):
+ return self.stress_test_download(test_tcp=False)
\ No newline at end of file
diff --git a/acts_tests/tests/google/tel/live/TelLiveStressFdrTest.py b/acts_tests/tests/google/tel/live/TelLiveStressFdrTest.py
index 46bef20..91e1332 100644
--- a/acts_tests/tests/google/tel/live/TelLiveStressFdrTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveStressFdrTest.py
@@ -25,31 +25,29 @@
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_data_utils import wifi_tethering_setup_teardown
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE
-from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_OMADM
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_TETHERING_ENTITLEMENT_CHECK
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
from acts_contrib.test_utils.tel.tel_defines import GEN_4G
from acts_contrib.test_utils.tel.tel_defines import TETHERING_MODE_WIFI
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_AFTER_FDR
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phone_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import get_model_name
+from acts_contrib.test_utils.tel.tel_bootloader_utils import fastboot_wipe
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_message_utils import mms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_network_generation
from acts_contrib.test_utils.tel.tel_test_utils import get_outgoing_voice_sub_id
from acts_contrib.test_utils.tel.tel_test_utils import is_droid_in_network_generation
-from acts_contrib.test_utils.tel.tel_test_utils import mms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import fastboot_wipe
-from acts_contrib.test_utils.tel.tel_test_utils import sms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_generation
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
from acts_contrib.test_utils.tel.tel_test_utils import wait_for_state
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
from acts.utils import get_current_epoch_time
from acts.utils import rand_ascii_str
@@ -59,6 +57,7 @@
def setup_class(self):
TelephonyBaseTest.setup_class(self)
+ self.user_params["telephony_auto_rerun"] = 0
self.stress_test_number = int(
self.user_params.get("stress_test_number", 100))
self.skip_reset_between_cases = False
diff --git a/acts_tests/tests/google/tel/live/TelLiveStressSmsTest.py b/acts_tests/tests/google/tel/live/TelLiveStressSmsTest.py
index 5813657..249446a 100644
--- a/acts_tests/tests/google/tel/live/TelLiveStressSmsTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveStressSmsTest.py
@@ -16,23 +16,18 @@
import random
import time
-from acts import signals
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
-from acts_contrib.test_utils.tel.tel_subscription_utils \
- import set_message_subid
-from acts_contrib.test_utils.tel.tel_subscription_utils \
- import get_subid_on_same_network_of_host_ad
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import sms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_voice_utils \
- import phone_setup_volte_for_subscription
-from acts_contrib.test_utils.tel.tel_voice_utils \
- import phone_setup_csfb_for_subscription
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_on_rat
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb_for_subscription
+from acts_contrib.test_utils.tel.tel_subscription_utils import set_message_subid
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad
+from acts_contrib.test_utils.tel.tel_test_utils import install_message_apk
from acts.utils import rand_ascii_str
+from acts.libs.utils.multithread import multithread_func
class TelLiveStressSmsTest(TelephonyBaseTest):
def setup_class(self):
@@ -46,6 +41,15 @@
self.long_sms_ims_cycle = \
self.user_params.get("long_sms_ims_cycle", 1)
+ self.message_util = self.user_params.get("message_apk", None)
+ if isinstance(self.message_util, list):
+ self.message_util = self.message_util[0]
+
+ if self.message_util:
+ ads = self.android_devices
+ for ad in ads:
+ install_message_apk(ad, self.message_util)
+
def teardown_test(self):
ensure_phones_idle(self.log, self.android_devices)
diff --git a/acts_tests/tests/google/tel/live/TelLiveStressTest.py b/acts_tests/tests/google/tel/live/TelLiveStressTest.py
index 80d3e7e..e04ba6a 100644
--- a/acts_tests/tests/google/tel/live/TelLiveStressTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveStressTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3.4
#
-# Copyright 2017 - Google
+# Copyright 2022 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -30,8 +30,6 @@
from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
from acts_contrib.test_utils.tel.loggers.telephony_stress_metric_logger import TelephonyStressMetricLogger
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE
-from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC
from acts_contrib.test_utils.tel.tel_defines import GEN_3G
from acts_contrib.test_utils.tel.tel_defines import GEN_4G
from acts_contrib.test_utils.tel.tel_defines import GOOGLE_CBRS_CARRIER_ID
@@ -48,53 +46,25 @@
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_MESSAGE_SUB_ID
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_VOICE_SUB_ID
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_CBRS_DATA_SWITCH
-from acts_contrib.test_utils.tel.tel_defines import CARRIER_SING
+from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g
+from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_test
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
+from acts_contrib.test_utils.tel.tel_logging_utils import extract_test_log
+from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
+from acts_contrib.test_utils.tel.tel_logging_utils import start_sdm_loggers
+from acts_contrib.test_utils.tel.tel_logging_utils import start_adb_tcpdump
from acts_contrib.test_utils.tel.tel_lookup_tables import is_rat_svd_capable
-from acts_contrib.test_utils.tel.tel_test_utils import STORY_LINE
-from acts_contrib.test_utils.tel.tel_test_utils import active_file_download_test
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_generation_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
-from acts_contrib.test_utils.tel.tel_test_utils import extract_test_log
-from acts_contrib.test_utils.tel.tel_test_utils import force_connectivity_metrics_upload
-from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
-from acts_contrib.test_utils.tel.tel_test_utils import get_telephony_signal_strength
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call_by_adb
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import last_call_drop_reason
-from acts_contrib.test_utils.tel.tel_test_utils import run_multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
-from acts_contrib.test_utils.tel.tel_test_utils import sms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
-from acts_contrib.test_utils.tel.tel_test_utils import start_sdm_loggers
-from acts_contrib.test_utils.tel.tel_test_utils import start_adb_tcpdump
-from acts_contrib.test_utils.tel.tel_test_utils import synchronize_device_time
-from acts_contrib.test_utils.tel.tel_test_utils import mms_send_receive_verify
-from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_network_mode_pref
-from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection_by_ping
-from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_call_id_clearing
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_in_call_active
-from acts_contrib.test_utils.tel.tel_test_utils import is_current_data_on_cbrs
-from acts_contrib.test_utils.tel.tel_test_utils import check_voice_network_type
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import get_current_voice_rat
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_message_utils import mms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation_for_subscription
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_2g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_volte
from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
from acts_contrib.test_utils.tel.tel_subscription_utils import get_operatorname_from_slot_index
from acts_contrib.test_utils.tel.tel_subscription_utils import get_carrierid_from_slot_index
@@ -103,9 +73,36 @@
from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_message
from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_outgoing_call
from acts_contrib.test_utils.tel.tel_subscription_utils import set_always_allow_mms_data
-from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from acts_contrib.test_utils.tel.tel_test_utils import STORY_LINE
+from acts_contrib.test_utils.tel.tel_test_utils import force_connectivity_metrics_upload
+from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
+from acts_contrib.test_utils.tel.tel_test_utils import get_telephony_signal_strength
+from acts_contrib.test_utils.tel.tel_test_utils import synchronize_device_time
+from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_network_mode_pref
+from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
+from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection_by_ping
+from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_data_connection
+from acts_contrib.test_utils.tel.tel_test_utils import is_current_data_on_cbrs
+from acts_contrib.test_utils.tel.tel_test_utils import check_voice_network_type
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call_by_adb
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
+from acts_contrib.test_utils.tel.tel_voice_utils import last_call_drop_reason
+from acts_contrib.test_utils.tel.tel_voice_utils import get_current_voice_rat
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_call_id_clearing
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_in_call_active
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
from acts.utils import get_current_epoch_time
from acts.utils import rand_ascii_str
+from acts.libs.utils.multithread import run_multithread_func
EXCEPTION_TOLERANCE = 5
BINDER_LOGS = ["/sys/kernel/debug/binder"]
@@ -196,6 +193,7 @@
"CALL_ID_CLEANUP_FAIL": 0 }
self.call_stats_check = self.user_params.get("call_stats_check", False)
self.nsa_5g_for_stress = self.user_params.get("nsa_5g_for_stress", False)
+ self.nr_type = self.user_params.get("nr_type", 'nsa')
return True
def setup_test(self):
@@ -480,8 +478,7 @@
incall_ui_display=INCALL_UI_DISPLAY_BACKGROUND,
call_stats_check=self.call_stats_check,
voice_type_init=voice_type_init,
- result_info = self.result_info,
- nsa_5g_for_stress=self.nsa_5g_for_stress
+ result_info = self.result_info
) and wait_for_in_call_active(self.dut, 60, 3)
else:
call_setup_result = call_setup_teardown(
@@ -496,8 +493,7 @@
slot_id_callee=slot_id_callee,
call_stats_check=self.call_stats_check,
voice_type_init=voice_type_init,
- result_info = self.result_info,
- nsa_5g_for_stress=self.nsa_5g_for_stress)
+ result_info = self.result_info)
self.result_collection[RESULTS_LIST[call_setup_result.result_value]] += 1
if not call_setup_result:
@@ -564,6 +560,11 @@
if not hangup_call(self.log, ads[0]):
failure_reasons.add("Teardown")
result = False
+ else:
+ if self.nsa_5g_for_stress:
+ for ad in (ads[0], ads[1]):
+ if not is_current_network_5g(ad, self.nr_type):
+ ad.log.error("Phone not attached on 5G")
for ad in ads:
if not wait_for_call_id_clearing(ad,
[]) or ad.droid.telecomIsInCall():
diff --git a/acts_tests/tests/google/tel/live/TelLiveVideoDataTest.py b/acts_tests/tests/google/tel/live/TelLiveVideoDataTest.py
index 8f86f9f..fb0ef06 100644
--- a/acts_tests/tests/google/tel/live/TelLiveVideoDataTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveVideoDataTest.py
@@ -16,15 +16,14 @@
"""
Test Script for VT Data test
"""
+from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.tel.tel_video_utils import \
- is_phone_in_call_video_bidirectional
+from acts_contrib.test_utils.tel.tel_video_utils import is_phone_in_call_video_bidirectional
from acts_contrib.test_utils.tel.tel_video_utils import phone_setup_video
from acts_contrib.test_utils.tel.tel_video_utils import video_call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
class TelLiveVideoDataTest(TelephonyBaseTest):
diff --git a/acts_tests/tests/google/tel/live/TelLiveVideoTest.py b/acts_tests/tests/google/tel/live/TelLiveVideoTest.py
index de2e85a..2f80ef8 100644
--- a/acts_tests/tests/google/tel/live/TelLiveVideoTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveVideoTest.py
@@ -21,14 +21,13 @@
from queue import Empty
from acts import signals
from acts.test_decorators import test_tracker_info
+from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import AUDIO_ROUTE_EARPIECE
from acts_contrib.test_utils.tel.tel_defines import AUDIO_ROUTE_SPEAKER
from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_ACTIVE
from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_HOLDING
from acts_contrib.test_utils.tel.tel_defines import CALL_CAPABILITY_MANAGE_CONFERENCE
-from acts_contrib.test_utils.tel.tel_defines import CALL_CAPABILITY_MERGE_CONFERENCE
-from acts_contrib.test_utils.tel.tel_defines import CALL_CAPABILITY_SWAP_CONFERENCE
from acts_contrib.test_utils.tel.tel_defines import CALL_PROPERTY_CONFERENCE
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VT
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VIDEO_SESSION_EVENT
@@ -45,34 +44,28 @@
from acts_contrib.test_utils.tel.tel_defines import EventTelecomVideoCallSessionEvent
from acts_contrib.test_utils.tel.tel_defines import SESSION_EVENT_RX_PAUSE
from acts_contrib.test_utils.tel.tel_defines import SESSION_EVENT_RX_RESUME
-from acts_contrib.test_utils.tel.tel_lookup_tables import operator_capabilities
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_video_enabled
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import disconnect_call_by_id
-from acts_contrib.test_utils.tel.tel_test_utils import get_model_name
-from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_video_enabled
from acts_contrib.test_utils.tel.tel_test_utils import get_capability_for_subscription
from acts_contrib.test_utils.tel.tel_video_utils import get_call_id_in_video_state
-from acts_contrib.test_utils.tel.tel_video_utils import \
- is_phone_in_call_video_bidirectional
+from acts_contrib.test_utils.tel.tel_video_utils import is_phone_in_call_video_bidirectional
from acts_contrib.test_utils.tel.tel_video_utils import is_phone_in_call_voice_hd
from acts_contrib.test_utils.tel.tel_video_utils import phone_setup_video
-from acts_contrib.test_utils.tel.tel_video_utils import \
- verify_video_call_in_expected_state
+from acts_contrib.test_utils.tel.tel_video_utils import verify_video_call_in_expected_state
from acts_contrib.test_utils.tel.tel_video_utils import video_call_downgrade
from acts_contrib.test_utils.tel.tel_video_utils import video_call_modify_video
from acts_contrib.test_utils.tel.tel_video_utils import video_call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import disconnect_call_by_id
from acts_contrib.test_utils.tel.tel_voice_utils import get_audio_route
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import set_audio_route
from acts_contrib.test_utils.tel.tel_voice_utils import get_cep_conference_call_id
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
+from acts_contrib.test_utils.tel.tel_voice_utils import set_audio_route
DEFAULT_LONG_DURATION_CALL_TOTAL_DURATION = 1 * 60 * 60 # default 1 hour
diff --git a/acts_tests/tests/google/tel/live/TelLiveVoiceConfTest.py b/acts_tests/tests/google/tel/live/TelLiveVoiceConfTest.py
index 02088ee..8e53ea7 100644
--- a/acts_tests/tests/google/tel/live/TelLiveVoiceConfTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveVoiceConfTest.py
@@ -20,28 +20,34 @@
import time
from acts import signals
from acts.test_decorators import test_tracker_info
+from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import CALL_CAPABILITY_MERGE_CONFERENCE
from acts_contrib.test_utils.tel.tel_defines import CALL_CAPABILITY_SWAP_CONFERENCE
from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_ACTIVE
-from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_HOLDING
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_CONFERENCE
from acts_contrib.test_utils.tel.tel_defines import PHONE_TYPE_CDMA
-from acts_contrib.test_utils.tel.tel_defines import PHONE_TYPE_GSM
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_2g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_ss_utils import three_phone_call_forwarding_short_seq
+from acts_contrib.test_utils.tel.tel_ss_utils import three_phone_call_waiting_short_seq
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
-from acts_contrib.test_utils.tel.tel_test_utils import call_reject
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
from acts_contrib.test_utils.tel.tel_test_utils import get_phone_number
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
+from acts_contrib.test_utils.tel.tel_test_utils import install_dialer_apk
from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls
from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
-from acts_contrib.test_utils.tel.tel_test_utils import wait_and_answer_call
from acts_contrib.test_utils.tel.tel_test_utils import get_capability_for_subscription
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
+from acts_contrib.test_utils.tel.tel_voice_utils import call_reject
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_1x
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
@@ -49,34 +55,21 @@
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_wcdma
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_general
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
from acts_contrib.test_utils.tel.tel_voice_utils import swap_calls
-from acts_contrib.test_utils.tel.tel_voice_utils import three_phone_call_forwarding_short_seq
-from acts_contrib.test_utils.tel.tel_voice_utils import three_phone_call_waiting_short_seq
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _get_expected_call_state
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _hangup_call
-from acts_contrib.test_utils.tel.tel_voice_conf_utils import \
- _test_ims_conference_merge_drop_first_call_from_host
-from acts_contrib.test_utils.tel.tel_voice_conf_utils import \
- _test_ims_conference_merge_drop_first_call_from_participant
-from acts_contrib.test_utils.tel.tel_voice_conf_utils import \
- _test_ims_conference_merge_drop_second_call_from_host
-from acts_contrib.test_utils.tel.tel_voice_conf_utils import \
- _test_ims_conference_merge_drop_second_call_from_participant
+from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_ims_conference_merge_drop_first_call_from_host
+from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_ims_conference_merge_drop_first_call_from_participant
+from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_ims_conference_merge_drop_second_call_from_host
+from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_ims_conference_merge_drop_second_call_from_participant
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_call_mo_mo_add_swap_x
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_call_mo_mt_add_swap_x
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_call_mt_mt_add_swap_x
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _three_phone_call_mo_add_mo
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _three_phone_call_mo_add_mt
-from acts_contrib.test_utils.tel.tel_voice_conf_utils import _three_phone_call_mt_add_mt
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _three_phone_hangup_call_verify_call_state
-
+from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_wcdma_conference_merge_drop
class TelLiveVoiceConfTest(TelephonyBaseTest):
def setup_class(self):
@@ -90,6 +83,15 @@
raise signals.TestAbortClass(
"Conference call is not supported, abort test.")
+ self.dialer_util = self.user_params.get("dialer_apk", None)
+ if isinstance(self.dialer_util, list):
+ self.dialer_util = self.dialer_util[0]
+
+ if self.dialer_util:
+ ads = self.android_devices
+ for ad in ads:
+ install_dialer_apk(ad, self.dialer_util)
+
def teardown_test(self):
ensure_phones_idle(self.log, self.android_devices)
@@ -437,78 +439,7 @@
return False
return True
-
- def _test_wcdma_conference_merge_drop(self, call_ab_id, call_ac_id):
- """Test conference merge and drop in WCDMA/CSFB_WCDMA call.
-
- PhoneA in WCDMA (or CSFB_WCDMA) call with PhoneB.
- PhoneA in WCDMA (or CSFB_WCDMA) call with PhoneC.
- Merge calls to conference on PhoneA.
- Hangup on PhoneC, check call continues between AB.
- Hangup on PhoneB, check A ends.
-
- Args:
- call_ab_id: call id for call_AB on PhoneA.
- call_ac_id: call id for call_AC on PhoneA.
-
- Returns:
- True if succeed;
- False if failed.
- """
- ads = self.android_devices
-
- self.log.info("Step4: Merge to Conf Call and verify Conf Call.")
- ads[0].droid.telecomCallJoinCallsInConf(call_ab_id, call_ac_id)
- time.sleep(WAIT_TIME_IN_CALL)
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
- if num_active_calls(self.log, ads[0]) != 3:
- ads[0].log.error("Total number of call ids is not 3.")
- return False
- call_conf_id = None
- for call_id in calls:
- if call_id != call_ab_id and call_id != call_ac_id:
- call_conf_id = call_id
- if not call_conf_id:
- self.log.error("Merge call fail, no new conference call id.")
- return False
- if not verify_incall_state(self.log, [ads[0], ads[1], ads[2]], True):
- return False
-
- # Check if Conf Call is currently active
- if ads[0].droid.telecomCallGetCallState(
- call_conf_id) != CALL_STATE_ACTIVE:
- ads[0].log.error(
- "Call_id: %s, state: %s, expected: STATE_ACTIVE", call_conf_id,
- ads[0].droid.telecomCallGetCallState(call_conf_id))
- return False
-
- self.log.info("Step5: End call on PhoneC and verify call continues.")
- if not _hangup_call(self.log, ads[2], "PhoneC"):
- return False
- time.sleep(WAIT_TIME_IN_CALL)
- calls = ads[0].droid.telecomCallGetCallIds()
- ads[0].log.info("Calls in PhoneA %s", calls)
- if num_active_calls(self.log, ads[0]) != 1:
- return False
- if not verify_incall_state(self.log, [ads[0], ads[1]], True):
- return False
- if not verify_incall_state(self.log, [ads[2]], False):
- return False
-
- self.log.info("Step6: End call on PhoneB and verify PhoneA end.")
- if not _hangup_call(self.log, ads[1], "PhoneB"):
- return False
- time.sleep(WAIT_TIME_IN_CALL)
- if not verify_incall_state(self.log, [ads[0], ads[1], ads[2]], False):
- return False
- return True
-
-
-
""" Tests Begin """
-
-
@TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="3cd45972-3862-4956-9504-7fefacdd5ca6")
def test_wcdma_mo_mo_add_merge_drop(self):
@@ -537,7 +468,7 @@
if call_ab_id is None or call_ac_id is None:
return False
- return self._test_wcdma_conference_merge_drop(call_ab_id, call_ac_id)
+ return _test_wcdma_conference_merge_drop(self.log, ads, call_ab_id, call_ac_id)
@TelephonyBaseTest.tel_test_wrap
@@ -568,7 +499,7 @@
if call_ab_id is None or call_ac_id is None:
return False
- return self._test_wcdma_conference_merge_drop(call_ab_id, call_ac_id)
+ return _test_wcdma_conference_merge_drop(self.log, ads, call_ab_id, call_ac_id)
@TelephonyBaseTest.tel_test_wrap
@@ -6641,7 +6572,7 @@
if call_ab_id is None or call_ac_id is None:
return False
- return self._test_wcdma_conference_merge_drop(call_ab_id, call_ac_id)
+ return _test_wcdma_conference_merge_drop(self.log, ads, call_ab_id, call_ac_id)
@TelephonyBaseTest.tel_test_wrap
@@ -6671,7 +6602,7 @@
if call_ab_id is None or call_ac_id is None:
return False
- return self._test_wcdma_conference_merge_drop(call_ab_id, call_ac_id)
+ return _test_wcdma_conference_merge_drop(self.log, ads, call_ab_id, call_ac_id)
@TelephonyBaseTest.tel_test_wrap
@@ -6700,7 +6631,7 @@
if call_ab_id is None or call_ac_id is None:
return False
- return self._test_wcdma_conference_merge_drop(call_ab_id, call_ac_id)
+ return _test_wcdma_conference_merge_drop(self.log, ads, call_ab_id, call_ac_id)
@TelephonyBaseTest.tel_test_wrap
@@ -6730,7 +6661,7 @@
if call_ab_id is None or call_ac_id is None:
return False
- return self._test_wcdma_conference_merge_drop(call_ab_id, call_ac_id)
+ return _test_wcdma_conference_merge_drop(self.log, ads, call_ab_id, call_ac_id)
@TelephonyBaseTest.tel_test_wrap
@@ -6759,7 +6690,7 @@
if call_ab_id is None or call_ac_id is None:
return False
- return self._test_wcdma_conference_merge_drop(call_ab_id, call_ac_id)
+ return _test_wcdma_conference_merge_drop(self.log, ads, call_ab_id, call_ac_id)
@TelephonyBaseTest.tel_test_wrap
@@ -6789,7 +6720,7 @@
if call_ab_id is None or call_ac_id is None:
return False
- return self._test_wcdma_conference_merge_drop(call_ab_id, call_ac_id)
+ return _test_wcdma_conference_merge_drop(self.log, ads, call_ab_id, call_ac_id)
@TelephonyBaseTest.tel_test_wrap
@@ -6819,7 +6750,7 @@
if call_ab_id is None or call_ac_id is None:
return False
- return self._test_wcdma_conference_merge_drop(call_ab_id, call_ac_id)
+ return _test_wcdma_conference_merge_drop(self.log, ads, call_ab_id, call_ac_id)
@TelephonyBaseTest.tel_test_wrap
@@ -6849,7 +6780,7 @@
if call_ab_id is None or call_ac_id is None:
return False
- return self._test_wcdma_conference_merge_drop(call_ab_id, call_ac_id)
+ return _test_wcdma_conference_merge_drop(self.log, ads, call_ab_id, call_ac_id)
@TelephonyBaseTest.tel_test_wrap
@@ -6878,7 +6809,7 @@
if call_ab_id is None or call_ac_id is None:
return False
- return self._test_wcdma_conference_merge_drop(call_ab_id, call_ac_id)
+ return _test_wcdma_conference_merge_drop(self.log, ads, call_ab_id, call_ac_id)
@TelephonyBaseTest.tel_test_wrap
@@ -6908,7 +6839,7 @@
if call_ab_id is None or call_ac_id is None:
return False
- return self._test_wcdma_conference_merge_drop(call_ab_id, call_ac_id)
+ return _test_wcdma_conference_merge_drop(self.log, ads, call_ab_id, call_ac_id)
@TelephonyBaseTest.tel_test_wrap
@@ -11415,6 +11346,29 @@
@TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="f4990e20-4a40-4238-9a2a-a75d9be3d354")
+ def test_volte_call_forwarding_unconditional(self):
+
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0])),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_forwarding_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_forwarding_type="unconditional")
+
+
+ @TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="26b85c3f-5a38-465a-a6e3-dfd03c6ea315")
def test_call_forwarding_busy(self):
@@ -11438,6 +11392,29 @@
@TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="26b85c3f-5a38-465a-a6e3-dfd03c6ea315")
+ def test_volte_call_forwarding_busy(self):
+
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0])),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_forwarding_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_forwarding_type="busy")
+
+
+ @TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="96638a39-efe2-40e2-afb6-6a97f87c4af5")
def test_call_forwarding_not_answered(self):
@@ -11461,6 +11438,29 @@
@TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="96638a39-efe2-40e2-afb6-6a97f87c4af5")
+ def test_volte_call_forwarding_not_answered(self):
+
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0])),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_forwarding_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_forwarding_type="not_answered")
+
+
+ @TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="a13e586a-3345-49d8-9e84-ca33bd3fbd7d")
def test_call_forwarding_not_reachable(self):
@@ -11484,6 +11484,29 @@
@TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="a13e586a-3345-49d8-9e84-ca33bd3fbd7d")
+ def test_volte_call_forwarding_not_reachable(self):
+
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0])),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_forwarding_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_forwarding_type="not_reachable")
+
+
+ @TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="e9a6027b-7dd1-4dca-a700-e4d42c9c947d")
def test_call_waiting_scenario_1(self):
""" Call waiting scenario 1: 1st call ended first by caller1 during 2nd
@@ -11510,6 +11533,50 @@
@TelephonyBaseTest.tel_test_wrap
+ @test_tracker_info(uuid="e9a6027b-7dd1-4dca-a700-e4d42c9c947d")
+ def test_volte_call_waiting_scenario_1(self):
+ """Tests that the call waiting function is workable by scenario 1.
+
+ Initial Condition:
+ (1) Network Type:
+ - DUT: LTE, VoLTE ON.
+ - Caller1: LTE/3G.
+
+ Execution Criteria:
+ (1) Enable call waiting on DUT.
+ (2) Let caller1 make the first MO call to DUT and let DUT answer the
+ call.
+ (3) Let caller2 make the second MO call to DUT. Do NOT answer the
+ call and keep the call alerting.
+ (4) End the first call by caller1.
+ (5) Let DUT answer the second call.
+ (6) End the second call by caller2.
+
+ Pass Criteria:
+ (2)(5) All the call can be made/answered correctly.
+ (4)(6) All the call can be released correctly.
+ """
+ ads = self.android_devices
+
+ tasks = [(phone_setup_volte, (self.log, ads[0])),
+ (phone_setup_voice_general, (self.log, ads[1])),
+ (phone_setup_voice_general, (self.log, ads[2]))]
+ if not multithread_func(self.log, tasks):
+ self.log.error("Phone Failed to Set Up Properly.")
+ return False
+
+ return three_phone_call_waiting_short_seq(
+ self.log,
+ ads[0],
+ None,
+ None,
+ ads[1],
+ ads[2],
+ call_waiting=True,
+ scenario=1)
+
+
+ @TelephonyBaseTest.tel_test_wrap
@test_tracker_info(uuid="3fe02cb7-68d7-4762-882a-02bff8ce32f9")
def test_call_waiting_scenario_2(self):
""" Call waiting scenario 2: 1st call ended first by caller1 during 2nd
diff --git a/acts_tests/tests/google/tel/live/TelLiveVoiceTest.py b/acts_tests/tests/google/tel/live/TelLiveVoiceTest.py
index a5f0117..2d055ea 100644
--- a/acts_tests/tests/google/tel/live/TelLiveVoiceTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveVoiceTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3.4
#
-# Copyright 2016 - Google
+# Copyright 2022 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -24,11 +24,14 @@
from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_data_utils import wifi_cell_switching
+from acts_contrib.test_utils.tel.tel_data_utils import get_mobile_data_usage
+from acts_contrib.test_utils.tel.tel_data_utils import remove_mobile_data_usage_limit
+from acts_contrib.test_utils.tel.tel_data_utils import set_mobile_data_usage_limit
from acts_contrib.test_utils.tel.tel_data_utils import test_call_setup_in_active_data_transfer
from acts_contrib.test_utils.tel.tel_data_utils import test_call_setup_in_active_youtube_video
from acts_contrib.test_utils.tel.tel_data_utils import call_epdg_to_epdg_wfc
from acts_contrib.test_utils.tel.tel_data_utils import test_wifi_cell_switching_in_call
+from acts_contrib.test_utils.tel.tel_defines import CARRIER_VZW
from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED
from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_TERMINATED
from acts_contrib.test_utils.tel.tel_defines import GEN_2G
@@ -43,28 +46,27 @@
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_incoming_voice_sub_id
-from acts_contrib.test_utils.tel.tel_subscription_utils import \
- get_outgoing_voice_sub_id
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import \
- call_voicemail_erase_all_pending_voicemail
-from acts.utils import adb_shell_ping
-from acts_contrib.test_utils.tel.tel_test_utils import get_mobile_data_usage
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call_active
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_2g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan_cellular_preferred
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_2g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
+from acts_contrib.test_utils.tel.tel_test_utils import install_dialer_apk
from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls
-from acts_contrib.test_utils.tel.tel_test_utils import remove_mobile_data_usage_limit
-from acts_contrib.test_utils.tel.tel_test_utils import run_multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import set_mobile_data_usage_limit
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_ringing_call
-from acts_contrib.test_utils.tel.tel_test_utils import set_wifi_to_default
from acts_contrib.test_utils.tel.tel_test_utils import STORY_LINE
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_in_call_active
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import hold_unhold_test
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_1x
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
@@ -74,29 +76,21 @@
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_wcdma
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
from acts_contrib.test_utils.tel.tel_voice_utils import _test_call_long_duration
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import \
- phone_setup_iwlan_cellular_preferred
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_general
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_2g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_volte
+from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
+from acts_contrib.test_utils.tel.tel_voice_utils import call_voicemail_erase_all_pending_voicemail
from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_leave_voice_mail
from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_long_seq
from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_short_seq
-from acts_contrib.test_utils.tel.tel_voice_utils import hold_unhold_test
-
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_in_call_active
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_ringing_call
+from acts_contrib.test_utils.tel.tel_wifi_utils import set_wifi_to_default
+from acts.libs.utils.multithread import multithread_func
DEFAULT_PING_DURATION = 120 # in seconds
CallResult = TelephonyVoiceTestResult.CallResult.Value
+
class TelLiveVoiceTest(TelephonyBaseTest):
def setup_class(self):
super().setup_class()
@@ -109,6 +103,25 @@
self.call_server_number = self.user_params.get(
"call_server_number", STORY_LINE)
self.tel_logger = TelephonyMetricLogger.for_test_case()
+ self.dialer_util = self.user_params.get("dialer_apk", None)
+ if isinstance(self.dialer_util, list):
+ self.dialer_util = self.dialer_util[0]
+
+ if self.dialer_util:
+ ads = self.android_devices
+ for ad in ads:
+ install_dialer_apk(ad, self.dialer_util)
+
+ def get_carrier_name(self, ad):
+ return ad.adb.getprop("gsm.sim.operator.alpha")
+
+ def check_band_support(self,ad):
+ carrier = ad.adb.getprop("gsm.sim.operator.alpha")
+
+ if int(ad.adb.getprop("ro.product.first_api_level")) > 30 and (
+ carrier == CARRIER_VZW):
+ raise signals.TestSkip(
+ "Device Doesn't Support 2g/3G Band.")
""" Tests Begin """
@@ -389,6 +402,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
tasks = [(phone_setup_volte, (self.log, ads[0])), (phone_setup_csfb,
(self.log, ads[1]))]
@@ -420,6 +434,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
tasks = [(phone_setup_volte, (self.log, ads[0])), (phone_setup_csfb,
(self.log, ads[1]))]
@@ -531,6 +546,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
tasks = [(phone_setup_volte, (self.log, ads[0])),
(phone_setup_voice_3g, (self.log, ads[1]))]
@@ -564,6 +580,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Make Sure PhoneB is CDMA phone.
if ads[1].droid.telephonyGetPhoneType() != PHONE_TYPE_CDMA:
self.log.error("PhoneB not cdma phone, can not 3g 1x. Stop test.")
@@ -603,6 +620,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Make Sure PhoneB is GSM phone.
if ads[1].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM:
self.log.error(
@@ -641,6 +659,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
tasks = [(phone_setup_volte, (self.log, ads[0])),
(phone_setup_voice_2g, (self.log, ads[1]))]
@@ -938,6 +957,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Turn OFF WiFi for Phone B
set_wifi_to_default(self.log, ads[1])
tasks = [(phone_setup_iwlan,
@@ -972,6 +992,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Turn OFF WiFi for Phone B
set_wifi_to_default(self.log, ads[1])
tasks = [(phone_setup_iwlan,
@@ -1006,6 +1027,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Turn OFF WiFi for Phone B
set_wifi_to_default(self.log, ads[1])
tasks = [(phone_setup_iwlan,
@@ -1040,6 +1062,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Turn OFF WiFi for Phone B
set_wifi_to_default(self.log, ads[1])
tasks = [(phone_setup_iwlan,
@@ -1074,6 +1097,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Turn OFF WiFi for Phone B
set_wifi_to_default(self.log, ads[1])
tasks = [(phone_setup_iwlan,
@@ -1108,6 +1132,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Turn OFF WiFi for Phone B
set_wifi_to_default(self.log, ads[1])
tasks = [(phone_setup_iwlan,
@@ -1142,6 +1167,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Turn OFF WiFi for Phone B
set_wifi_to_default(self.log, ads[1])
tasks = [(phone_setup_iwlan,
@@ -1176,6 +1202,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Turn OFF WiFi for Phone B
set_wifi_to_default(self.log, ads[1])
tasks = [(phone_setup_iwlan,
@@ -1210,6 +1237,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Turn OFF WiFi for Phone B
set_wifi_to_default(self.log, ads[1])
tasks = [(phone_setup_csfb, (self.log, ads[0])), (phone_setup_csfb,
@@ -1242,6 +1270,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Turn OFF WiFi for Phone B
set_wifi_to_default(self.log, ads[1])
tasks = [(phone_setup_voice_3g, (self.log, ads[0])),
@@ -1462,6 +1491,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Turn OFF WiFi for Phone B
set_wifi_to_default(self.log, ads[1])
tasks = [(phone_setup_csfb, (self.log, ads[0])), (phone_setup_csfb,
@@ -1496,6 +1526,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# Turn OFF WiFi for Phone B
set_wifi_to_default(self.log, ads[1])
tasks = [(phone_setup_voice_3g, (self.log, ads[0])),
@@ -1825,6 +1856,7 @@
# TODO: b/26338422 Make this a parameter
MINIMUM_SUCCESS_RATE = .95
ads = self.android_devices
+ self.check_band_support(ads[0])
tasks = [(phone_setup_csfb, (self.log, ads[0])), (phone_setup_csfb,
(self.log, ads[1]))]
@@ -1878,6 +1910,7 @@
# TODO: b/26338422 Make this a parameter
MINIMUM_SUCCESS_RATE = .95
ads = self.android_devices
+ self.check_band_support(ads[0])
tasks = [(phone_setup_voice_3g, (self.log, ads[0])),
(phone_setup_voice_3g, (self.log, ads[1]))]
@@ -2397,6 +2430,7 @@
True if pass; False if fail.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# make sure PhoneA is GSM phone before proceed.
if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
ads[0].log.error(
@@ -2449,6 +2483,7 @@
True if pass; False if fail.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# make sure PhoneA is GSM phone before proceed.
if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
ads[0].log.error(
@@ -2690,6 +2725,7 @@
True if pass; False if fail.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
tasks = [(phone_setup_voice_3g, (self.log, ads[0])),
(phone_setup_voice_general, (self.log, ads[1]))]
@@ -2718,6 +2754,7 @@
True if pass; False if fail.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
tasks = [(phone_setup_voice_general, (self.log, ads[1])),
(phone_setup_voice_2g, (self.log, ads[0]))]
@@ -2805,6 +2842,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
(phone_setup_voice_2g, (self.log, ads[1]))]
@@ -2838,6 +2876,7 @@
TestFailure if not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
tasks = [(phone_setup_voice_2g, (self.log, ads[0])),
(phone_setup_voice_2g, (self.log, ads[1]))]
@@ -2867,6 +2906,7 @@
True if pass; False if fail.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# make sure PhoneA is GSM phone before proceed.
if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
raise signals.TestSkip(
@@ -2912,6 +2952,7 @@
True if pass; False if fail.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
# make sure PhoneA is GSM phone before proceed.
if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
self.log.error("Not GSM phone, abort this wcdma hold/unhold test.")
@@ -3020,6 +3061,7 @@
Otherwise True.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
tasks = [(phone_setup_voice_3g, (self.log, ads[0])),
(phone_setup_voice_general, (self.log, ads[1]))]
@@ -3274,6 +3316,7 @@
True if success.
False if failed.
"""
+ self.check_band_support(self.android_devices[0])
if not phone_setup_voice_3g(self.log, self.android_devices[0]):
self.android_devices[0].log.error("Failed to setup 3G")
return False
@@ -3301,6 +3344,7 @@
True if success.
False if failed.
"""
+ self.check_band_support(self.android_devices[0])
if not phone_setup_voice_3g(self.log, self.android_devices[0]):
self.android_devices[0].log.error("Failed to setup 3G")
return False
@@ -3328,6 +3372,7 @@
True if success.
False if failed.
"""
+ self.check_band_support(self.android_devices[0])
if not phone_setup_voice_2g(self.log, self.android_devices[0]):
self.android_devices[0].log.error("Failed to setup voice in 2G")
return False
@@ -3355,6 +3400,7 @@
True if success.
False if failed.
"""
+ self.check_band_support(self.android_devices[0])
if not phone_setup_voice_2g(self.log, self.android_devices[0]):
self.android_devices[0].log.error("Failed to setup voice in 2G")
return False
@@ -3430,8 +3476,13 @@
True if success.
False if failed.
"""
+ carrier = self.get_carrier_name(self.android_devices[0])
+ if carrier == CARRIER_VZW:
+ wfc = WFC_MODE_CELLULAR_PREFERRED
+ else:
+ wfc = WFC_MODE_WIFI_PREFERRED
if not phone_setup_iwlan(self.log, self.android_devices[0], True,
- WFC_MODE_WIFI_PREFERRED,
+ wfc,
self.wifi_network_ssid,
self.wifi_network_pass):
self.android_devices[0].log.error(
@@ -3456,8 +3507,13 @@
True if success.
False if failed.
"""
+ carrier = self.get_carrier_name(self.android_devices[0])
+ if carrier == CARRIER_VZW:
+ wfc = WFC_MODE_CELLULAR_PREFERRED
+ else:
+ wfc = WFC_MODE_WIFI_PREFERRED
if not phone_setup_iwlan(self.log, self.android_devices[0], True,
- WFC_MODE_WIFI_PREFERRED,
+ wfc,
self.wifi_network_ssid,
self.wifi_network_pass):
self.android_devices[0].log.error(
@@ -3482,8 +3538,10 @@
True if success.
False if failed.
"""
- if not phone_setup_iwlan_cellular_preferred(self.log,
+ if not phone_setup_iwlan(self.log,
self.android_devices[0],
+ True,
+ WFC_MODE_CELLULAR_PREFERRED,
self.wifi_network_ssid,
self.wifi_network_pass):
self.android_devices[0].log.error(
@@ -3508,8 +3566,10 @@
True if success.
False if failed.
"""
- if not phone_setup_iwlan_cellular_preferred(self.log,
+ if not phone_setup_iwlan(self.log,
self.android_devices[0],
+ True,
+ WFC_MODE_CELLULAR_PREFERRED,
self.wifi_network_ssid,
self.wifi_network_pass):
self.android_devices[0].log.error(
@@ -3662,6 +3722,7 @@
True if success.
False if failed.
"""
+ self.check_band_support(self.android_devices[0])
if not phone_setup_voice_3g(self.log, self.android_devices[0]):
self.android_devices[0].log.error("Failed to setup 3G")
return False
@@ -3685,6 +3746,7 @@
True if success.
False if failed.
"""
+ self.check_band_support(self.android_devices[0])
if not phone_setup_voice_3g(self.log, self.android_devices[0]):
self.android_devices[0].log.error("Failed to setup 3G")
return False
@@ -3708,6 +3770,7 @@
True if success.
False if failed.
"""
+ self.check_band_support(self.android_devices[0])
if not phone_setup_voice_2g(self.log, self.android_devices[0]):
self.android_devices[0].log.error("Failed to setup voice in 2G")
return False
@@ -3731,6 +3794,7 @@
True if success.
False if failed.
"""
+ self.check_band_support(self.android_devices[0])
if not phone_setup_voice_2g(self.log, self.android_devices[0]):
self.android_devices[0].log.error("Failed to setup voice in 2G")
return False
@@ -3803,8 +3867,13 @@
True if success.
False if failed.
"""
+ carrier = self.get_carrier_name(self.android_devices[0])
+ if carrier == CARRIER_VZW:
+ wfc = WFC_MODE_CELLULAR_PREFERRED
+ else:
+ wfc = WFC_MODE_WIFI_PREFERRED
if not phone_setup_iwlan(self.log, self.android_devices[0], True,
- WFC_MODE_WIFI_PREFERRED,
+ wfc,
self.wifi_network_ssid,
self.wifi_network_pass):
self.android_devices[0].log.error(
@@ -3828,8 +3897,13 @@
True if success.
False if failed.
"""
+ carrier = self.get_carrier_name(self.android_devices[0])
+ if carrier == CARRIER_VZW:
+ wfc = WFC_MODE_CELLULAR_PREFERRED
+ else:
+ wfc = WFC_MODE_WIFI_PREFERRED
if not phone_setup_iwlan(self.log, self.android_devices[0], True,
- WFC_MODE_WIFI_PREFERRED,
+ wfc,
self.wifi_network_ssid,
self.wifi_network_pass):
self.android_devices[0].log.error(
@@ -3903,8 +3977,10 @@
True if success.
False if failed.
"""
- if not phone_setup_iwlan_cellular_preferred(self.log,
+ if not phone_setup_iwlan(self.log,
self.android_devices[0],
+ True,
+ WFC_MODE_CELLULAR_PREFERRED,
self.wifi_network_ssid,
self.wifi_network_pass):
self.android_devices[0].log.error(
@@ -3928,8 +4004,10 @@
True if success.
False if failed.
"""
- if not phone_setup_iwlan_cellular_preferred(self.log,
+ if not phone_setup_iwlan(self.log,
self.android_devices[0],
+ True,
+ WFC_MODE_CELLULAR_PREFERRED,
self.wifi_network_ssid,
self.wifi_network_pass):
self.android_devices[0].log.error(
@@ -3956,6 +4034,7 @@
TestFailure is not success.
"""
ads = self.android_devices
+ self.check_band_support(ads[0])
try:
subscriber_id = ads[0].droid.telephonyGetSubscriberId()
data_usage = get_mobile_data_usage(ads[0], subscriber_id)
diff --git a/acts_tests/tests/google/tel/live/TelWifiDataTest.py b/acts_tests/tests/google/tel/live/TelWifiDataTest.py
index 4672feb..9582405 100644
--- a/acts_tests/tests/google/tel/live/TelWifiDataTest.py
+++ b/acts_tests/tests/google/tel/live/TelWifiDataTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3.4
#
-# Copyright 2016 - The Android Open Source Project
+# Copyright 2022 - 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.
@@ -24,18 +24,18 @@
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
from acts_contrib.test_utils.tel.tel_defines import GEN_4G
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_generation
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_test
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_wifi_data_connection
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_cell_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wifi_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import run_multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import active_file_download_test
from acts_contrib.test_utils.tel.tel_test_utils import get_telephony_signal_strength
-from acts_contrib.test_utils.tel.tel_test_utils import get_wifi_signal_strength
from acts_contrib.test_utils.tel.tel_test_utils import reboot_device
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import get_wifi_signal_strength
from acts.utils import adb_shell_ping
+from acts.libs.utils.multithread import run_multithread_func
# Attenuator name
ATTEN_NAME_FOR_WIFI_2G = 'wifi0'
diff --git a/acts_tests/tests/google/tel/live/TelWifiVideoTest.py b/acts_tests/tests/google/tel/live/TelWifiVideoTest.py
index 8f32038..692a96e 100644
--- a/acts_tests/tests/google/tel/live/TelWifiVideoTest.py
+++ b/acts_tests/tests/google/tel/live/TelWifiVideoTest.py
@@ -17,59 +17,14 @@
Test Script for ViWiFi live call test
"""
-import time
-from queue import Empty
from acts.test_decorators import test_tracker_info
+from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_defines import AUDIO_ROUTE_EARPIECE
-from acts_contrib.test_utils.tel.tel_defines import AUDIO_ROUTE_SPEAKER
-from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_ACTIVE
-from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_HOLDING
-from acts_contrib.test_utils.tel.tel_defines import CALL_CAPABILITY_MANAGE_CONFERENCE
-from acts_contrib.test_utils.tel.tel_defines import CALL_CAPABILITY_MERGE_CONFERENCE
-from acts_contrib.test_utils.tel.tel_defines import CALL_CAPABILITY_SWAP_CONFERENCE
-from acts_contrib.test_utils.tel.tel_defines import CALL_PROPERTY_CONFERENCE
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VIDEO_SESSION_EVENT
-from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOLTE_ENABLED
-from acts_contrib.test_utils.tel.tel_defines import VT_STATE_AUDIO_ONLY
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL
-from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL_PAUSED
-from acts_contrib.test_utils.tel.tel_defines import VT_VIDEO_QUALITY_DEFAULT
-from acts_contrib.test_utils.tel.tel_defines import VT_STATE_RX_ENABLED
-from acts_contrib.test_utils.tel.tel_defines import VT_STATE_TX_ENABLED
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
-from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
-from acts_contrib.test_utils.tel.tel_defines import EVENT_VIDEO_SESSION_EVENT
-from acts_contrib.test_utils.tel.tel_defines import EventTelecomVideoCallSessionEvent
-from acts_contrib.test_utils.tel.tel_defines import SESSION_EVENT_RX_PAUSE
-from acts_contrib.test_utils.tel.tel_defines import SESSION_EVENT_RX_RESUME
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
-from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
-from acts_contrib.test_utils.tel.tel_test_utils import disconnect_call_by_id
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
-from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls
-from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_video_enabled
-from acts_contrib.test_utils.tel.tel_video_utils import get_call_id_in_video_state
-from acts_contrib.test_utils.tel.tel_video_utils import \
- is_phone_in_call_video_bidirectional
-from acts_contrib.test_utils.tel.tel_video_utils import \
- is_phone_in_call_viwifi_bidirectional
-from acts_contrib.test_utils.tel.tel_video_utils import is_phone_in_call_voice_hd
-from acts_contrib.test_utils.tel.tel_video_utils import phone_setup_video
-from acts_contrib.test_utils.tel.tel_video_utils import \
- verify_video_call_in_expected_state
-from acts_contrib.test_utils.tel.tel_video_utils import video_call_downgrade
-from acts_contrib.test_utils.tel.tel_video_utils import video_call_modify_video
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
+from acts_contrib.test_utils.tel.tel_video_utils import is_phone_in_call_viwifi_bidirectional
from acts_contrib.test_utils.tel.tel_video_utils import video_call_setup_teardown
-from acts_contrib.test_utils.tel.tel_voice_utils import get_audio_route
-from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import set_audio_route
-from acts_contrib.test_utils.tel.tel_voice_utils import get_cep_conference_call_id
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
DEFAULT_LONG_DURATION_CALL_TOTAL_DURATION = 1 * 60 * 60 # default 1 hour
diff --git a/acts_tests/tests/google/tel/live/TelWifiVoiceTest.py b/acts_tests/tests/google/tel/live/TelWifiVoiceTest.py
index 1b177836..4fc7c4b 100644
--- a/acts_tests/tests/google/tel/live/TelWifiVoiceTest.py
+++ b/acts_tests/tests/google/tel/live/TelWifiVoiceTest.py
@@ -22,7 +22,7 @@
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_atten_utils import set_rssi
-from acts_contrib.test_utils.tel.tel_defines import CELL_STRONG_RSSI_VALUE
+from acts_contrib.test_utils.tel.tel_defines import ATTEN_MIN_VALUE
from acts_contrib.test_utils.tel.tel_defines import CELL_WEAK_RSSI_VALUE
from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED
from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_TERMINATED
@@ -35,12 +35,8 @@
from acts_contrib.test_utils.tel.tel_defines import MIN_RSSI_RESERVED_VALUE
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
-from acts_contrib.test_utils.tel.tel_defines import PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND
-from acts_contrib.test_utils.tel.tel_defines import PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND
-from acts_contrib.test_utils.tel.tel_defines import PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING
from acts_contrib.test_utils.tel.tel_defines import RAT_LTE
from acts_contrib.test_utils.tel.tel_defines import RAT_IWLAN
-from acts_contrib.test_utils.tel.tel_defines import RAT_WCDMA
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_REG_AND_CALL
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_WIFI_RSSI_CALIBRATION_SCREEN_ON
@@ -54,41 +50,41 @@
from acts_contrib.test_utils.tel.tel_defines import NetworkCallbackAvailable
from acts_contrib.test_utils.tel.tel_defines import NetworkCallbackLost
from acts_contrib.test_utils.tel.tel_defines import SignalStrengthContainer
-from acts_contrib.test_utils.tel.tel_test_utils import wifi_toggle_state
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_generation
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_default_state
-from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_wifi_data_connection
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_disabled
+from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_enabled
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_default_state
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import is_phone_not_in_call
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_3g
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_csfb
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_not_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_volte
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_droid_not_in_call
from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat
from acts_contrib.test_utils.tel.tel_test_utils import get_phone_number
-from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
-from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
from acts_contrib.test_utils.tel.tel_test_utils import is_network_call_back_event_match
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call
-from acts_contrib.test_utils.tel.tel_test_utils import is_phone_not_in_call
-from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
-from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte
-from acts_contrib.test_utils.tel.tel_test_utils import wait_and_answer_call
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_cell_data_connection
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_droid_not_in_call
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wfc_disabled
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wfc_enabled
-from acts_contrib.test_utils.tel.tel_test_utils import wait_for_wifi_data_connection
+from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
from acts_contrib.test_utils.tel.tel_test_utils import get_telephony_signal_strength
-from acts_contrib.test_utils.tel.tel_test_utils import get_wifi_signal_strength
from acts_contrib.test_utils.tel.tel_test_utils import wait_for_state
+from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
+from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
+from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_not_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_general
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_3g
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_csfb
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_not_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_volte
+from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call
+from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
+from acts_contrib.test_utils.tel.tel_wifi_utils import get_wifi_signal_strength
+from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
# Attenuator name
ATTEN_NAME_FOR_WIFI_2G = 'wifi0'
@@ -122,7 +118,7 @@
self.attens = {}
for atten in self.attenuators:
self.attens[atten.path] = atten
- atten.set_atten(atten.get_max_atten()) # Default all attens to max
+ atten.set_atten(ATTEN_MIN_VALUE, retry=True) # Default all attens to min
self.log.info("WFC phone: <{}> <{}>".format(
self.android_devices[0].serial,
@@ -207,13 +203,13 @@
super().teardown_test()
set_rssi(self.log, self.attens[ATTEN_NAME_FOR_WIFI_2G], 0,
- MAX_RSSI_RESERVED_VALUE)
+ MIN_RSSI_RESERVED_VALUE)
set_rssi(self.log, self.attens[ATTEN_NAME_FOR_WIFI_5G], 0,
- MAX_RSSI_RESERVED_VALUE)
+ MIN_RSSI_RESERVED_VALUE)
set_rssi(self.log, self.attens[ATTEN_NAME_FOR_CELL_3G], 0,
- MAX_RSSI_RESERVED_VALUE)
+ MIN_RSSI_RESERVED_VALUE)
set_rssi(self.log, self.attens[ATTEN_NAME_FOR_CELL_4G], 0,
- MAX_RSSI_RESERVED_VALUE)
+ MIN_RSSI_RESERVED_VALUE)
return True
def _wfc_call_sequence(self, ads, mo_mt, initial_wifi_cellular_setup_func,
@@ -3205,16 +3201,20 @@
"""
# Increase LTE RSRP to MAX_RSSI_RESERVED_VALUE
time.sleep(30)
- set_rssi(self.log, self.attens[ATTEN_NAME_FOR_CELL_3G], 0,
- MAX_RSSI_RESERVED_VALUE)
- set_rssi(self.log, self.attens[ATTEN_NAME_FOR_CELL_4G], 0,
- MAX_RSSI_RESERVED_VALUE)
+ if not set_rssi(self.log, self.attens[ATTEN_NAME_FOR_CELL_3G], 0,
+ MAX_RSSI_RESERVED_VALUE):
+ return False
+ if not set_rssi(self.log, self.attens[ATTEN_NAME_FOR_CELL_4G], 0,
+ MAX_RSSI_RESERVED_VALUE):
+ return False
time.sleep(30)
# Decrease WiFi RSSI to MIN_RSSI_RESERVED_VALUE
- set_rssi(self.log, self.attens[ATTEN_NAME_FOR_WIFI_2G], 0,
- MIN_RSSI_RESERVED_VALUE, 5, 1)
- set_rssi(self.log, self.attens[ATTEN_NAME_FOR_WIFI_5G], 0,
- MIN_RSSI_RESERVED_VALUE, 5, 1)
+ if not set_rssi(self.log, self.attens[ATTEN_NAME_FOR_WIFI_2G], 0,
+ MIN_RSSI_RESERVED_VALUE, 5, 1):
+ return False
+ if not set_rssi(self.log, self.attens[ATTEN_NAME_FOR_WIFI_5G], 0,
+ MIN_RSSI_RESERVED_VALUE, 5, 1):
+ return False
# Make sure phone hand-out, not drop call
if not self._phone_wait_for_not_wfc():
self.log.error("Phone should hand out to LTE.")
@@ -3257,8 +3257,10 @@
Increase Cellular RSSI to MAX_RSSI_RESERVED_VALUE
PhoneA should still be in call. PhoneA should hand-out to LTE.
"""
- self._decrease_cellular_rssi_check_phone_hand_out()
- self._increase_lte_decrease_wifi_rssi_check_phone_hand_out()
+ if not self._decrease_cellular_rssi_check_phone_hand_out():
+ return False
+ if not self._increase_lte_decrease_wifi_rssi_check_phone_hand_out():
+ return False
return True
@@ -3528,10 +3530,12 @@
"""
time.sleep(60)
# Decrease Cellular RSSI to MIN_RSSI_RESERVED_VALUE
- set_rssi(self.log, self.attens[ATTEN_NAME_FOR_CELL_3G], 0,
- MIN_RSSI_RESERVED_VALUE, 5, 1)
- set_rssi(self.log, self.attens[ATTEN_NAME_FOR_CELL_4G], 0,
- MIN_RSSI_RESERVED_VALUE, 5, 1)
+ if not set_rssi(self.log, self.attens[ATTEN_NAME_FOR_CELL_3G], 0,
+ MIN_RSSI_RESERVED_VALUE, 5, 1):
+ return False
+ if not set_rssi(self.log, self.attens[ATTEN_NAME_FOR_CELL_4G], 0,
+ MIN_RSSI_RESERVED_VALUE, 5, 1):
+ return False
# Make sure phone hand-out to iWLAN, not drop call
if not self._phone_wait_for_wfc():
self.log.error("Phone should hand out to iWLAN.")
diff --git a/acts_tests/tests/google/tel/live/msim/TelLiveMSIMSmsTest.py b/acts_tests/tests/google/tel/live/msim/TelLiveMSIMSmsTest.py
index ad6e713..83ac659 100644
--- a/acts_tests/tests/google/tel/live/msim/TelLiveMSIMSmsTest.py
+++ b/acts_tests/tests/google/tel/live/msim/TelLiveMSIMSmsTest.py
@@ -15,17 +15,14 @@
# limitations under the License.
import time
-from acts_contrib.test_utils.tel.tel_test_utils \
- import sms_send_receive_verify, multithread_func
-from acts.utils import rand_ascii_str
-from acts_contrib.test_utils.tel.tel_subscription_utils \
- import get_subid_from_slot_index, set_subid_for_message
-from acts_contrib.test_utils.tel.tel_defines \
- import MULTI_SIM_CONFIG, WAIT_TIME_ANDROID_STATE_SETTLING
-from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_voice_utils \
- import phone_setup_voice_general_for_slot
+from acts_contrib.test_utils.tel.tel_defines import MULTI_SIM_CONFIG, WAIT_TIME_ANDROID_STATE_SETTLING
+from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general_for_slot
+from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index, set_subid_for_message
+from acts.libs.utils.multithread import multithread_func
+from acts.test_decorators import test_tracker_info
+from acts.utils import rand_ascii_str
class TelLiveMSIMSmsTest(TelephonyBaseTest):
diff --git a/acts_tests/tests/google/tel/live/msim/TelLiveMSIMVoiceTest.py b/acts_tests/tests/google/tel/live/msim/TelLiveMSIMVoiceTest.py
index 501b0d6..f8c3237 100644
--- a/acts_tests/tests/google/tel/live/msim/TelLiveMSIMVoiceTest.py
+++ b/acts_tests/tests/google/tel/live/msim/TelLiveMSIMVoiceTest.py
@@ -14,12 +14,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from acts_contrib.test_utils.tel.tel_voice_utils \
- import two_phone_call_msim_short_seq, phone_setup_voice_general_for_slot
from acts.test_decorators import test_tracker_info
+from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
from acts_contrib.test_utils.tel.tel_defines import MULTI_SIM_CONFIG
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general_for_slot
+from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_msim_short_seq
class TelLiveMSIMVoiceTest(TelephonyBaseTest):
diff --git a/acts_tests/tests/google/usb/UsbTetheringFunctionsTest.py b/acts_tests/tests/google/usb/UsbTetheringFunctionsTest.py
index 14eb381..be84075 100644
--- a/acts_tests/tests/google/usb/UsbTetheringFunctionsTest.py
+++ b/acts_tests/tests/google/usb/UsbTetheringFunctionsTest.py
@@ -28,6 +28,7 @@
from acts_contrib.test_utils.tel import tel_defines
from acts_contrib.test_utils.tel.anritsu_utils import wait_for_sms_sent_success
from acts_contrib.test_utils.tel.tel_defines import EventMmsSentSuccess
+from acts_contrib.test_utils.tel.tel_bootloader_utils import fastboot_wipe
# Time it takes for the usb tethering IP to
# show up in ifconfig and function waiting.
@@ -407,7 +408,7 @@
5. Run ping test through usb tethering interface.
"""
self.enable_usb_tethering()
- tutils.fastboot_wipe(self.dut)
+ fastboot_wipe(self.dut)
time.sleep(DEFAULT_SETTLE_TIME)
# Skip setup wizard after wipe.
self.dut.adb.shell(
diff --git a/acts_tests/tests/google/wifi/WifiAutoUpdateTest.py b/acts_tests/tests/google/wifi/WifiAutoUpdateTest.py
index 743a155..c50cef7 100755
--- a/acts_tests/tests/google/wifi/WifiAutoUpdateTest.py
+++ b/acts_tests/tests/google/wifi/WifiAutoUpdateTest.py
@@ -20,7 +20,7 @@
from acts.libs.ota import ota_updater
import acts.signals as signals
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
import acts.utils as utils
diff --git a/acts_tests/tests/google/wifi/WifiConnectedMacRandomizationTest.py b/acts_tests/tests/google/wifi/WifiConnectedMacRandomizationTest.py
index 8165c72..28dc90e 100644
--- a/acts_tests/tests/google/wifi/WifiConnectedMacRandomizationTest.py
+++ b/acts_tests/tests/google/wifi/WifiConnectedMacRandomizationTest.py
@@ -21,7 +21,7 @@
import acts.base_test
import acts.signals as signals
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
import acts.utils as utils
diff --git a/acts_tests/tests/google/wifi/WifiCrashStressTest.py b/acts_tests/tests/google/wifi/WifiCrashStressTest.py
index 90e546f..9982cd8 100644
--- a/acts_tests/tests/google/wifi/WifiCrashStressTest.py
+++ b/acts_tests/tests/google/wifi/WifiCrashStressTest.py
@@ -21,7 +21,7 @@
from acts import utils
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
-from acts_contrib.test_utils.tel.tel_test_utils import disable_qxdm_logger
+from acts_contrib.test_utils.tel.tel_logging_utils import disable_qxdm_logger
WifiEnums = wutils.WifiEnums
diff --git a/acts_tests/tests/google/wifi/WifiMacRandomizationTest.py b/acts_tests/tests/google/wifi/WifiMacRandomizationTest.py
index e7fd9fa..d83460d 100644
--- a/acts_tests/tests/google/wifi/WifiMacRandomizationTest.py
+++ b/acts_tests/tests/google/wifi/WifiMacRandomizationTest.py
@@ -27,8 +27,8 @@
from acts import asserts
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
from scapy.all import *
from acts.controllers.ap_lib import hostapd_constants
diff --git a/acts_tests/tests/google/wifi/WifiPingTest.py b/acts_tests/tests/google/wifi/WifiPingTest.py
index 4d25f26..ea45381 100644
--- a/acts_tests/tests/google/wifi/WifiPingTest.py
+++ b/acts_tests/tests/google/wifi/WifiPingTest.py
@@ -306,7 +306,7 @@
zero_counter = 0
for atten in testcase_params['atten_range']:
for attenuator in self.attenuators:
- attenuator.set_atten(atten, strict=False)
+ attenuator.set_atten(atten, strict=False, retry=True)
rssi_future = wputils.get_connected_rssi_nb(
self.dut,
int(testcase_params['ping_duration'] / 2 /
@@ -325,8 +325,8 @@
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(
+ 'Attenuation = {0}dB\tPacket Loss = {1:.1f}%\t'
+ 'Avg RTT = {2:.2f}ms\tRSSI = {3:.2f} [{4},{5}]\t'.format(
atten, current_ping_stats['packet_loss_percentage'],
statistics.mean(current_ping_stats['rtt']),
current_rssi['signal_poll_rssi']['mean'],
@@ -395,6 +395,10 @@
testcase_params['test_network']['SSID']):
self.log.info('Already connected to desired network')
else:
+ wutils.wifi_toggle_state(self.dut, False)
+ wutils.set_wifi_country_code(self.dut,
+ self.testclass_params['country_code'])
+ wutils.wifi_toggle_state(self.dut, True)
wutils.reset_wifi(self.dut)
wutils.set_wifi_country_code(self.dut,
self.testclass_params['country_code'])
@@ -428,7 +432,7 @@
self.setup_ap(testcase_params)
# Set attenuator to 0 dB
for attenuator in self.attenuators:
- attenuator.set_atten(0, strict=False)
+ attenuator.set_atten(0, strict=False, retry=True)
# Reset, configure, and connect DUT
self.setup_dut(testcase_params)
diff --git a/acts_tests/tests/google/wifi/WifiRoamingTest.py b/acts_tests/tests/google/wifi/WifiRoamingTest.py
index 2af178b..2da901c 100644
--- a/acts_tests/tests/google/wifi/WifiRoamingTest.py
+++ b/acts_tests/tests/google/wifi/WifiRoamingTest.py
@@ -276,7 +276,7 @@
"""
for ad in self.android_devices:
wutils.set_wifi_country_code(
- ad, wutils.WifiEnums.CountryCode.AUSTRALIA)
+ ad, wutils.WifiEnums.CountryCode.AUSTRALIA)
if "OpenWrtAP" in self.user_params:
self.configure_openwrt_ap_and_start(open_network=True,
ap_count=2,
@@ -292,9 +292,9 @@
# start softap on 2G and verify the channel is 6.
sap_config = {
- WifiEnums.SSID_KEY: "hotspot_%s" % utils.rand_ascii_str(6),
- WifiEnums.PWD_KEY: "pass_%s" % utils.rand_ascii_str(6),
- WifiEnums.AP_BAND_KEY: WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G}
+ WifiEnums.SSID_KEY: "hotspot_%s" % utils.rand_ascii_str(6),
+ WifiEnums.PWD_KEY: "pass_%s" % utils.rand_ascii_str(6),
+ WifiEnums.AP_BAND_KEY: WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G}
asserts.assert_true(
self.dut.droid.wifiSetWifiApConfiguration(sap_config),
"Failed to set WifiAp Configuration")
@@ -678,7 +678,7 @@
# Configure AP1 to enable capable PMF.
self.configure_openwrt_ap_and_start(wpa_network=True,
- ieee80211w=1)
+ ieee80211w=1)
ap1_network = self.reference_networks[0]["5g"]
ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]]
@@ -1047,15 +1047,16 @@
self.roaming_from_AP1_and_AP2(ap1_network, ap2_network)
@test_tracker_info(uuid="e875233f-d242-4ddd-b357-8e3e215af050")
- def test_roaming_fail_between_psk_to_sae_5g(self):
+ def test_roaming_between_psk_to_sae_5g(self):
"""Verify fail with diff security type after roaming with OpenWrtAP
+ This test will pass after design change but this is not seamless roaming.
Steps:
1. Configure 2 APs security type to sae
2. Configure AP1 security type to psk
3. Connect DUT to AP1
4. Roam to AP2
- 5. Verify the DUT can't connect to AP2 after roaming
+ 5. Verify the DUT connect to AP2 after roaming
"""
# Use OpenWrt as Wi-Fi AP when it's available in testbed.
asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params")
@@ -1081,15 +1082,10 @@
ap2_network["SSID"] = ap1_network["SSID"]
ap2_network["password"] = ap1_network["password"]
- try:
- # DUT roaming from AP1 to AP2 with diff security type.
- self.dut.log.info("Roaming via WPA2 AP1 to SAE AP2 [{}]"
- .format(ap2_network["bssid"]))
- self.roaming_from_AP1_and_AP2(ap1_network, ap2_network)
- except:
- self.dut.log.info("Failed roaming to AP2 with diff security type")
- else:
- raise signals.TestFailure("DUT unexpectedly connect to Wi-Fi.")
+ # DUT roaming from AP1 to AP2 with diff security type.
+ # Expect device disconnect from AP1 and connect to AP2 due to
+ # saved network contain AP2.
+ self.roaming_from_AP1_and_AP2(ap1_network, ap2_network)
@test_tracker_info(uuid="76098016-56a4-4b92-8c13-7333a21c9a1b")
def test_roaming_between_psk_to_saemixed_2g(self):
diff --git a/acts_tests/tests/google/wifi/WifiRvrTest.py b/acts_tests/tests/google/wifi/WifiRvrTest.py
index 7131d80..5096f93 100644
--- a/acts_tests/tests/google/wifi/WifiRvrTest.py
+++ b/acts_tests/tests/google/wifi/WifiRvrTest.py
@@ -373,7 +373,7 @@
asserts.skip('DUT health check failed. Skipping test.')
# Set Attenuation
for attenuator in self.attenuators:
- attenuator.set_atten(atten, strict=False)
+ attenuator.set_atten(atten, strict=False, retry=True)
# Refresh link layer stats
llstats_obj.update_stats()
# Setup sniffer
@@ -453,7 +453,7 @@
(len(testcase_params['atten_range']) - len(throughput)))
break
for attenuator in self.attenuators:
- attenuator.set_atten(0, strict=False)
+ attenuator.set_atten(0, strict=False, retry=True)
# Compile test result and meta data
rvr_result = collections.OrderedDict()
rvr_result['test_name'] = self.current_test_name
@@ -512,8 +512,12 @@
testcase_params['test_network']['SSID']):
self.log.info('Already connected to desired network')
else:
- wutils.reset_wifi(self.sta_dut)
- wutils.set_wifi_country_code(self.sta_dut,
+ wutils.wifi_toggle_state(self.dut, False)
+ wutils.set_wifi_country_code(self.dut,
+ self.testclass_params['country_code'])
+ wutils.wifi_toggle_state(self.dut, True)
+ wutils.reset_wifi(self.dut)
+ wutils.set_wifi_country_code(self.dut,
self.testclass_params['country_code'])
if self.testbed_params['sniffer_enable']:
self.sniffer.start_capture(
@@ -540,7 +544,7 @@
self.setup_ap(testcase_params)
# Set attenuator to 0 dB
for attenuator in self.attenuators:
- attenuator.set_atten(0, strict=False)
+ attenuator.set_atten(0, strict=False, retry=True)
# Reset, configure, and connect DUT
self.setup_dut(testcase_params)
# Wait before running the first wifi test
diff --git a/acts_tests/tests/google/wifi/WifiSensitivityTest.py b/acts_tests/tests/google/wifi/WifiSensitivityTest.py
index b876ae9..41aa32c 100644
--- a/acts_tests/tests/google/wifi/WifiSensitivityTest.py
+++ b/acts_tests/tests/google/wifi/WifiSensitivityTest.py
@@ -246,7 +246,7 @@
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)
+ metric_value = numpy.mean(metric_data)
self.testclass_metric_logger.add_metric(metric_key, metric_value)
# write csv
@@ -395,6 +395,10 @@
testcase_params['test_network']['SSID']):
self.log.info('Already connected to desired network')
else:
+ wutils.wifi_toggle_state(self.dut, False)
+ wutils.set_wifi_country_code(self.dut,
+ self.testclass_params['country_code'])
+ wutils.wifi_toggle_state(self.dut, True)
wutils.reset_wifi(self.dut)
wutils.set_wifi_country_code(self.dut,
self.testclass_params['country_code'])
@@ -689,6 +693,10 @@
testcase_params['test_network']['SSID']):
self.log.info('Already connected to desired network')
else:
+ wutils.wifi_toggle_state(self.dut, False)
+ wutils.set_wifi_country_code(self.dut,
+ self.testclass_params['country_code'])
+ wutils.wifi_toggle_state(self.dut, True)
wutils.reset_wifi(self.dut)
wutils.set_wifi_country_code(self.dut,
self.testclass_params['country_code'])
@@ -697,7 +705,7 @@
wutils.wifi_connect(self.dut,
testcase_params['test_network'],
num_of_tries=5,
- check_connectivity=False)
+ check_connectivity=True)
self.dut_ip = self.dut.droid.connectivityGetIPv4Addresses('wlan0')[0]
def process_testclass_results(self):
diff --git a/acts_tests/tests/google/wifi/WifiSoftApAcsTest.py b/acts_tests/tests/google/wifi/WifiSoftApAcsTest.py
index da7877d..886754f 100644
--- a/acts_tests/tests/google/wifi/WifiSoftApAcsTest.py
+++ b/acts_tests/tests/google/wifi/WifiSoftApAcsTest.py
@@ -28,8 +28,8 @@
from acts import asserts
from acts.controllers.ap_lib import hostapd_constants
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
from threading import Thread
diff --git a/acts_tests/tests/google/wifi/WifiSoftApMultiCountryTest.py b/acts_tests/tests/google/wifi/WifiSoftApMultiCountryTest.py
index af34ce9..f5173ff 100644
--- a/acts_tests/tests/google/wifi/WifiSoftApMultiCountryTest.py
+++ b/acts_tests/tests/google/wifi/WifiSoftApMultiCountryTest.py
@@ -30,9 +30,9 @@
from acts_contrib.test_utils.net import socket_test_utils as sutils
from acts_contrib.test_utils.tel import tel_defines
from acts_contrib.test_utils.tel import tel_test_utils as tel_utils
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_AUTO
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_AUTO
from acts_contrib.test_utils.wifi import wifi_constants
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
diff --git a/acts_tests/tests/google/wifi/WifiStaApConcurrencyStressTest.py b/acts_tests/tests/google/wifi/WifiStaApConcurrencyStressTest.py
index 9fddb69..21333e3 100755
--- a/acts_tests/tests/google/wifi/WifiStaApConcurrencyStressTest.py
+++ b/acts_tests/tests/google/wifi/WifiStaApConcurrencyStressTest.py
@@ -22,8 +22,8 @@
from acts import signals
from acts import utils
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
from WifiStaApConcurrencyTest import WifiStaApConcurrencyTest
import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
diff --git a/acts_tests/tests/google/wifi/WifiStaApConcurrencyTest.py b/acts_tests/tests/google/wifi/WifiStaApConcurrencyTest.py
index 846d57c..4775c15 100644
--- a/acts_tests/tests/google/wifi/WifiStaApConcurrencyTest.py
+++ b/acts_tests/tests/google/wifi/WifiStaApConcurrencyTest.py
@@ -23,8 +23,8 @@
from acts.controllers.ap_lib import hostapd_constants
import acts.signals as signals
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
import acts.utils as utils
diff --git a/acts_tests/tests/google/wifi/WifiTeleCoexTest.py b/acts_tests/tests/google/wifi/WifiTeleCoexTest.py
index 7260919..02e9541 100644
--- a/acts_tests/tests/google/wifi/WifiTeleCoexTest.py
+++ b/acts_tests/tests/google/wifi/WifiTeleCoexTest.py
@@ -13,10 +13,13 @@
from acts import signals
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_general
+from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
+from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_short_seq
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_iwlan
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_iwlan
from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import GEN_4G
@@ -68,7 +71,7 @@
for ad in self.android_devices:
wifi_utils.reset_wifi(ad)
ad.droid.telephonyToggleDataConnection(False)
- tele_utils.ensure_phones_idle(self.log, self.android_devices)
+ ensure_phones_idle(self.log, self.android_devices)
nutil.stop_usb_tethering(self.dut)
"""Helper Functions"""
@@ -208,14 +211,14 @@
"""
tele_utils.toggle_airplane_mode(self.log, self.android_devices[0], False)
- tele_utils.toggle_volte(self.log, self.android_devices[0], volte_mode)
+ toggle_volte(self.log, self.android_devices[0], volte_mode)
if not tele_utils.ensure_network_generation(
self.log,
self.android_devices[0],
GEN_4G,
voice_or_data=NETWORK_SERVICE_DATA):
return False
- if not tele_utils.set_wfc_mode(self.log, self.android_devices[0], wfc_mode):
+ if not set_wfc_mode(self.log, self.android_devices[0], wfc_mode):
self.log.error("{} set WFC mode failed.".format(
self.android_devices[0].serial))
return False
diff --git a/acts_tests/tests/google/wifi/WifiTethering2GOpenOTATest.py b/acts_tests/tests/google/wifi/WifiTethering2GOpenOTATest.py
index 0790546..af2648b 100755
--- a/acts_tests/tests/google/wifi/WifiTethering2GOpenOTATest.py
+++ b/acts_tests/tests/google/wifi/WifiTethering2GOpenOTATest.py
@@ -20,7 +20,7 @@
from acts.base_test import BaseTestClass
from acts.libs.ota import ota_updater
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
import acts_contrib.test_utils.net.net_test_utils as nutils
import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
diff --git a/acts_tests/tests/google/wifi/WifiTethering2GPskOTATest.py b/acts_tests/tests/google/wifi/WifiTethering2GPskOTATest.py
index c0b6d28..7d3c988 100755
--- a/acts_tests/tests/google/wifi/WifiTethering2GPskOTATest.py
+++ b/acts_tests/tests/google/wifi/WifiTethering2GPskOTATest.py
@@ -20,7 +20,7 @@
from acts.base_test import BaseTestClass
from acts.libs.ota import ota_updater
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
import acts_contrib.test_utils.net.net_test_utils as nutils
import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
diff --git a/acts_tests/tests/google/wifi/WifiTethering5GOpenOTATest.py b/acts_tests/tests/google/wifi/WifiTethering5GOpenOTATest.py
index 12f6824..151bedf 100755
--- a/acts_tests/tests/google/wifi/WifiTethering5GOpenOTATest.py
+++ b/acts_tests/tests/google/wifi/WifiTethering5GOpenOTATest.py
@@ -20,7 +20,7 @@
from acts.base_test import BaseTestClass
from acts.libs.ota import ota_updater
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
import acts_contrib.test_utils.net.net_test_utils as nutils
import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
diff --git a/acts_tests/tests/google/wifi/WifiTethering5GPskOTATest.py b/acts_tests/tests/google/wifi/WifiTethering5GPskOTATest.py
index de0f901..b293206 100755
--- a/acts_tests/tests/google/wifi/WifiTethering5GPskOTATest.py
+++ b/acts_tests/tests/google/wifi/WifiTethering5GPskOTATest.py
@@ -20,7 +20,7 @@
from acts.base_test import BaseTestClass
from acts.libs.ota import ota_updater
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
import acts_contrib.test_utils.net.net_test_utils as nutils
import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
diff --git a/acts_tests/tests/google/wifi/WifiTetheringPowerTest.py b/acts_tests/tests/google/wifi/WifiTetheringPowerTest.py
index 577e100..84fc6aa 100644
--- a/acts_tests/tests/google/wifi/WifiTetheringPowerTest.py
+++ b/acts_tests/tests/google/wifi/WifiTetheringPowerTest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3.4
#
-# Copyright 2017 - The Android Open Source Project
+# Copyright 2022 - 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.
@@ -25,9 +25,9 @@
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
from acts_contrib.test_utils.tel import tel_data_utils as tel_utils
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
-from acts_contrib.test_utils.tel.tel_test_utils import http_file_download_by_chrome
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_data_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
diff --git a/acts_tests/tests/google/wifi/WifiTetheringTest.py b/acts_tests/tests/google/wifi/WifiTetheringTest.py
index 99028d0..730bae3 100644
--- a/acts_tests/tests/google/wifi/WifiTetheringTest.py
+++ b/acts_tests/tests/google/wifi/WifiTetheringTest.py
@@ -24,11 +24,9 @@
from acts.controllers import adb
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel import tel_defines
-from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection
from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
-from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
from acts_contrib.test_utils.net import socket_test_utils as sutils
from acts_contrib.test_utils.net import arduino_test_utils as dutils
from acts_contrib.test_utils.net import net_test_utils as nutils
diff --git a/acts_tests/tests/google/wifi/rtt/functional/RangeApSupporting11McTest.py b/acts_tests/tests/google/wifi/rtt/functional/RangeApSupporting11McTest.py
index 020f6e2..dfdb1ab 100644
--- a/acts_tests/tests/google/wifi/rtt/functional/RangeApSupporting11McTest.py
+++ b/acts_tests/tests/google/wifi/rtt/functional/RangeApSupporting11McTest.py
@@ -19,7 +19,7 @@
from acts import asserts
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
from acts_contrib.test_utils.wifi.rtt import rtt_const as rconsts
from acts_contrib.test_utils.wifi.rtt import rtt_test_utils as rutils
diff --git a/acts_tests/tests/google/wifi/rtt/functional/RangeSoftApTest.py b/acts_tests/tests/google/wifi/rtt/functional/RangeSoftApTest.py
index 6f7d5fe..daf2469 100644
--- a/acts_tests/tests/google/wifi/rtt/functional/RangeSoftApTest.py
+++ b/acts_tests/tests/google/wifi/rtt/functional/RangeSoftApTest.py
@@ -16,7 +16,7 @@
from acts import asserts
from acts.test_decorators import test_tracker_info
-from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G
+from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
from acts_contrib.test_utils.wifi.rtt import rtt_const as rconsts
from acts_contrib.test_utils.wifi.rtt import rtt_test_utils as rutils
diff --git a/tools/create_virtualenv.sh b/tools/create_virtualenv.sh
index 197282a..ad4931d 100755
--- a/tools/create_virtualenv.sh
+++ b/tools/create_virtualenv.sh
@@ -11,10 +11,10 @@
virtualenv='/tmp/acts_preupload_virtualenv'
echo "preparing virtual env" > "${virtualenv}.log"
-python3 -m virtualenv -p python3 $virtualenv &>> "${virtualenv}.log"
+python3 -m virtualenv -p python3 $virtualenv >> "${virtualenv}.log" 2>&1
cp -r acts/framework $virtualenv/
cd $virtualenv/framework
echo "installing acts in virtual env" >> "${virtualenv}.log"
-$virtualenv/bin/python3 setup.py develop &>> "${virtualenv}.log"
+$virtualenv/bin/python3 setup.py develop >> "${virtualenv}.log" 2>&1
cd -
echo "done" >> "${virtualenv}.log"