Merge "Added Telephony Bootup Time Test"
diff --git a/acts/framework/acts/base_test.py b/acts/framework/acts/base_test.py
index 0dab072..c6e4a00 100755
--- a/acts/framework/acts/base_test.py
+++ b/acts/framework/acts/base_test.py
@@ -68,7 +68,7 @@
         self.results = records.TestResult()
         self.current_test_name = None
         self.log = tracelogger.TraceLogger(self.log)
-        if 'self.android_devices' in self.__dict__:
+        if 'android_devices' in self.__dict__:
             for ad in self.android_devices:
                 if ad.droid:
                     utils.set_location_service(ad, False)
diff --git a/acts/framework/acts/controllers/anritsu_lib/md8475a.py b/acts/framework/acts/controllers/anritsu_lib/md8475a.py
index 07c1b7a..584cf53 100644
--- a/acts/framework/acts/controllers/anritsu_lib/md8475a.py
+++ b/acts/framework/acts/controllers/anritsu_lib/md8475a.py
@@ -32,8 +32,8 @@
 # the times for socket to time out. Increasing them is to make sure there is
 # enough time for MD8475A operation to be completed in some cases.
 # It won't increase test execution time.
-SMARTSTUDIO_LAUNCH_WAIT_TIME = 180  # was 90
-SMARTSTUDIO_SIMULATION_START_WAIT_TIME = 180  # was 120
+SMARTSTUDIO_LAUNCH_WAIT_TIME = 300  # was 90
+SMARTSTUDIO_SIMULATION_START_WAIT_TIME = 300  # was 120
 REGISTRATION_STATE_WAIT_TIME = 240
 LOAD_SIMULATION_PARAM_FILE_WAIT_TIME = 30
 COMMUNICATION_STATE_WAIT_TIME = 240
