1#!/usr/bin/env python3.4 2# 3# Copyright 2016 - 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 Base Class for Defining Common Telephony Test Functionality 18""" 19 20import os 21import time 22import traceback 23 24import acts.controllers.diag_logger 25 26from acts.base_test import BaseTestClass 27from acts.signals import TestSignal 28from acts import utils 29 30from acts.test_utils.tel.tel_subscription_utils import \ 31 get_subid_from_slot_index 32from acts.test_utils.tel.tel_subscription_utils import \ 33 initial_set_up_for_subid_infomation 34from acts.test_utils.tel.tel_subscription_utils import set_subid_for_data 35from acts.test_utils.tel.tel_subscription_utils import \ 36 set_subid_for_message 37from acts.test_utils.tel.tel_subscription_utils import \ 38 set_subid_for_outgoing_call 39from acts.test_utils.tel.tel_test_utils import ensure_phones_default_state 40from acts.test_utils.tel.tel_test_utils import \ 41 reset_preferred_network_type_to_allowable_range 42from acts.test_utils.tel.tel_test_utils import set_phone_screen_on 43from acts.test_utils.tel.tel_test_utils import set_phone_silent_mode 44from acts.test_utils.tel.tel_test_utils import setup_droid_properties 45from acts.test_utils.tel.tel_test_utils import refresh_droid_config 46from acts.test_utils.tel.tel_defines import PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND 47from acts.test_utils.tel.tel_defines import PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING 48from acts.test_utils.tel.tel_defines import PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND 49from acts.test_utils.tel.tel_defines import WIFI_VERBOSE_LOGGING_ENABLED 50from acts.test_utils.tel.tel_defines import WIFI_VERBOSE_LOGGING_DISABLED 51from acts.utils import force_airplane_mode 52 53 54class TelephonyBaseTest(BaseTestClass): 55 def __init__(self, controllers): 56 BaseTestClass.__init__(self, controllers) 57 self.logger_sessions = [] 58 59 # Use for logging in the test cases to facilitate 60 # faster log lookup and reduce ambiguity in logging. 61 def tel_test_wrap(fn): 62 def _safe_wrap_test_case(self, *args, **kwargs): 63 test_id = "{}:{}:{}".format(self.__class__.__name__, fn.__name__, 64 time.time()) 65 log_string = "[Test ID] {}".format(test_id) 66 self.log.info(log_string) 67 try: 68 for ad in self.android_devices: 69 ad.droid.logI("Started " + log_string) 70 # TODO: b/19002120 start QXDM Logging 71 result = fn(self, *args, **kwargs) 72 if result is not True and "telephony_auto_rerun" in self.user_params: 73 self.teardown_test() 74 # re-run only once, if re-run pass, mark as pass 75 log_string = "[Rerun Test ID] {}. 1st run failed.".format( 76 test_id) 77 self.log.info(log_string) 78 self.setup_test() 79 for ad in self.android_devices: 80 ad.droid.logI("Rerun Started " + log_string) 81 result = fn(self, *args, **kwargs) 82 if result is True: 83 self.log.info("Rerun passed.") 84 elif result is False: 85 self.log.info("Rerun failed.") 86 else: 87 # In the event that we have a non-bool or null 88 # retval, we want to clearly distinguish this in the 89 # logs from an explicit failure, though the test will 90 # still be considered a failure for reporting purposes. 91 self.log.info("Rerun indeterminate.") 92 result = False 93 return result 94 except TestSignal: 95 raise 96 except Exception as e: 97 self.log.error(traceback.format_exc()) 98 self.log.error(str(e)) 99 return False 100 finally: 101 # TODO: b/19002120 stop QXDM Logging 102 for ad in self.android_devices: 103 try: 104 ad.adb.wait_for_device() 105 ad.droid.logI("Finished " + log_string) 106 except Exception as e: 107 self.log.error(str(e)) 108 109 return _safe_wrap_test_case 110 111 def setup_class(self): 112 setattr(self, "diag_logger", 113 self.register_controller(acts.controllers.diag_logger, 114 required=False)) 115 for ad in self.android_devices: 116 setup_droid_properties(self.log, ad, 117 self.user_params["sim_conf_file"]) 118 if not set_phone_screen_on(self.log, ad): 119 self.log.error("Failed to set phone screen-on time.") 120 return False 121 if not set_phone_silent_mode(self.log, ad): 122 self.log.error("Failed to set phone silent mode.") 123 return False 124 125 ad.droid.telephonyAdjustPreciseCallStateListenLevel( 126 PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND, True) 127 ad.droid.telephonyAdjustPreciseCallStateListenLevel( 128 PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING, True) 129 ad.droid.telephonyAdjustPreciseCallStateListenLevel( 130 PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND, True) 131 132 if "enable_wifi_verbose_logging" in self.user_params: 133 ad.droid.wifiEnableVerboseLogging(WIFI_VERBOSE_LOGGING_ENABLED) 134 135 # Reset preferred network type. 136 reset_preferred_network_type_to_allowable_range(self.log, ad) 137 138 # Sub ID setup 139 for ad in self.android_devices: 140 initial_set_up_for_subid_infomation(self.log, ad) 141 return True 142 143 def teardown_class(self): 144 try: 145 ensure_phones_default_state(self.log, self.android_devices) 146 147 for ad in self.android_devices: 148 ad.droid.telephonyAdjustPreciseCallStateListenLevel( 149 PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND, False) 150 ad.droid.telephonyAdjustPreciseCallStateListenLevel( 151 PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING, False) 152 ad.droid.telephonyAdjustPreciseCallStateListenLevel( 153 PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND, False) 154 if "enable_wifi_verbose_logging" in self.user_params: 155 ad.droid.wifiEnableVerboseLogging( 156 WIFI_VERBOSE_LOGGING_DISABLED) 157 finally: 158 for ad in self.android_devices: 159 try: 160 ad.droid.connectivityToggleAirplaneMode(True) 161 except BrokenPipeError: 162 # Broken Pipe, can not call SL4A API to turn on Airplane Mode. 163 # Use adb command to turn on Airplane Mode. 164 if not force_airplane_mode(ad, True): 165 self.log.error( 166 "Can not turn on airplane mode on:{}".format( 167 ad.serial)) 168 return True 169 170 def setup_test(self): 171 for ad in self.android_devices: 172 refresh_droid_config(self.log, ad) 173 174 if getattr(self, "diag_logger", None): 175 for logger in self.diag_logger: 176 self.log.info("Starting a diagnostic session {}".format( 177 logger)) 178 self.logger_sessions.append((logger, logger.start())) 179 180 return ensure_phones_default_state(self.log, self.android_devices) 181 182 def teardown_test(self): 183 for (logger, session) in self.logger_sessions: 184 self.log.info("Resetting a diagnostic session {},{}".format( 185 logger, session)) 186 logger.reset() 187 self.logger_sessions = [] 188 return True 189 190 def on_exception(self, test_name, begin_time): 191 self._pull_diag_logs(test_name, begin_time) 192 return self._take_bug_report(test_name, begin_time) 193 194 def on_fail(self, test_name, begin_time): 195 self._pull_diag_logs(test_name, begin_time) 196 return self._take_bug_report(test_name, begin_time) 197 198 def _pull_diag_logs(self, test_name, begin_time): 199 for (logger, session) in self.logger_sessions: 200 self.log.info("Pulling diagnostic session {}".format(logger)) 201 logger.stop(session) 202 diag_path = os.path.join(self.log_path, begin_time) 203 utils.create_dir(diag_path) 204 logger.pull(session, diag_path) 205 206 def _take_bug_report(self, test_name, begin_time): 207 if "no_bug_report_on_fail" in self.user_params: 208 return 209 210 # magical sleep to ensure the runtime restart or reboot begins 211 time.sleep(1) 212 for ad in self.android_devices: 213 try: 214 ad.adb.wait_for_device() 215 ad.take_bug_report(test_name, begin_time) 216 tombstone_path = os.path.join( 217 ad.log_path, "BugReports", 218 "{},{}".format(begin_time, ad.serial).replace(' ', '_')) 219 utils.create_dir(tombstone_path) 220 ad.adb.pull('/data/tombstones/', tombstone_path) 221 except: 222 ad.log.error("Failed to take a bug report for {}, {}" 223 .format(ad.serial, test_name)) 224