• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3.4
2#
3#   Copyright 2017 - Google
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16"""
17    Test Script for Telephony Stress Call Test
18"""
19
20import collections
21import json
22import os
23import random
24import time
25
26from acts import context
27from acts import signals
28from acts.libs.proc import job
29from acts.test_decorators import test_tracker_info
30from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
31from acts_contrib.test_utils.tel.loggers.telephony_stress_metric_logger import TelephonyStressMetricLogger
32from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
33from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE
34from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC
35from acts_contrib.test_utils.tel.tel_defines import GEN_3G
36from acts_contrib.test_utils.tel.tel_defines import GEN_4G
37from acts_contrib.test_utils.tel.tel_defines import GOOGLE_CBRS_CARRIER_ID
38from acts_contrib.test_utils.tel.tel_defines import GOOGLE_FI_CARRIER_ID
39from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND
40from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
41from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_WCDMA_ONLY
42from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GLOBAL
43from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_CDMA
44from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GSM_ONLY
45from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_TDSCDMA_GSM_WCDMA
46from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_AFTER_MODE_CHANGE
47from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
48from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
49from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_MESSAGE_SUB_ID
50from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_VOICE_SUB_ID
51from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_CBRS_DATA_SWITCH
52from acts_contrib.test_utils.tel.tel_defines import CARRIER_SING
53from acts_contrib.test_utils.tel.tel_lookup_tables import is_rat_svd_capable
54from acts_contrib.test_utils.tel.tel_test_utils import STORY_LINE
55from acts_contrib.test_utils.tel.tel_test_utils import active_file_download_test
56from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call
57from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
58from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_generation_for_subscription
59from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
60from acts_contrib.test_utils.tel.tel_test_utils import extract_test_log
61from acts_contrib.test_utils.tel.tel_test_utils import force_connectivity_metrics_upload
62from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
63from acts_contrib.test_utils.tel.tel_test_utils import get_telephony_signal_strength
64from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
65from acts_contrib.test_utils.tel.tel_test_utils import hangup_call_by_adb
66from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
67from acts_contrib.test_utils.tel.tel_test_utils import last_call_drop_reason
68from acts_contrib.test_utils.tel.tel_test_utils import run_multithread_func
69from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
70from acts_contrib.test_utils.tel.tel_test_utils import sms_send_receive_verify
71from acts_contrib.test_utils.tel.tel_test_utils import start_qxdm_loggers
72from acts_contrib.test_utils.tel.tel_test_utils import start_sdm_loggers
73from acts_contrib.test_utils.tel.tel_test_utils import start_adb_tcpdump
74from acts_contrib.test_utils.tel.tel_test_utils import synchronize_device_time
75from acts_contrib.test_utils.tel.tel_test_utils import mms_send_receive_verify
76from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_network_mode_pref
77from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
78from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection_by_ping
79from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
80from acts_contrib.test_utils.tel.tel_test_utils import wait_for_call_id_clearing
81from acts_contrib.test_utils.tel.tel_test_utils import wait_for_data_connection
82from acts_contrib.test_utils.tel.tel_test_utils import wait_for_in_call_active
83from acts_contrib.test_utils.tel.tel_test_utils import is_current_data_on_cbrs
84from acts_contrib.test_utils.tel.tel_test_utils import check_voice_network_type
85from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
86from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
87from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
88from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
89from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
90from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
91from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
92from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
93from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
94from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
95from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_iwlan
96from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_volte
97from acts_contrib.test_utils.tel.tel_voice_utils import get_current_voice_rat
98from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
99from acts_contrib.test_utils.tel.tel_subscription_utils import get_operatorname_from_slot_index
100from acts_contrib.test_utils.tel.tel_subscription_utils import get_carrierid_from_slot_index
101from acts_contrib.test_utils.tel.tel_subscription_utils import get_isopportunistic_from_slot_index
102from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_data
103from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_message
104from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_outgoing_call
105from acts_contrib.test_utils.tel.tel_subscription_utils import set_always_allow_mms_data
106from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
107from acts.utils import get_current_epoch_time
108from acts.utils import rand_ascii_str
109
110EXCEPTION_TOLERANCE = 5
111BINDER_LOGS = ["/sys/kernel/debug/binder"]
112DEFAULT_FILE_DOWNLOADS = ["1MB", "5MB", "10MB", "20MB", "50MB"]
113RESULTS_LIST = {-2: "UNAVAILABLE_NETWORK_TYPE",
114                -1: "CALL_SETUP_FAILURE",
115                 0: "SUCCESS",
116                 1: "INITIATE_FAILED",
117                 2: "NO_RING_EVENT_OR_ANSWER_FAILED",
118                 3: "NO_CALL_ID_FOUND",
119                 4: "CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT",
120                 5: "AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT",
121                 6: "AUDIO_STATE_NOT_INCALL_AFTER_CONNECTED",
122                 7: "CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT",
123                 8: "CALL_DROP_OR_WRONG_STATE_AFTER_CONNECTED",
124                 9: "CALL_HANGUP_FAIL",
125                 10: "CALL_ID_CLEANUP_FAIL"}
126
127
128class TelLiveStressTest(TelephonyBaseTest):
129    def setup_class(self):
130        super(TelLiveStressTest, self).setup_class()
131        self.dut = self.android_devices[0]
132        self.single_phone_test = self.user_params.get("single_phone_test",
133                                                      False)
134        # supported file download methods: chrome, sl4a, curl
135        self.file_download_method = self.user_params.get(
136            "file_download_method", "curl")
137        self.get_binder_logs = self.user_params.get("get_binder_logs", False)
138        if len(self.android_devices) == 1:
139            self.single_phone_test = True
140        if self.single_phone_test:
141            self.android_devices = self.android_devices[:1]
142            self.call_server_number = self.user_params.get(
143                "call_server_number", STORY_LINE)
144            if self.file_download_method == "sl4a":
145                # with single device, do not use sl4a file download
146                # due to stability issue
147                self.file_download_method = "curl"
148        else:
149            self.android_devices = self.android_devices[:2]
150        self.sdm_log = self.user_params.get("sdm_log", False)
151        for ad in self.android_devices:
152            setattr(ad, "sdm_log", self.sdm_log)
153            ad.adb.shell("setprop nfc.debug_enable 1")
154            if self.user_params.get("turn_on_tcpdump", False):
155                start_adb_tcpdump(ad, interface="any", mask="all")
156        self.user_params["telephony_auto_rerun"] = 0
157        self.phone_call_iteration = int(
158            self.user_params.get("phone_call_iteration", 500))
159        self.max_phone_call_duration = int(
160            self.user_params.get("max_phone_call_duration", 600))
161        self.min_sleep_time = int(self.user_params.get("min_sleep_time", 30))
162        self.max_sleep_time = int(self.user_params.get("max_sleep_time", 60))
163        self.max_run_time = int(self.user_params.get("max_run_time", 14400))
164        self.max_sms_length = int(self.user_params.get("max_sms_length", 1000))
165        self.max_mms_length = int(self.user_params.get("max_mms_length", 160))
166        self.min_sms_length = int(self.user_params.get("min_sms_length", 1))
167        self.min_mms_length = int(self.user_params.get("min_mms_length", 1))
168        self.min_phone_call_duration = int(
169            self.user_params.get("min_phone_call_duration", 10))
170        self.crash_check_interval = int(
171            self.user_params.get("crash_check_interval", 300))
172        self.cbrs_check_interval = int(
173            self.user_params.get("cbrs_check_interval", 100))
174        self.dut_incall = False
175        self.dsds_esim = self.user_params.get("dsds_esim", False)
176        self.cbrs_esim = self.user_params.get("cbrs_esim", False)
177        telephony_info = getattr(self.dut, "telephony", {})
178        self.dut_capabilities = telephony_info.get("capabilities", [])
179        self.dut_wfc_modes = telephony_info.get("wfc_modes", [])
180        self.gps_log_file = self.user_params.get("gps_log_file", None)
181        self.file_name_list = self.user_params.get("file_downloads", DEFAULT_FILE_DOWNLOADS)
182        self.tel_logger = TelephonyMetricLogger.for_test_case()
183        self.tel_logger = TelephonyStressMetricLogger.for_test_case()
184        self.result_collection = {"UNAVAILABLE_NETWORK_TYPE" : 0,
185                                  "CALL_SETUP_FAILURE" : 0,
186                                  "SUCCESS" : 0,
187                                  "INITIATE_FAILED" : 0,
188                                  "NO_RING_EVENT_OR_ANSWER_FAILED" : 0,
189                                  "NO_CALL_ID_FOUND" : 0,
190                                  "CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT" : 0,
191                                  "AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT" : 0,
192                                  "AUDIO_STATE_NOT_INCALL_AFTER_CONNECTED" : 0,
193                                  "CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT" : 0,
194                                  "CALL_DROP_OR_WRONG_STATE_AFTER_CONNECTED": 0,
195                                  "CALL_HANGUP_FAIL": 0,
196                                  "CALL_ID_CLEANUP_FAIL": 0 }
197        self.call_stats_check = self.user_params.get("call_stats_check", False)
198        self.nsa_5g_for_stress = self.user_params.get("nsa_5g_for_stress", False)
199        return True
200
201    def setup_test(self):
202        super(TelLiveStressTest, self).setup_test()
203        self.result_info = collections.defaultdict(int)
204        self._init_perf_json()
205        self.internet_connection_check_method = verify_internet_connection
206
207    def on_fail(self, test_name, begin_time):
208        pass
209
210    def _take_bug_report(self, test_name, begin_time):
211        if self._skip_bug_report(test_name):
212            return
213        src_dir = context.get_current_context().get_full_output_path()
214        dst_dir = os.path.join(self.log_path, test_name)
215
216        # Extract test_run_info.txt, test_run_debug.txt
217        for file_name in ("test_run_info.txt", "test_run_debug.txt"):
218            extract_test_log(self.log, os.path.join(src_dir, file_name),
219                             os.path.join(dst_dir,
220                                          "%s_%s" % (test_name, file_name)),
221                             "\[Test Case\] %s " % test_name)
222        super()._take_bug_report(test_name, begin_time)
223
224    def _ad_take_extra_logs(self, ad, test_name, begin_time):
225        src_file = os.path.join(ad.device_log_path,
226                                'adblog_%s_debug.txt' % ad.serial)
227        dst_file = os.path.join(ad.device_log_path, test_name,
228                                "%s_%s.logcat" % (ad.serial, test_name))
229        extract_test_log(self.log, src_file, dst_file, test_name)
230        return super()._ad_take_extra_logs(ad, test_name, begin_time)
231
232    def _setup_wfc(self):
233        for ad in self.android_devices:
234            if not ensure_wifi_connected(
235                    self.log,
236                    ad,
237                    self.wifi_network_ssid,
238                    self.wifi_network_pass,
239                    retries=3):
240                ad.log.error("Bringing up Wifi connection fails.")
241                return False
242            ad.log.info("Phone WIFI is connected successfully.")
243            if not set_wfc_mode(self.log, ad, WFC_MODE_WIFI_PREFERRED):
244                ad.log.error("Phone failed to enable Wifi-Calling.")
245                return False
246            ad.log.info("Phone is set in Wifi-Calling successfully.")
247            if not phone_idle_iwlan(self.log, ad):
248                ad.log.error("Phone is not in WFC enabled state.")
249                return False
250            ad.log.info("Phone is in WFC enabled state.")
251        return True
252
253    def _setup_wfc_apm(self):
254        for ad in self.android_devices:
255            if not phone_setup_iwlan(
256                    self.log, ad, True, WFC_MODE_CELLULAR_PREFERRED,
257                    self.wifi_network_ssid, self.wifi_network_pass):
258                ad.log.error("Failed to setup WFC.")
259                return False
260        return True
261
262    def _setup_lte_volte_enabled(self):
263        for ad in self.android_devices:
264            if not phone_setup_volte(self.log, ad):
265                ad.log.error("Phone failed to enable VoLTE.")
266                return False
267            ad.log.info("Phone VOLTE is enabled successfully.")
268            # TODO: b/186865335 Move 5G methods to NR directory
269            if self.nsa_5g_for_stress:
270                if not provision_device_for_5g(self.log, ad):
271                    ad.log.error("Phone failed to attach 5G NSA.")
272                    return False
273                ad.log.info("Phone 5G NSA VOLTE is enabled successfully.")
274        return True
275
276    def _setup_lte_volte_disabled(self):
277        for ad in self.android_devices:
278            if not phone_setup_csfb(self.log, ad):
279                ad.log.error("Phone failed to setup CSFB.")
280                return False
281            ad.log.info("Phone VOLTE is disabled successfully.")
282        return True
283
284    def _setup_3g(self):
285        for ad in self.android_devices:
286            if not phone_setup_voice_3g(self.log, ad):
287                ad.log.error("Phone failed to setup 3g.")
288                return False
289            ad.log.info("Phone RAT 3G is enabled successfully.")
290        return True
291
292    def _setup_2g(self):
293        for ad in self.android_devices:
294            if not phone_setup_voice_2g(self.log, ad):
295                ad.log.error("Phone failed to setup 2g.")
296                return False
297            ad.log.info("RAT 2G is enabled successfully.")
298        return True
299
300    def _get_network_rat(self, slot_id):
301        rat = self.dut.adb.getprop("gsm.network.type")
302        if "," in rat:
303            if self.dsds_esim:
304                rat = rat.split(',')[slot_id]
305            else:
306                (rat1, rat2) = rat.split(',')
307                if rat1 == "Unknown":
308                    rat = rat2
309                else:
310                    rat = rat1
311        return rat
312
313    def _send_message(self, max_wait_time=2 * MAX_WAIT_TIME_SMS_RECEIVE):
314        slot_id_rx = None
315        if self.single_phone_test:
316            ads = [self.dut, self.dut]
317        else:
318            ads = self.android_devices[:]
319            random.shuffle(ads)
320        slot_id = random.randint(0,1)
321        if self.dsds_esim:
322            sub_id = get_subid_from_slot_index(self.log, ads[0], slot_id)
323            ads[0].log.info("Message - MO - slot_Id %d", slot_id)
324            set_subid_for_message(ads[0], sub_id)
325            time.sleep(WAIT_TIME_CHANGE_MESSAGE_SUB_ID)
326            slot_id_rx = random.randint(0,1)
327            ads[1].log.info("Message - MT - slot_id %d", slot_id_rx)
328        selection = random.randrange(0, 2)
329        message_type_map = {0: "SMS", 1: "MMS"}
330        max_length_map = {0: self.max_sms_length, 1: self.max_mms_length}
331        min_length_map = {0: self.min_sms_length, 1: self.min_mms_length}
332        length = random.randrange(min_length_map[selection],
333                                  max_length_map[selection] + 1)
334        message_func_map = {
335            0: sms_send_receive_verify,
336            1: mms_send_receive_verify
337        }
338        rat = self._get_network_rat(slot_id)
339        self.dut.log.info("Network in RAT %s", rat)
340        if self.dut_incall and not is_rat_svd_capable(rat.upper()):
341            self.dut.log.info("In call data not supported, test SMS only")
342            selection = 0
343        message_type = message_type_map[selection]
344        the_number = self.result_info["%s Total" % message_type] + 1
345        begin_time = get_device_epoch_time(self.dut)
346        test_name = "%s_No_%s_%s" % (self.test_name, the_number, message_type)
347        if self.sdm_log:
348            start_sdm_loggers(self.log, self.android_devices)
349        else:
350            start_qxdm_loggers(self.log, self.android_devices)
351        log_msg = "[Test Case] %s" % test_name
352        self.log.info("%s begin", log_msg)
353        for ad in self.android_devices:
354            if self.user_params.get("turn_on_tcpdump", False):
355                start_adb_tcpdump(ad, interface="any", mask="all")
356            if not getattr(ad, "messaging_droid", None):
357                ad.messaging_droid, ad.messaging_ed = ad.get_droid()
358                ad.messaging_ed.start()
359            else:
360                try:
361                    if not ad.messaging_droid.is_live:
362                        ad.messaging_droid, ad.messaging_ed = ad.get_droid()
363                        ad.messaging_ed.start()
364                    else:
365                        ad.messaging_ed.clear_all_events()
366                except Exception:
367                    ad.log.info("Create new sl4a session for messaging")
368                    ad.messaging_droid, ad.messaging_ed = ad.get_droid()
369                    ad.messaging_ed.start()
370            ad.messaging_droid.logI("[BEGIN]%s" % log_msg)
371
372        text = "%s:" % test_name
373        text_length = len(text)
374        if length < text_length:
375            text = text[:length]
376        else:
377            text += rand_ascii_str(length - text_length)
378        message_content_map = {0: [text], 1: [(test_name, text, None)]}
379
380        result = message_func_map[selection](self.log, ads[0], ads[1],
381                                             message_content_map[selection],
382                                             max_wait_time,
383                                             slot_id_rx=slot_id_rx)
384        self.log.info("%s end", log_msg)
385        for ad in self.android_devices:
386            ad.messaging_droid.logI("[END]%s" % log_msg)
387        if not result:
388            self.result_info["%s Total" % message_type] += 1
389            if message_type == "SMS":
390                self.log.error("%s fails", log_msg)
391                self.result_info["%s Failure" % message_type] += 1
392            else:
393                rat = self._get_network_rat(slot_id)
394                self.dut.log.info("Network in RAT %s", rat)
395                if self.dut_incall and not is_rat_svd_capable(rat.upper()):
396                    self.dut.log.info(
397                        "In call data not supported, MMS failure expected")
398                    self.result_info["Expected In-call MMS failure"] += 1
399                    return True
400                else:
401                    self.log.error("%s fails", log_msg)
402                    self.result_info["MMS Failure"] += 1
403            try:
404                self._take_bug_report(test_name, begin_time)
405            except Exception as e:
406                self.log.exception(e)
407            return False
408        else:
409            self.result_info["%s Total" % message_type] += 1
410            self.log.info("%s succeed", log_msg)
411            self.result_info["%s Success" % message_type] += 1
412            return True
413
414    def _make_phone_call(self, call_verification_func=None, voice_stress_only = False):
415        ads = self.android_devices[:]
416        slot_id_callee = None
417        if not voice_stress_only:
418            if not self.single_phone_test:
419                random.shuffle(ads)
420        if self.dsds_esim:
421            slot_id = random.randint(0,1)
422            sub_id = get_subid_from_slot_index(self.log, ads[0], slot_id)
423            ads[0].log.info("Voice - MO - slot_Id %d", slot_id)
424            set_subid_for_outgoing_call(ads[0], sub_id)
425            time.sleep(WAIT_TIME_CHANGE_VOICE_SUB_ID)
426            slot_id_callee = random.randint(0,1)
427            ads[1].log.info("Voice - MT - slot_id %d", slot_id_callee)
428        the_number = self.result_info["Call Total"] + 1
429        if voice_stress_only:
430            duration = 30
431        else:
432            duration = random.randrange(self.min_phone_call_duration,
433                                    self.max_phone_call_duration)
434        result = True
435        test_name = "%s_No_%s_phone_call" % (self.test_name, the_number)
436        log_msg = "[Test Case] %s" % test_name
437        self.log.info("%s for %s seconds begin", log_msg, duration)
438
439        if self.call_stats_check:
440            voice_type_init = check_voice_network_type(ads, voice_init=True)
441        else:
442            voice_type_init = None
443
444        begin_time = get_device_epoch_time(ads[0])
445        for ad in self.android_devices:
446            if self.user_params.get("turn_on_tcpdump", False):
447                start_adb_tcpdump(ad, interface="any", mask="all")
448            if not getattr(ad, "droid", None):
449                ad.droid, ad.ed = ad.get_droid()
450                ad.ed.start()
451            else:
452                try:
453                    if not ad.droid.is_live:
454                        ad.droid, ad.ed = ad.get_droid()
455                        ad.ed.start()
456                    else:
457                        ad.ed.clear_all_events()
458                except Exception:
459                    ad.log.info("Create new sl4a session for phone call")
460                    ad.droid, ad.ed = ad.get_droid()
461                    ad.ed.start()
462            ad.droid.logI("[BEGIN]%s" % log_msg)
463        if self.sdm_log:
464            for ad in ads:
465                ad.adb.shell("i2cset -fy 3 64 6 1 b", ignore_status=True)
466                ad.adb.shell("i2cset -fy 3 65 6 1 b", ignore_status=True)
467            start_sdm_loggers(self.log, self.android_devices)
468        else:
469            start_qxdm_loggers(self.log, self.android_devices)
470        if self.cbrs_esim:
471            self._cbrs_data_check_test(begin_time, expected_cbrs=True,
472                                       test_time="before")
473        failure_reasons = set()
474        self.dut_incall = True
475        if self.single_phone_test:
476            call_setup_result = initiate_call(
477                self.log,
478                self.dut,
479                self.call_server_number,
480                incall_ui_display=INCALL_UI_DISPLAY_BACKGROUND,
481                call_stats_check=self.call_stats_check,
482                voice_type_init=voice_type_init,
483                result_info = self.result_info,
484                nsa_5g_for_stress=self.nsa_5g_for_stress
485            ) and wait_for_in_call_active(self.dut, 60, 3)
486        else:
487            call_setup_result = call_setup_teardown(
488                self.log,
489                ads[0],
490                ads[1],
491                ad_hangup=None,
492                verify_caller_func=call_verification_func,
493                verify_callee_func=call_verification_func,
494                wait_time_in_call=0,
495                incall_ui_display=INCALL_UI_DISPLAY_BACKGROUND,
496                slot_id_callee=slot_id_callee,
497                call_stats_check=self.call_stats_check,
498                voice_type_init=voice_type_init,
499                result_info = self.result_info,
500                nsa_5g_for_stress=self.nsa_5g_for_stress)
501            self.result_collection[RESULTS_LIST[call_setup_result.result_value]] += 1
502
503        if not call_setup_result:
504            get_telephony_signal_strength(ads[0])
505            if not self.single_phone_test:
506                get_telephony_signal_strength(ads[1])
507            call_logs = ads[0].search_logcat(
508                "ActivityManager: START u0 {act=android.intent.action.CALL",
509                begin_time)
510            messaging_logs = ads[0].search_logcat(
511                "com.google.android.apps.messaging/.ui.conversation.ConversationActivity",
512                begin_time)
513            if call_logs and messaging_logs:
514                if (messaging_logs[-1]["datetime_obj"] -
515                        call_logs[-1]["datetime_obj"]).seconds < 5:
516                    ads[0].log.info(
517                        "Call setup failure due to simultaneous activities")
518                    self.result_info[
519                        "Call Setup Failure With Simultaneous Activity"] += 1
520                    return True
521            self.log.error("%s: Setup Call failed.", log_msg)
522            failure_reasons.add("Setup")
523            result = False
524        else:
525            elapsed_time = 0
526            check_interval = 5
527            if self.sdm_log:
528                for ad in ads:
529                    ad.adb.shell("i2cset -fy 3 64 6 1 b", ignore_status=True)
530                    ad.adb.shell("i2cset -fy 3 65 6 1 b", ignore_status=True)
531            if self.cbrs_esim:
532                time.sleep(5)
533                self._cbrs_data_check_test(begin_time, expected_cbrs=False,
534                                           test_time="during")
535            while (elapsed_time < duration):
536                check_interval = min(check_interval, duration - elapsed_time)
537                time.sleep(check_interval)
538                elapsed_time += check_interval
539                time_message = "at <%s>/<%s> second." % (elapsed_time,
540                                                         duration)
541                for ad in ads:
542                    get_telephony_signal_strength(ad)
543                    if not call_verification_func(self.log, ad):
544                        ad.log.warning("Call is NOT in correct %s state at %s",
545                                       call_verification_func.__name__,
546                                       time_message)
547                        if call_verification_func.__name__ == "is_phone_in_call_iwlan":
548                            if is_phone_in_call(self.log, ad):
549                                if getattr(ad, "data_rat_state_error_count",
550                                           0) < 1:
551                                    setattr(ad, "data_rat_state_error_count",
552                                            1)
553                                    continue
554                        failure_reasons.add("Maintenance")
555                        last_call_drop_reason(ad, begin_time)
556                        hangup_call(self.log, ads[0])
557                        result = False
558                    else:
559                        ad.log.info("Call is in correct %s state at %s",
560                                    call_verification_func.__name__,
561                                    time_message)
562                if not result:
563                    break
564        if not hangup_call(self.log, ads[0]):
565            failure_reasons.add("Teardown")
566            result = False
567        for ad in ads:
568            if not wait_for_call_id_clearing(ad,
569                                             []) or ad.droid.telecomIsInCall():
570                ad.log.error("Fail to hang up call")
571                failure_reasons.add("Teardown")
572                result = False
573        self.result_info["Call Total"] += 1
574        for ad in self.android_devices:
575            try:
576                ad.droid.logI("[END]%s" % log_msg)
577            except:
578                pass
579        self.log.info("%s end", log_msg)
580        self.dut_incall = False
581        if self.cbrs_esim:
582            time.sleep(30)
583            self._cbrs_data_check_test(begin_time, expected_cbrs=True,
584                                       test_time="after")
585        if not result:
586            self.log.info("%s failed", log_msg)
587            if self.gps_log_file:
588                gps_info = job.run(
589                    "tail %s" % self.gps_log_file, ignore_status=True)
590                if gps_info.stdout:
591                    gps_log_path = os.path.join(self.log_path, test_name)
592                    os.makedirs(gps_log_path, exist_ok=True)
593                    job.run(
594                        "tail %s > %s" %
595                        (self.gps_log_file,
596                         os.path.join(gps_log_path, "gps_logs.txt")),
597                        ignore_status=True)
598                    self.log.info("gps log:\n%s", gps_info.stdout)
599                else:
600                    self.log.warning("Fail to get gps log %s",
601                                     self.user_params["gps_log_file"])
602            for reason in failure_reasons:
603                self.result_info["Call %s Failure" % reason] += 1
604            for ad in ads:
605                log_path = os.path.join(self.log_path, test_name,
606                                        "%s_binder_logs" % ad.serial)
607                os.makedirs(log_path, exist_ok=True)
608                ad.pull_files(BINDER_LOGS, log_path)
609            try:
610                self._take_bug_report(test_name, begin_time)
611            except Exception as e:
612                self.log.exception(e)
613            for ad in ads:
614                if ad.droid.telecomIsInCall():
615                    hangup_call_by_adb(ad)
616        else:
617            self.log.info("%s test succeed", log_msg)
618            self.result_info["Call Success"] += 1
619            if self.result_info["Call Total"] % 50 == 0:
620                for ad in ads:
621                    synchronize_device_time(ad)
622                    force_connectivity_metrics_upload(ad)
623                    if self.get_binder_logs:
624                        log_path = os.path.join(self.log_path, test_name,
625                                                "%s_binder_logs" % ad.serial)
626                        os.makedirs(log_path, exist_ok=True)
627                        ad.pull_files(BINDER_LOGS, log_path)
628        return result
629
630    def _prefnetwork_mode_change(self, sub_id):
631        # ModePref change to non-LTE
632        begin_time = get_device_epoch_time(self.dut)
633        if self.sdm_log:
634            start_sdm_loggers(self.log, self.android_devices)
635        else:
636            start_qxdm_loggers(self.log, self.android_devices)
637        self.result_info["Network Change Request Total"] += 1
638        test_name = "%s_network_change_iter_%s" % (
639            self.test_name, self.result_info["Network Change Request Total"])
640        log_msg = "[Test Case] %s" % test_name
641        self.log.info("%s begin", log_msg)
642        self.dut.droid.logI("[BEGIN]%s" % log_msg)
643        network_preference_list = [
644            NETWORK_MODE_TDSCDMA_GSM_WCDMA, NETWORK_MODE_WCDMA_ONLY,
645            NETWORK_MODE_GLOBAL, NETWORK_MODE_CDMA, NETWORK_MODE_GSM_ONLY
646        ]
647        network_preference = random.choice(network_preference_list)
648        set_preferred_network_mode_pref(self.log, self.dut, sub_id,
649                                        network_preference)
650        time.sleep(WAIT_TIME_AFTER_MODE_CHANGE)
651        self.dut.log.info("Current Voice RAT is %s",
652                          get_current_voice_rat(self.log, self.dut))
653
654        # ModePref change back to with LTE
655        if not phone_setup_volte(self.log, self.dut):
656            self.dut.log.error("Phone failed to enable VoLTE.")
657            self.result_info["VoLTE Setup Failure"] += 1
658            self.dut.droid.logI("%s end" % log_msg)
659            self.dut.log.info("[END]%s", log_msg)
660            try:
661                self._ad_take_extra_logs(self.dut, test_name, begin_time)
662                self._ad_take_bugreport(self.dut, test_name, begin_time)
663            except Exception as e:
664                self.log.exception(e)
665            return False
666        else:
667            self.result_info["VoLTE Setup Success"] += 1
668            return True
669
670    def _mobile_data_toggling(self, setup="volte"):
671        # ModePref change to non-LTE
672        begin_time = get_device_epoch_time(self.dut)
673        if self.sdm_log:
674            start_sdm_loggers(self.log, self.android_devices)
675        else:
676            start_qxdm_loggers(self.log, self.android_devices)
677        result = True
678        self.result_info["Data Toggling Request Total"] += 1
679        test_name = "%s_data_toggling_iter_%s" % (
680            self.test_name, self.result_info["Data Toggling Request Total"])
681        log_msg = "[Test Case] %s" % test_name
682        self.log.info("%s begin", log_msg)
683        self.dut.droid.logI("[BEGIN]%s" % log_msg)
684        self.dut.adb.shell("svc data disable")
685        time.sleep(WAIT_TIME_AFTER_MODE_CHANGE)
686        self.dut.adb.shell("svc data enable")
687        if not self._check_data():
688            result = False
689        elif setup == "volte" and not phone_idle_volte(self.log, self.dut):
690            result = False
691        self.dut.droid.logI("%s end" % log_msg)
692        self.dut.log.info("[END]%s", log_msg)
693        if not result:
694            self.result_info["Data Toggling Failure"] += 1
695            try:
696                self._ad_take_extra_logs(self.dut, test_name, begin_time)
697                self._ad_take_bugreport(self.dut, test_name, begin_time)
698            except Exception as e:
699                self.log.exception(e)
700            return False
701        else:
702            self.result_info["Data Toggling Success"] += 1
703            return True
704
705    def _get_result_message(self):
706        msg_list = [
707            "%s: %s" % (count, self.result_info[count])
708            for count in sorted(self.result_info.keys())
709        ]
710        return ", ".join(msg_list)
711
712    def _write_perf_json(self):
713        json_str = json.dumps(self.perf_data, indent=4, sort_keys=True)
714        with open(self.perf_file, 'w') as f:
715            f.write(json_str)
716
717    def _init_perf_json(self):
718        self.perf_file = os.path.join(self.log_path, "%s_perf_data_%s.json" %
719                                      (self.test_name, self.begin_time))
720        self.perf_data = self.dut.build_info.copy()
721        self.perf_data["build_fingerprint"] = self.dut.adb.getprop(
722            "ro.build.fingerprint")
723        self.perf_data["model"] = self.dut.model
724        self.perf_data["carrier"] = self.dut.adb.getprop(
725            "gsm.sim.operator.alpha")
726        self._write_perf_json()
727
728    def _update_perf_json(self):
729        for result_key, result_value in self.result_info.items():
730            self.perf_data[result_key] = result_value
731        self._write_perf_json()
732
733    def crash_check_test(self):
734        failure = 0
735        while time.time() < self.finishing_time:
736            try:
737                self.log.info(dict(self.result_info))
738                self._update_perf_json()
739                begin_time = get_device_epoch_time(self.dut)
740                run_time_in_seconds = (begin_time - self.begin_time) / 1000
741                test_name = "%s_crash_%s_seconds_after_start" % (
742                    self.test_name, run_time_in_seconds)
743                time.sleep(self.crash_check_interval)
744                for ad in self.android_devices:
745                    crash_report = ad.check_crash_report(
746                        test_name, begin_time, log_crash_report=True)
747                    if crash_report:
748                        ad.log.error("Find new crash reports %s", crash_report)
749                        failure += 1
750                        self.result_info["Crashes"] += len(crash_report)
751                        for crash in crash_report:
752                            if "ramdump_modem" in crash:
753                                self.result_info["Crashes-Modem"] += 1
754                        try:
755                            ad.take_bug_report(test_name, begin_time)
756                        except Exception as e:
757                            self.log.exception(e)
758            except Exception as e:
759                self.log.error("Exception error %s", str(e))
760                self.result_info["Exception Errors"] += 1
761            self.log.info("Crashes found: %s", failure)
762            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
763                self.log.error("Too many exception errors, quit test")
764                return False
765        if failure:
766            return False
767        else:
768            return True
769
770    def _cbrs_data_check_test(self, begin_time, expected_cbrs=True,
771                              test_time="before"):
772        cbrs_fail_count = 0
773        the_number = self.result_info["CBRS Total"] + 1
774        test_name = "%s_cbrs_%s_call_No_%s" % (self.test_name,
775                                               test_time, the_number)
776        for ad in self.android_devices:
777            current_state = is_current_data_on_cbrs(ad, ad.cbrs)
778            if current_state == expected_cbrs:
779                self.result_info["CBRS-Check-Pass"] += 1
780            else:
781                self.result_info["CBRS-Check-Fail"] += 1
782                cbrs_fail_count += 1
783                try:
784                    self._ad_take_extra_logs(ad, test_name, begin_time)
785                    self._ad_take_bugreport(ad, test_name, begin_time)
786                except Exception as e:
787                    self.log.warning(e)
788        if cbrs_fail_count > 0:
789            ad.log.error("Found %d checks failed, expected cbrs %s",
790                         cbrs_fail_count, expected_cbrs)
791            cbrs_fail_count += 1
792        self.result_info["CBRS Total"] += 1
793        return True
794
795    def call_test(self, call_verification_func=None):
796        while time.time() < self.finishing_time:
797            time.sleep(
798                random.randrange(self.min_sleep_time, self.max_sleep_time))
799            try:
800                self._make_phone_call(call_verification_func)
801            except Exception as e:
802                self.log.exception("Exception error %s", str(e))
803                self.result_info["Exception Errors"] += 1
804            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
805                self.log.error("Too many exception errors, quit test")
806                return False
807            self.log.info("%s", dict(self.result_info))
808        self.tel_logger.set_result(self.result_collection)
809        if any([
810                self.result_info["Call Setup Failure"],
811                self.result_info["Call Maintenance Failure"],
812                self.result_info["Call Teardown Failure"]
813        ]):
814            return False
815        else:
816            return True
817
818    def message_test(self, max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
819        while time.time() < self.finishing_time:
820            try:
821                self._send_message(max_wait_time=max_wait_time)
822            except Exception as e:
823                self.log.exception("Exception error %s", str(e))
824                self.result_info["Exception Errors"] += 1
825            self.log.info(dict(self.result_info))
826            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
827                self.log.error("Too many exception errors, quit test")
828                return False
829            time.sleep(
830                random.randrange(self.min_sleep_time, self.max_sleep_time))
831        if self.result_info["SMS Failure"] or (
832                self.result_info["MMS Failure"] / self.result_info["MMS Total"]
833                > 0.3):
834            return False
835        else:
836            return True
837
838    def _data_download(self, file_names=[]):
839        begin_time = get_current_epoch_time()
840        slot_id = random.randint(0,1)
841        if self.dsds_esim:
842            sub_id = get_subid_from_slot_index(self.log, self.dut, slot_id)
843            self.dut.log.info("Data - slot_Id %d", slot_id)
844            set_subid_for_data(self.dut, sub_id)
845            self.dut.droid.telephonyToggleDataConnection(True)
846        if self.sdm_log:
847            start_sdm_loggers(self.log, self.android_devices)
848        else:
849            start_qxdm_loggers(self.log, self.android_devices)
850        self.dut.log.info(dict(self.result_info))
851        selection = random.randrange(0, len(file_names))
852        file_name = file_names[selection]
853        self.result_info["Internet Connection Check Total"] += 1
854
855        rat = self._get_network_rat(slot_id)
856        if not self.internet_connection_check_method(self.log, self.dut):
857            self.dut.log.info("Network in RAT %s", rat)
858            if self.dut_incall and not is_rat_svd_capable(rat.upper()):
859                self.result_info[
860                    "Expected Incall Internet Connection Check Failure"] += 1
861                return True
862            else:
863                self.result_info["Internet Connection Check Failure"] += 1
864                test_name = "%s_internet_connection_No_%s_failure" % (
865                    self.test_name,
866                    self.result_info["Internet Connection Check Failure"])
867                try:
868                    self._ad_take_extra_logs(self.dut, test_name, begin_time)
869                    self._ad_take_bugreport(self.dut, test_name, begin_time)
870                except Exception as e:
871                    self.log.exception(e)
872                return False
873        else:
874            self.result_info["Internet Connection Check Success"] += 1
875
876        self.result_info["File Download Total"] += 1
877        self.result_info["Data Download Total"] += int(file_name[:-2])
878        if not active_file_download_test(
879                self.log, self.dut, file_name,
880                method=self.file_download_method):
881            self.result_info["File Download Failure"] += 1
882            self.result_info["Data Failure Total"] += int(file_name[:-2])
883            if self.result_info["File Download Failure"] == 1:
884                try:
885                    self._ad_take_extra_logs(
886                        self.dut, "%s_file_download_failure" % self.test_name,
887                        begin_time)
888                    self._ad_take_bugreport(
889                        self.dut, "%s_file_download_failure" % self.test_name,
890                        begin_time)
891                except Exception as e:
892                    self.log.exception(e)
893            return False
894        else:
895            self.result_info["File Download Success"] += 1
896            self.result_info["Data Success Total"] += int(file_name[:-2])
897            return True
898
899    def data_test(self):
900        while time.time() < self.finishing_time:
901            try:
902                self._data_download(self.file_name_list)
903            except Exception as e:
904                self.log.error("Exception error %s", str(e))
905                self.result_info["Exception Errors"] += 1
906            self.log.info("%s", dict(self.result_info))
907            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
908                self.log.error("Too many exception errors, quit test")
909                return False
910            time.sleep(
911                random.randrange(self.min_sleep_time, self.max_sleep_time))
912        if self.result_info["Internet Connection Check Failure"]:
913            return False
914        else:
915            return True
916
917    def _check_data(self):
918        self.result_info["Data Connection Check Total"] += 1
919        if not wait_for_data_connection(self.log, self.dut, True):
920            self.result_info["Data Connection Setup Failure"] += 1
921            return False
922        if not self.internet_connection_check_method(self.log, self.dut):
923            rat = self.dut.adb.getprop("gsm.network.type")
924            self.dut.log.info("Network in RAT %s", rat)
925            self.result_info["Internet Connection Check Failure"] += 1
926            return False
927        return True
928
929    def _data_call_test(self, sub_id, generation):
930        self.dut.log.info(dict(self.result_info))
931        begin_time = get_device_epoch_time(self.dut)
932        if self.sdm_log:
933            start_sdm_loggers(self.log, self.android_devices)
934        else:
935            start_qxdm_loggers(self.log, self.android_devices)
936        self.result_info["Network Change Request Total"] += 1
937        test_name = "%s_network_change_test_iter_%s" % (
938            self.test_name, self.result_info["Network Change Request Total"])
939        log_msg = "[Test Case] %s" % test_name
940        self.log.info("%s begin", log_msg)
941        self.dut.droid.logI("[BEGIN]%s" % log_msg)
942        if not ensure_network_generation_for_subscription(
943                self.log, self.dut, sub_id,
944                generation) or not self._check_data():
945            self.result_info["Network Change Failure"] += 1
946            self.dut.droid.logI("%s end" % log_msg)
947            self.dut.log.info("[END]%s", log_msg)
948            try:
949                self._ad_take_extra_logs(self.dut, test_name, begin_time)
950                self._ad_take_bugreport(self.dut, test_name, begin_time)
951            except Exception as e:
952                self.log.warning(e)
953            return False
954        if not self._mobile_data_toggling(setup=None):
955            return False
956        return True
957
958    def data_call_stress_test(self):
959        result = True
960        sub_id = self.dut.droid.subscriptionGetDefaultSubId()
961        while time.time() < self.finishing_time:
962            for generation in (GEN_4G, GEN_3G):
963                try:
964                    if not self._data_call_test(sub_id, generation):
965                        result = False
966                except Exception as e:
967                    self.log.error("Exception error %s", str(e))
968                    self.result_info["Exception Errors"] += 1
969            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
970                self.log.error("Too many exception errors, quit test")
971                return False
972        return result
973
974    def check_incall_data(self):
975        if verify_internet_connection_by_ping(self.log, self.dut):
976            self.internet_connection_check_method = verify_internet_connection_by_ping
977        elif verify_http_connection(self.log, self.dut):
978            self.internet_connection_check_method = verify_http_connection
979        else:
980            self.dut.log.error("Data test failed")
981            raise signals.TestFailure("Data check failed")
982        if self.single_phone_test:
983            if not initiate_call(
984                    self.log, self.dut,
985                    self.call_server_number) and wait_for_in_call_active(
986                        self.dut, 60, 3):
987                self._take_bug_report(self.test_name, self.begin_time)
988                raise signals.TestFailure("Unable to make phone call")
989        else:
990            if not call_setup_teardown(
991                    self.log, self.dut, self.android_devices[1],
992                    ad_hangup=None):
993                self._take_bug_report(self.test_name, self.begin_time)
994                raise signals.TestFailure("Unable to make phone call")
995        voice_rat = self.dut.droid.telephonyGetCurrentVoiceNetworkType()
996        data_rat = self.dut.droid.telephonyGetCurrentDataNetworkType()
997        self.dut.log.info("Voice in RAT %s, Data in RAT %s", voice_rat,
998                          data_rat)
999        try:
1000            if "wfc" in self.test_name or is_rat_svd_capable(
1001                    voice_rat.upper()) and is_rat_svd_capable(
1002                        data_rat.upper()):
1003                self.dut.log.info("Capable for simultaneous voice and data")
1004
1005                if not self.internet_connection_check_method(
1006                        self.log, self.dut):
1007                    self.dut.log.error("Incall data check failed")
1008                    raise signals.TestFailure("Incall data check failed")
1009                else:
1010                    return True
1011            else:
1012                self.dut.log.info(
1013                    "Not capable for simultaneous voice and data")
1014                return False
1015            hangup_call(self.log, self.dut)
1016        finally:
1017            for ad in self.android_devices:
1018                if ad.droid.telecomIsInCall():
1019                    hangup_call(self.log, ad)
1020
1021    def parallel_tests(self, setup_func=None, call_verification_func=None):
1022        self.log.info(self._get_result_message())
1023        if setup_func and not setup_func():
1024            msg = "%s setup %s failed" % (self.test_name, setup_func.__name__)
1025            self.log.error(msg)
1026            self._take_bug_report("%s%s" % (self.test_name,
1027                                            setup_func.__name__),
1028                                  self.begin_time)
1029            return False
1030        if not call_verification_func:
1031            call_verification_func = is_phone_in_call
1032        self.finishing_time = time.time() + self.max_run_time
1033        # CBRS setup
1034        if self.cbrs_esim:
1035            cbrs_sub_count = 0
1036            for ad in self.android_devices:
1037                if not getattr(ad, 'cbrs', {}):
1038                    setattr(ad, 'cbrs', None)
1039                for i in range(0, 2):
1040                    sub_id = get_subid_from_slot_index(ad.log, ad, i)
1041                    operator = get_operatorname_from_slot_index(ad, i)
1042                    carrier_id = get_carrierid_from_slot_index(ad, i)
1043                    is_opportunistic = get_isopportunistic_from_slot_index(ad, i)
1044                    ad.log.info("Slot %d - Sub %s - %s - %d", i, sub_id, operator, carrier_id)
1045                    if carrier_id == GOOGLE_CBRS_CARRIER_ID or (carrier_id == GOOGLE_FI_CARRIER_ID and is_opportunistic):
1046                        ad.cbrs = sub_id
1047                        cbrs_sub_count += 1
1048            if cbrs_sub_count != 2:
1049                self.log.error("Expecting - 2 CBRS subs, found - %d", cbrs_sub_count)
1050                raise signals.TestAbortClass("Cannot find all expected CBRS subs")
1051        # DSDS setup
1052        if self.dsds_esim:
1053            for ad in self.android_devices:
1054                for i in range(0, 2):
1055                    sub_id = get_subid_from_slot_index(ad.log, ad, i)
1056                    set_always_allow_mms_data(ad, sub_id)
1057                    operator = get_operatorname_from_slot_index(ad, i)
1058                    ad.log.info("Slot %d - Sub %s - %s", i, sub_id, operator)
1059        # Actual test trigger
1060        if not self.dsds_esim and self.check_incall_data():
1061            self.log.info(
1062                "==== Start parallel voice/message/data stress test ====")
1063            self.perf_data["testing method"] = "parallel"
1064            results = run_multithread_func(
1065                self.log, [(self.call_test, [call_verification_func]),
1066                           (self.message_test, []), (self.data_test, []),
1067                           (self.crash_check_test, [])])
1068        else:
1069            self.log.info(
1070                "==== Start sequential voice/message/data stress test ====")
1071            self.perf_data["testing method"] = "sequential"
1072            results = run_multithread_func(
1073                self.log, [(self.sequential_tests, [call_verification_func]),
1074                           (self.crash_check_test, [])])
1075        result_message = self._get_result_message()
1076        self.log.info(result_message)
1077        self._update_perf_json()
1078        self.result_detail = result_message
1079        return all(results)
1080
1081    def sequential_tests(self, call_verification_func):
1082        funcs = [(self._make_phone_call, [call_verification_func]),
1083                 (self._send_message, []), (self._data_download, [["5MB"]])]
1084        while time.time() < self.finishing_time:
1085            selection = random.randrange(0, 3)
1086            try:
1087                funcs[selection][0](*funcs[selection][1])
1088            except Exception as e:
1089                self.log.error("Exception error %s", str(e))
1090                self.result_info["Exception Errors"] += 1
1091            self.log.info("%s", dict(self.result_info))
1092            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
1093                self.log.error("Too many exception errors, quit test")
1094                return False
1095            time.sleep(
1096                random.randrange(self.min_sleep_time, self.max_sleep_time))
1097        if any([
1098                self.result_info["Call Setup Failure"],
1099                self.result_info["Call Maintenance Failure"],
1100                self.result_info["Call Teardown Failure"],
1101                self.result_info["SMS Failure"],
1102                self.result_info["MMS Failure"],
1103                self.result_info["Internet Connection Check Failure"]
1104        ]):
1105            return False
1106        return True
1107
1108    def volte_modechange_volte_test(self):
1109        sub_id = self.dut.droid.subscriptionGetDefaultSubId()
1110        result = True
1111        while time.time() < self.finishing_time:
1112            try:
1113                if self._prefnetwork_mode_change(sub_id):
1114                    run_multithread_func(
1115                        self.log,
1116                        [(self._data_download, [["5MB"]]),
1117                         (self._make_phone_call, [is_phone_in_call_volte]),
1118                         (self._send_message, [])])
1119                else:
1120                    result = False
1121                if self._mobile_data_toggling():
1122                    run_multithread_func(
1123                        self.log,
1124                        [(self._data_download, [["5MB"]]),
1125                         (self._make_phone_call, [is_phone_in_call_volte]),
1126                         (self._send_message, [])])
1127                else:
1128                    result = False
1129            except Exception as e:
1130                self.log.error("Exception error %s", str(e))
1131                self.result_info["Exception Errors"] += 1
1132            self.log.info(dict(self.result_info))
1133            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
1134                self.log.error("Too many exception errors, quit test")
1135                return False
1136        return result
1137
1138    def parallel_with_network_change_tests(self, setup_func=None):
1139        if setup_func and not setup_func():
1140            self.log.error("Test setup %s failed", setup_func.__name__)
1141            return False
1142        self.finishing_time = time.time() + self.max_run_time
1143        results = run_multithread_func(self.log,
1144                                       [(self.volte_modechange_volte_test, []),
1145                                        (self.crash_check_test, [])])
1146        result_message = self._get_result_message()
1147        self.log.info(result_message)
1148        self._update_perf_json()
1149        self.result_detail = result_message
1150        return all(results)
1151
1152    def connect_to_wifi(self):
1153        for ad in self.android_devices:
1154            if not ensure_wifi_connected(
1155                    self.log,
1156                    ad,
1157                    self.wifi_network_ssid,
1158                    self.wifi_network_pass,
1159                    retries=3):
1160                ad.log.error("Bringing up Wifi connection fails.")
1161                return False
1162        ad.log.info("Phone WIFI is connected successfully.")
1163        return True
1164
1165    def performance_tests(self, setup_func=None, call_verification_func=None):
1166        self.log.info(self._get_result_message())
1167        if setup_func and not setup_func():
1168            msg = "%s setup %s failed" % (self.test_name, setup_func.__name__)
1169            self.log.error(msg)
1170            self._take_bug_report("%s%s" % (self.test_name,
1171                                            setup_func.__name__),
1172                                  self.begin_time)
1173            return False
1174        if not call_verification_func:
1175            call_verification_func = is_phone_in_call
1176        self.finishing_time = time.time() + self.max_run_time
1177
1178        self.log.info(
1179            "==== Start voice stress test ====")
1180        self.perf_data["testing method"] = "parallel"
1181        results = self.call_performance_test(call_verification_func)
1182
1183        result_message = self._get_result_message()
1184        self.log.info(result_message)
1185        self._update_perf_json()
1186        self.result_detail = result_message
1187        total_call = self.result_info["Call Total"]
1188        success_call = self.result_info["Call Success Total"]
1189        call_fail = total_call - success_call
1190        if call_fail != 0:
1191            call_fail_rate = ( call_fail / total_call ) * 100
1192        else:
1193            call_fail_rate = 0
1194        call_success_rate = (success_call / total_call) * 100
1195
1196        self.log.info("Call Success Rate is %s", call_success_rate)
1197        self.log.info("Call Drop Rate is %s", call_success_rate)
1198
1199        return results
1200
1201    def _update_initiate_call_fail_count(self):
1202        self.result_info["Call Initiate Fail"] += 1
1203
1204    def call_performance_test(self, call_verification_func=None):
1205        count = 0
1206        while count < self.phone_call_iteration:
1207            time.sleep(15)
1208            count += 1
1209            try:
1210                self._make_phone_call(call_verification_func, True)
1211            except Exception as e:
1212                self.log.exception("Exception error %s", str(e))
1213                self.result_info["Exception Errors"] += 1
1214            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
1215                self.log.error("Too many exception errors, quit test")
1216                return False
1217            self.log.info("%s", dict(self.result_info))
1218            self.result_info["Call Success Total"] += 1
1219        if any([
1220                self.result_info["Call Setup Failure"],
1221                self.result_info["Call Maintenance Failure"],
1222                self.result_info["Call Teardown Failure"]
1223        ]):
1224            return False
1225        else:
1226            return True
1227
1228    """ Tests Begin """
1229
1230    @test_tracker_info(uuid="d035e5b9-476a-4e3d-b4e9-6fd86c51a68d")
1231    @TelephonyBaseTest.tel_test_wrap
1232    def test_default_parallel_stress(self):
1233        """ Default state stress test"""
1234        return self.parallel_tests()
1235
1236    @test_tracker_info(uuid="798a3c34-db75-4bcf-b8ef-e1116414a7fe")
1237    @TelephonyBaseTest.tel_test_wrap
1238    def test_default_parallel_stress_with_wifi(self):
1239        """ Default state stress test with Wifi enabled."""
1240        if self.connect_to_wifi():
1241            return self.parallel_tests()
1242
1243    @test_tracker_info(uuid="c21e1f17-3282-4f0b-b527-19f048798098")
1244    @TelephonyBaseTest.tel_test_wrap
1245    def test_lte_volte_parallel_stress(self):
1246        """ VoLTE on stress test"""
1247        return self.parallel_tests(
1248            setup_func=self._setup_lte_volte_enabled,
1249            call_verification_func=is_phone_in_call_volte)
1250
1251    @test_tracker_info(uuid="a317c23a-41e0-4ef8-af67-661451cfefcf")
1252    @TelephonyBaseTest.tel_test_wrap
1253    def test_csfb_parallel_stress(self):
1254        """ LTE non-VoLTE stress test"""
1255        return self.parallel_tests(
1256            setup_func=self._setup_lte_volte_disabled,
1257            call_verification_func=is_phone_in_call_csfb)
1258
1259    @test_tracker_info(uuid="fdb791bf-c414-4333-9fa3-cc18c9b3b234")
1260    @TelephonyBaseTest.tel_test_wrap
1261    def test_wfc_parallel_stress(self):
1262        """ Wifi calling APM mode off stress test"""
1263        if WFC_MODE_WIFI_PREFERRED not in self.dut_wfc_modes:
1264            raise signals.TestSkip("WFC_MODE_WIFI_PREFERRED is not supported")
1265        return self.parallel_tests(
1266            setup_func=self._setup_wfc,
1267            call_verification_func=is_phone_in_call_iwlan)
1268
1269    @test_tracker_info(uuid="e334c1b3-4378-49bb-bf57-1573fa1b23fa")
1270    @TelephonyBaseTest.tel_test_wrap
1271    def test_wfc_apm_parallel_stress(self):
1272        """ Wifi calling in APM mode on stress test"""
1273        return self.parallel_tests(
1274            setup_func=self._setup_wfc_apm,
1275            call_verification_func=is_phone_in_call_iwlan)
1276
1277    @test_tracker_info(uuid="4566eef6-55de-4ac8-87ee-58f2ef41a3e8")
1278    @TelephonyBaseTest.tel_test_wrap
1279    def test_3g_parallel_stress(self):
1280        """ 3G stress test"""
1281        return self.parallel_tests(
1282            setup_func=self._setup_3g,
1283            call_verification_func=is_phone_in_call_3g)
1284
1285    @test_tracker_info(uuid="f34f1a31-3948-4675-8698-372a83b8088d")
1286    @TelephonyBaseTest.tel_test_wrap
1287    def test_2g_parallel_stress(self):
1288        """ 2G call stress test"""
1289        return self.parallel_tests(
1290            setup_func=self._setup_2g,
1291            call_verification_func=is_phone_in_call_2g)
1292
1293    @test_tracker_info(uuid="af580fca-fea6-4ca5-b981-b8c710302d37")
1294    @TelephonyBaseTest.tel_test_wrap
1295    def test_volte_modeprefchange_parallel_stress(self):
1296        """ VoLTE Mode Pref call stress test"""
1297        return self.parallel_with_network_change_tests(
1298            setup_func=self._setup_lte_volte_enabled)
1299
1300    @test_tracker_info(uuid="10e34247-5fd3-4f87-81bf-3c17a6b71ab2")
1301    @TelephonyBaseTest.tel_test_wrap
1302    def test_data_call_stress(self):
1303        """ Default state stress test"""
1304        self.finishing_time = time.time() + self.max_run_time
1305        results = run_multithread_func(self.log,
1306                                       [(self.data_call_stress_test, []),
1307                                        (self.crash_check_test, [])])
1308        result_message = self._get_result_message()
1309        self.log.info(result_message)
1310        self._update_perf_json()
1311        self.result_detail = result_message
1312        return all(results)
1313
1314    @test_tracker_info(uuid="4212d0e0-fb87-47e5-ba48-9df9a4a6bb9b")
1315    @TelephonyBaseTest.tel_test_wrap
1316    def test_voice_performance_stress(self):
1317        """ Vocie Performance stress test"""
1318        return self.performance_tests()
1319
1320    """ Tests End """
1321