@@ -383,7 +383,7 @@
                       "Signaling Tester ({}) ".format(self._ipaddr))
         try:
             self._sock = socket.create_connection(
-                (self._ipaddr, 28002), timeout=30)
+                (self._ipaddr, 28002), timeout=120)
             self.send_query("*IDN?", 60)
             self.log.info("Communication with Signaling Tester OK.")
             self.log.info("Opened Socket connection to ({})"
@@ -818,8 +818,8 @@
         for _ in range(registration_check_iterations):
             waiting_time = 0
             while waiting_time <= time_to_wait:
-                callstat = self.send_query("CALLSTAT? BTS{}".format(
-                    bts)).split(",")
+                callstat = self.send_query(
+                    "CALLSTAT? BTS{}".format(bts)).split(",")
                 if callstat[0] == "IDLE" or callstat[1] == "COMMUNICATION":
                     break
                 time.sleep(sleep_interval)
diff --git a/acts/framework/acts/test_utils/tel/anritsu_utils.py b/acts/framework/acts/test_utils/tel/anritsu_utils.py
index 6989451..173c839 100644
--- a/acts/framework/acts/test_utils/tel/anritsu_utils.py
+++ b/acts/framework/acts/test_utils/tel/anritsu_utils.py
@@ -122,7 +122,7 @@
 WCDMA_BAND_2 = 2
 
 # Default Cell Parameters
-DEFAULT_OUTPUT_LEVEL = -40
+DEFAULT_OUTPUT_LEVEL = -30
 DEFAULT_INPUT_LEVEL = -10  # apply to LTE & WCDMA only
 DEFAULT_LTE_BAND = 2
 DEFAULT_WCDMA_BAND = 1
diff --git a/acts/framework/acts/test_utils/tel/tel_test_utils.py b/acts/framework/acts/test_utils/tel/tel_test_utils.py
index 0cba1d8..c7960a9 100644
--- a/acts/framework/acts/test_utils/tel/tel_test_utils.py
+++ b/acts/framework/acts/test_utils/tel/tel_test_utils.py
@@ -3926,7 +3926,7 @@
     Returns:
         results for tasks.
     """
-    MAX_NUMBER_OF_WORKERS = 4
+    MAX_NUMBER_OF_WORKERS = 5
     number_of_workers = min(MAX_NUMBER_OF_WORKERS, len(tasks))
     executor = concurrent.futures.ThreadPoolExecutor(
         max_workers=number_of_workers)
diff --git a/acts/tests/google/bt/BtAirplaneModeTest.py b/acts/tests/google/bt/BtAirplaneModeTest.py
index 90334fe..06a4af6 100644
--- a/acts/tests/google/bt/BtAirplaneModeTest.py
+++ b/acts/tests/google/bt/BtAirplaneModeTest.py
@@ -21,7 +21,7 @@
 from acts.test_decorators import test_tracker_info
 from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
 from acts.test_utils.bt.bt_test_utils import bluetooth_enabled_check
-from acts.test_utils.tel.tel_test_utils import toggle_airplane_mode
+from acts.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
 from queue import Empty
 import time
 
@@ -38,7 +38,7 @@
     def setup_test(self):
         super(BluetoothBaseTest, self).setup_test()
         # Ensure testcase starts with Airplane mode off
-        if not toggle_airplane_mode(self.log, self.dut, False):
+        if not toggle_airplane_mode_by_adb(self.log, self.dut, False):
             return False
         time.sleep(self.WAIT_TIME_ANDROID_STATE_SETTLING)
         return True
@@ -69,7 +69,7 @@
         if not bluetooth_enabled_check(self.dut):
             self.log.error("Failed to set Bluetooth state to enabled")
             return False
-        if not toggle_airplane_mode(self.log, self.dut, True):
+        if not toggle_airplane_mode_by_adb(self.log, self.dut, True):
             self.log.error("Failed to toggle airplane mode on")
             return False
         return not self.dut.droid.bluetoothCheckState()
@@ -102,12 +102,13 @@
         if not bluetooth_enabled_check(self.dut):
             self.log.error("Failed to set Bluetooth state to enabled")
             return False
-        if not toggle_airplane_mode(self.log, self.dut, True):
+        if not toggle_airplane_mode_by_adb(self.log, self.dut, True):
             self.log.error("Failed to toggle airplane mode on")
             return False
         toggle_timeout = 60
-        self.log.info("Waiting {} seconds until verifying Bluetooth state.".
-                      format(toggle_timeout))
+        self.log.info(
+            "Waiting {} seconds until verifying Bluetooth state.".format(
+                toggle_timeout))
         time.sleep(toggle_timeout)
         return not self.dut.droid.bluetoothCheckState()
 
@@ -140,10 +141,10 @@
         if not bluetooth_enabled_check(self.dut):
             self.log.error("Failed to set Bluetooth state to enabled")
             return False
-        if not toggle_airplane_mode(self.log, self.dut, True):
+        if not toggle_airplane_mode_by_adb(self.log, self.dut, True):
             self.log.error("Failed to toggle airplane mode on")
             return False
-        if not toggle_airplane_mode(self.log, self.dut, False):
+        if not toggle_airplane_mode_by_adb(self.log, self.dut, False):
             self.log.error("Failed to toggle airplane mode off")
             return False
         time.sleep(self.WAIT_TIME_ANDROID_STATE_SETTLING)
diff --git a/acts/tests/google/bt/pts/BtCmdLineTest.py b/acts/tests/google/bt/pts/BtCmdLineTest.py
new file mode 100644
index 0000000..842172d
--- /dev/null
+++ b/acts/tests/google/bt/pts/BtCmdLineTest.py
@@ -0,0 +1,89 @@
+#/usr/bin/env python3.4
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+"""
+Script for initializing a cmd line tool for PTS and other purposes.
+Required custom config parameters:
+'target_mac_address': '00:00:00:00:00:00'
+
+Optional config parameters:
+'sim_conf_file' : '/path_to_config/'
+"""
+from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
+from cmd_input import CmdInput
+from queue import Empty
+import os
+import uuid
+
+
+class BtCmdLineTest(BluetoothBaseTest):
+    target_mac_address = ""
+
+    def __init__(self, controllers):
+        BluetoothBaseTest.__init__(self, controllers)
+        if not "target_mac_address" in self.user_params.keys():
+            self.log.error(
+                "Missing mandatory user config \"target_mac_address\"!")
+            return False
+        self.target_mac_address = self.user_params["target_mac_address"].upper(
+        )
+
+        self.android_devices[0].droid.bluetoothSetLocalName("CMD LINE Test")
+        if len(self.android_devices) > 1:
+            #Setup for more complex testcases
+            if not "sim_conf_file" in self.user_params.keys():
+                self.log.error(
+                    "Missing mandatory user config \"sim_conf_file\"!")
+                return False
+            sim_conf_file = self.user_params["sim_conf_file"]
+            # If the sim_conf_file is not a full path, attempt to find it
+            # relative to the config file.
+            if not os.path.isfile(sim_conf_file):
+                sim_conf_file = os.path.join(
+                    self.user_params[Config.key_config_path], sim_conf_file)
+                if not os.path.isfile(sim_conf_file):
+                    log.error("Unable to load user config " + sim_conf_file +
+                              " from test config file.")
+                    return False
+            for ad in self.android_devices:
+                setup_droid_properties(self.log, ad, sim_conf_file)
+            music_path_str = "music_path"
+            android_music_path = "/sdcard/Music/"
+            if music_path_str not in self.user_params:
+                log.error("Need music for A2DP testcases")
+                return False
+            music_path = self.user_params[music_path_str]
+            self._add_music_to_primary_android_device(music_path,
+                                                      android_music_path)
+
+    def _add_music_to_primary_android_device(self, music_path,
+                                             android_music_path):
+        music_list = []
+        for dirname, dirnames, filenames in os.walk(music_path):
+            for filename in filenames:
+                file = os.path.join(dirname, filename)
+                #TODO: Handle file paths with spaces
+                self.android_devices[0].adb.push("{} {}".format(
+                    file, android_music_path))
+
+    def setup_class(self):
+        return True
+
+    def test_pts_cmd_line_helper(self):
+        cmd_line = CmdInput()
+        cmd_line.setup_vars(self.android_devices, self.target_mac_address,
+                            self.log)
+        cmd_line.cmdloop()
+        return True
diff --git a/acts/tests/google/bt/pts/cmd_input.py b/acts/tests/google/bt/pts/cmd_input.py
new file mode 100644
index 0000000..278c108
--- /dev/null
+++ b/acts/tests/google/bt/pts/cmd_input.py
@@ -0,0 +1,42 @@
+#/usr/bin/env python3.4
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+"""
+Python script for wrappers to various libraries.
+"""
+
+import cmd
+"""Various Global Strings"""
+CMD_LOG = "CMD {} result: {}"
+FAILURE = "CMD {} threw exception: {}"
+
+
+class CmdInput(cmd.Cmd):
+    """Simple command processor for Bluetooth PTS Testing"""
+
+    def setup_vars(self, android_devices, mac_addr, log):
+        self.pri_dut = android_devices[0]
+        if len(android_devices) > 1:
+            self.sec_dut = android_devices[1]
+            self.ter_dut = android_devices[2]
+        self.mac_addr = mac_addr
+        self.log = log
+
+    def emptyline(self):
+        pass
+
+    def do_EOF(self, line):
+        "End Script"
+        return True
diff --git a/acts/tests/google/tel/lab/TelLabSmsTest.py b/acts/tests/google/tel/lab/TelLabSmsTest.py
index 62619ae..bfe990a 100644
--- a/acts/tests/google/tel/lab/TelLabSmsTest.py
+++ b/acts/tests/google/tel/lab/TelLabSmsTest.py
@@ -61,6 +61,7 @@
         self.ad = self.android_devices[0]
         self.md8475a_ip_address = self.user_params[
             "anritsu_md8475a_ip_address"]
+        self.ad.sim_card = getattr(self.ad, "sim_card", None)
 
     def setup_class(self):
         try:
@@ -95,7 +96,8 @@
         try:
             self.anritsu.reset()
             self.anritsu.load_cell_paramfile(self.CELL_PARAM_FILE)
-            set_simulation_func(self.anritsu, self.user_params)
+            set_simulation_func(self.anritsu, self.user_params,
+                                self.ad.sim_card)
             self.anritsu.start_simulation()
 
             if rat == RAT_LTE:
@@ -114,11 +116,12 @@
                 self.log.error("No valid RAT provided for SMS test.")
                 return False
 
-            if not ensure_network_rat(self.log,
-                                      self.ad,
-                                      preferred_network_setting,
-                                      rat_family,
-                                      toggle_apm_after_setting=True):
+            if not ensure_network_rat(
+                    self.log,
+                    self.ad,
+                    preferred_network_setting,
+                    rat_family,
+                    toggle_apm_after_setting=True):
                 self.log.error(
                     "Failed to set rat family {}, preferred network:{}".format(
                         rat_family, preferred_network_setting))
@@ -145,8 +148,8 @@
                            str(e))
             return False
         except Exception as e:
-            self.log.error("Exception during emergency call procedure: " + str(
-                e))
+            self.log.error("Exception during emergency call procedure: " +
+                           str(e))
             return False
         return True
 
@@ -499,7 +502,8 @@
             rand_ascii_str(MULTI_PART_LEN),
             "multi part contains é in first part", 10)
         return self._setup_sms(set_system_model_wcdma, RAT_WCDMA,
-                               self.phoneNumber, text, DIRECTION_MOBILE_ORIGINATED)
+                               self.phoneNumber, text,
+                               DIRECTION_MOBILE_ORIGINATED)
 
     @TelephonyBaseTest.tel_test_wrap
     def test_mt_sms_multipart1_eacute_wcdma(self):
@@ -629,7 +633,8 @@
             rand_ascii_str(SINGLE_PART_LEN_75),
             "single part more than 71 characters with é", 72)
         return self._setup_sms(set_system_model_wcdma, RAT_WCDMA,
-                               self.phoneNumber, text, DIRECTION_MOBILE_TERMINATED)
+                               self.phoneNumber, text,
+                               DIRECTION_MOBILE_TERMINATED)
 
     @TelephonyBaseTest.tel_test_wrap
     def test_mo_sms_singlepart_gsm(self):
diff --git a/acts/tests/google/tel/lab/TelLabUeIdentityTest.py b/acts/tests/google/tel/lab/TelLabUeIdentityTest.py
index 6fedf87..9ca701c 100644
--- a/acts/tests/google/tel/lab/TelLabUeIdentityTest.py
+++ b/acts/tests/google/tel/lab/TelLabUeIdentityTest.py
@@ -52,6 +52,7 @@
         self.ad = self.android_devices[0]
         self.md8475a_ip_address = self.user_params[
             "anritsu_md8475a_ip_address"]
+        self.ad.sim_card = getattr(self.ad, "sim_card", None)
 
     def setup_class(self):
         try:
@@ -80,7 +81,8 @@
         try:
             self.anritsu.reset()
             self.anritsu.load_cell_paramfile(self.CELL_PARAM_FILE)
-            set_simulation_func(self.anritsu, self.user_params)
+            set_simulation_func(self.anritsu, self.user_params,
+                                self.ad.sim_card)
             self.anritsu.start_simulation()
 
             if rat == RAT_LTE:
@@ -100,11 +102,12 @@
                 return False
 
             self.ad.droid.telephonyToggleDataConnection(True)
-            if not ensure_network_rat(self.log,
-                                      self.ad,
-                                      preferred_network_setting,
-                                      rat_family,
-                                      toggle_apm_after_setting=True):
+            if not ensure_network_rat(
+                    self.log,
+                    self.ad,
+                    preferred_network_setting,
+                    rat_family,
+                    toggle_apm_after_setting=True):
                 self.log.error(
                     "Failed to set rat family {}, preferred network:{}".format(
                         rat_family, preferred_network_setting))
diff --git a/acts/tests/google/tel/live/TelLiveMobilityStressTest.py b/acts/tests/google/tel/live/TelLiveMobilityStressTest.py
new file mode 100644
index 0000000..0dbe855
--- /dev/null
+++ b/acts/tests/google/tel/live/TelLiveMobilityStressTest.py
@@ -0,0 +1,249 @@
+#!/usr/bin/env python3.4
+#
+#   Copyright 2017 - 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 Telephony Mobility Stress Test
+"""
+
+import collections
+import random
+import time
+from acts.test_decorators import test_tracker_info
+from acts.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
+from acts.test_utils.tel.tel_test_utils import active_file_download_test
+from acts.test_utils.tel.tel_test_utils import call_setup_teardown
+from acts.test_utils.tel.tel_test_utils import ensure_phone_default_state
+from acts.test_utils.tel.tel_test_utils import ensure_phone_subscription
+from acts.test_utils.tel.tel_test_utils import ensure_phones_idle
+from acts.test_utils.tel.tel_test_utils import ensure_wifi_connected
+from acts.test_utils.tel.tel_test_utils import hangup_call
+from acts.test_utils.tel.tel_test_utils import run_multithread_func
+from acts.test_utils.tel.tel_test_utils import set_wfc_mode
+from acts.test_utils.tel.tel_test_utils import sms_send_receive_verify
+from acts.test_utils.tel.tel_test_utils import mms_send_receive_verify
+from acts.test_utils.tel.tel_test_utils import verify_incall_state
+from acts.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
+from acts.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
+from acts.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
+from acts.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
+from acts.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
+from acts.test_utils.tel.tel_voice_utils import phone_setup_csfb
+from acts.test_utils.tel.tel_voice_utils import phone_setup_iwlan
+from acts.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
+from acts.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
+from acts.test_utils.tel.tel_voice_utils import phone_setup_volte
+from acts.utils import rand_ascii_str
+from TelWifiVoiceTest import TelWifiVoiceTest
+
+
+class TelLiveMobilityStressTest(TelWifiVoiceTest):
+    def setup_class(self):
+        super().setup_class()
+        #super(TelWifiVoiceTest, self).setup_class()
+        self.user_params["telephony_auto_rerun"] = False
+        self.max_phone_call_duration = int(
+            self.user_params.get("max_phone_call_duration", 600))
+        self.max_sleep_time = int(self.user_params.get("max_sleep_time", 120))
+        self.max_run_time = int(self.user_params.get("max_run_time", 18000))
+        self.max_sms_length = int(self.user_params.get("max_sms_length", 1000))
+        self.max_mms_length = int(self.user_params.get("max_mms_length", 160))
+        self.crash_check_interval = int(
+            self.user_params.get("crash_check_interval", 300))
+        self.dut = self.android_devices[0]
+        self.helper = self.android_devices[1]
+
+        return True
+
+    def _setup_volte_wfc_wifi_preferred(self):
+        return self._wfc_phone_setup(
+            False, WFC_MODE_WIFI_PREFERRED, volte_mode=True)
+
+    def _setup_volte_wfc_cell_preferred(self):
+        return self._wfc_phone_setup(
+            False, WFC_MODE_CELLULAR_PREFERRED, volte_mode=True)
+
+    def _setup_csfb_wfc_wifi_preferred(self):
+        return self._wfc_phone_setup(
+            False, WFC_MODE_WIFI_PREFERRED, volte_mode=False)
+
+    def _setup_csfb_wfc_cell_preferred(self):
+        return self._wfc_phone_setup(
+            False, WFC_MODE_CELLULAR_PREFERRED, volte_mode=False)
+
+    def _send_message(self, ads):
+        selection = random.randrange(0, 2)
+        message_type_map = {0: "SMS", 1: "MMS"}
+        max_length_map = {0: self.max_sms_length, 1: self.max_mms_length}
+        length = random.randrange(0, max_length_map[selection] + 1)
+        text = rand_ascii_str(length)
+        message_content_map = {0: [text], 1: [("Mms Message", text, None)]}
+        message_func_map = {
+            0: sms_send_receive_verify,
+            1: mms_send_receive_verify
+        }
+        if not message_func_map[selection](self.log, ads[0], ads[1],
+                                           message_content_map[selection]):
+            self.log.error("%s of length %s from %s to %s fails",
+                           message_type_map[selection], length, ads[0].serial,
+                           ads[1].serial)
+            return False
+        else:
+            self.log.info("%s of length %s from %s to %s succeed",
+                          message_type_map[selection], length, ads[0].serial,
+                          ads[1].serial)
+            return False
+
+    def _make_phone_call(self, ads):
+        if not call_setup_teardown(
+                self.log,
+                ads[0],
+                ads[1],
+                ad_hangup=ads[random.randrange(0, 2)],
+                wait_time_in_call=random.randrange(
+                    1, self.max_phone_call_duration)):
+            ads[0].log.error("Setup phone Call failed.")
+            return False
+        ads[0].log.info("Setup call successfully.")
+        return True
+
+    def _download_file(self):
+        #file_names = ["5MB", "10MB", "20MB", "50MB", "200MB", "512MB", "1GB"]
+        #wifi download is very slow in lab, limit the file size upto 200MB
+        file_names = ["5MB", "10MB", "20MB", "50MB", "200MB"]
+        selection = random.randrange(0, 7)
+        return active_file_download_test(self.log, self.dut,
+                                         file_names[selection])
+
+    def check_crash(self):
+        new_crash = self.dut.check_crash_report()
+        crash_diff = set(new_crash).difference(set(self.dut.crash_report))
+        self.dut.crash_report = new_crash
+        if crash_diff:
+            self.dut.log.error("Find new crash reports %s", list(crash_diff))
+            self.dut.pull_files(list(crash_diff))
+            return False
+        return True
+
+    def crash_check_test(self):
+        failure = 0
+        while time.time() < self.finishing_time:
+            if not self.check_crash():
+                failure += 1
+                self.log.error("Crash found count: %s", failure)
+                self._take_bug_report("%s_crash_found" % self.test_name,
+                                      time.strftime("%m-%d-%Y-%H-%M-%S"))
+            self.dut.droid.goToSleepNow()
+            time.sleep(self.crash_check_interval)
+        return failure
+
+    def change_environment(self):
+        environment_mapping = {
+            0: self._wfc_set_wifi_strong_cell_strong,
+            1: self._wfc_set_wifi_strong_cell_weak,
+            2: self._wfc_set_wifi_strong_cell_absent,
+            3: self._wfc_set_wifi_weak_cell_strong,
+            4: self._wfc_set_wifi_weak_cell_weak,
+            5: self._wfc_set_wifi_weak_cell_absent,
+            6: self._wfc_set_wifi_absent_cell_strong,
+            7: self._wfc_set_wifi_absent_cell_weak
+        }
+        while time.time() < self.finishing_time:
+            selection = random.randrange(0, 8)
+            environment_mapping[selection]()
+            time.sleep(random.randrange(0, self.max_sleep_time))
+
+    def call_test(self):
+        failure = 0
+        while time.time() < self.finishing_time:
+            ads = [self.dut, self.helper]
+            random.shuffle(ads)
+            if not self._make_phone_call(ads):
+                failure += 1
+                self.log.error("Call test failure count: %s", failure)
+                self._take_bug_report("%s_call_failure" % self.test_name,
+                                      time.strftime("%m-%d-%Y-%H-%M-%S"))
+            self.dut.droid.goToSleepNow()
+            time.sleep(random.randrange(0, self.max_sleep_time))
+        return failure
+
+    def message_test(self):
+        failure = 0
+        while time.time() < self.finishing_time:
+            ads = [self.dut, self.helper]
+            random.shuffle(ads)
+            if not self._send_message(ads):
+                failure += 1
+                self.log.error("Messaging test failure count: %s", failure)
+                self._take_bug_report("%s_messaging_failure" % self.test_name,
+                                      time.strftime("%m-%d-%Y-%H-%M-%S"))
+            self.dut.droid.goToSleepNow()
+            time.sleep(random.randrange(0, self.max_sleep_time))
+        return failure
+
+    def data_test(self):
+        failure = 0
+        while time.time() < self.finishing_time:
+            if not self._download_file():
+                failure += 1
+                self.log.error("File download test failure count: %s", failure)
+                self._take_bug_report("%s_download_failure" % self.test_name,
+                                      time.strftime("%m-%d-%Y-%H-%M-%S"))
+            self.dut.droid.goToSleepNow()
+            time.sleep(random.randrange(0, self.max_sleep_time))
+        return failure
+
+    def parallel_tests(self, setup_func=None):
+        if setup_func and not setup_func():
+            self.log.error("Test setup %s failed", setup_func.__name__)
+            return False
+        self.finishing_time = time.time() + self.max_run_time
+        results = run_multithread_func(self.log, [(self.call_test, []), (
+            self.message_test, []), (self.data_test, []), (
+                self.change_environment, []), (self.crash_check_test, [])])
+        self.log.info("Call failures: %s", results[0])
+        self.log.info("Messaging failures: %s", results[1])
+        self.log.info("Data failures: %s", results[2])
+        self.log.info("Crash failures: %s", results[4])
+        for result in results:
+            if result: return False
+
+    """ Tests Begin """
+
+    @test_tracker_info(uuid="6fcba97c-3572-47d7-bcac-9608f1aa5304")
+    @TelephonyBaseTest.tel_test_wrap
+    def test_volte_wfc_wifi_preferred_parallel_stress(self):
+        return self.parallel_tests(
+            setup_func=self._setup_volte_wfc_wifi_preferred)
+
+    @test_tracker_info(uuid="df78a9a8-2a14-40bf-a7aa-719502f975be")
+    @TelephonyBaseTest.tel_test_wrap
+    def test_volte_wfc_cell_preferred_parallel_stress(self):
+        return self.parallel_tests(
+            setup_func=self._setup_volte_wfc_cell_preferred)
+
+    @test_tracker_info(uuid="4cb47315-c420-44c2-ac47-a8bdca6d0e25")
+    @TelephonyBaseTest.tel_test_wrap
+    def test_csfb_wfc_wifi_preferred_parallel_stress(self):
+        return self.parallel_tests(
+            setup_func=self._setup_csfb_wfc_wifi_preferred)
+
+    @test_tracker_info(uuid="92821ef7-542a-4139-b3b0-22278e2b06c4")
+    @TelephonyBaseTest.tel_test_wrap
+    def test_csfb_wfc_cell_preferred_parallel_stress(self):
+        return self.parallel_tests(
+            setup_func=self._setup_csfb_wfc_cell_preferred)
+
+    """ Tests End """