1#!/usr/bin/env python3 2# 3# Copyright 2022 - 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 17import random 18import time 19 20from acts.libs.utils.multithread import multithread_func 21from acts.test_decorators import test_tracker_info 22from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest 23from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING 24from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED 25from acts_contrib.test_utils.tel.tel_data_utils import wait_for_cell_data_connection 26from acts_contrib.test_utils.tel.tel_message_utils import mms_send_receive_verify 27from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify 28from acts_contrib.test_utils.tel.tel_parse_utils import parse_mms 29from acts_contrib.test_utils.tel.tel_parse_utils import parse_sms_delivery_time 30from acts_contrib.test_utils.tel.tel_parse_utils import print_nested_dict 31from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb_for_subscription 32from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte_for_subscription 33from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan_for_subscription 34from acts_contrib.test_utils.tel.tel_subscription_utils import set_message_subid 35from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad 36from acts.utils import get_current_epoch_time 37from acts.utils import rand_ascii_str 38 39CALCULATE_EVERY_N_CYCLES = 10 40MAX_FAIL_COUNT = 10 41 42 43class TelLiveRilMessageKpiTest(TelephonyBaseTest): 44 def setup_class(self): 45 TelephonyBaseTest.setup_class(self) 46 self.sms_4g_over_sgs_test_cycle = self.user_params.get( 47 'sms_4g_over_sgs_test_cycle', 1) 48 self.sms_4g_over_ims_test_cycle = self.user_params.get( 49 'sms_4g_over_ims_test_cycle', 1) 50 self.sms_iwlan_test_cycle = self.user_params.get( 51 'sms_iwlan_test_cycle', 1) 52 self.mms_4g_test_cycle = self.user_params.get('mms_4g_test_cycle', 1) 53 self.mms_iwlan_test_cycle = self.user_params.get( 54 'mms_iwlan_test_cycle', 1) 55 56 def sms_test(self, ads): 57 """Send and receive a short SMS with random length and content between 58 two UEs. 59 60 Args: 61 ads: list containing Android objects 62 63 Returns: 64 True if both sending and receiving are successful. Otherwise False. 65 """ 66 msg_length = random.randint(5, 160) 67 msg_body = rand_ascii_str(msg_length) 68 69 if not sms_send_receive_verify(self.log, ads[0], ads[1], [msg_body]): 70 ads[0].log.warning('SMS of length %s test failed', msg_length) 71 return False 72 else: 73 ads[0].log.info('SMS of length %s test succeeded', msg_length) 74 return True 75 76 def mms_test(self, ads, expected_result=True): 77 """Send and receive a MMS with random text length and content between 78 two UEs. 79 80 Args: 81 ads: list containing Android objects 82 expected_result: True to expect successful MMS sending and reception. 83 Otherwise False. 84 85 Returns: 86 True if both sending and reception are successful. Otherwise False. 87 """ 88 message_length = random.randint(5, 160) 89 message_array = [('Test Message', rand_ascii_str(message_length), None)] 90 if not mms_send_receive_verify( 91 self.log, 92 ads[0], 93 ads[1], 94 message_array, 95 expected_result=expected_result): 96 self.log.warning('MMS of body length %s test failed', message_length) 97 return False 98 else: 99 self.log.info('MMS of body length %s test succeeded', message_length) 100 self.log.info('MMS test of body lengths %s succeeded', message_length) 101 return True 102 103 104 def _test_sms_4g(self, over_iwlan=False, over_ims=False): 105 """ Send/receive SMS over SGs/IMS to measure MO SMS setup time and SMS 106 delivery time. 107 108 Test steps: 109 1. Enable VoLTE when over IMS. Otherwise disable VoLTE. 110 2. Send a SMS from MO UE and receive it by MT UE. 111 3. Parse logcat of both MO and MT UEs to calculate MO SMS setup time 112 and SMS delivery time. 113 114 Args: 115 over_iwlan: True for over Wi-Fi and False for over cellular network 116 over_ims: True for over IMS and False for over SGs 117 118 Returns: 119 True if both sending and reception are successful. Otherwise False. 120 """ 121 ad_mo = self.android_devices[0] 122 ad_mt = self.android_devices[1] 123 124 mo_sub_id, mt_sub_id, _ = get_subid_on_same_network_of_host_ad( 125 [ad_mo, ad_mt], 126 host_sub_id=None, 127 type="sms") 128 set_message_subid(ad_mt, mt_sub_id) 129 130 cycle = self.sms_4g_over_sgs_test_cycle 131 phone_setup_func = phone_setup_csfb_for_subscription 132 mo_param = (self.log, ad_mo, mo_sub_id) 133 mt_param = (self.log, ad_mt, mt_sub_id) 134 wording = "SGs" 135 parsing = '4g' 136 if over_ims: 137 cycle = self.sms_4g_over_ims_test_cycle 138 phone_setup_func = phone_setup_volte_for_subscription 139 wording = "IMS" 140 parsing = 'iwlan' 141 142 if over_iwlan: 143 cycle = self.sms_iwlan_test_cycle 144 phone_setup_func = phone_setup_iwlan_for_subscription 145 146 mo_param = ( 147 self.log, 148 ad_mo, 149 mo_sub_id, 150 True, 151 WFC_MODE_CELLULAR_PREFERRED, 152 self.wifi_network_ssid, 153 self.wifi_network_pass) 154 155 mt_param = ( 156 self.log, 157 ad_mt, 158 mt_sub_id, 159 True, 160 WFC_MODE_CELLULAR_PREFERRED, 161 self.wifi_network_ssid, 162 self.wifi_network_pass) 163 164 wording = 'iwlan' 165 parsing = 'iwlan' 166 167 tasks = [ 168 (phone_setup_func, mo_param), 169 (phone_setup_func, mt_param)] 170 if not multithread_func(self.log, tasks): 171 self.log.error("Phone Failed to Set Up Properly.") 172 return False 173 174 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 175 176 sms_test_summary = [] 177 result = True 178 continuous_fail = 0 179 for attempt in range(cycle): 180 self.log.info( 181 '======> MO/MT SMS over %s %s/%s <======', 182 wording, 183 attempt+1, 184 cycle) 185 res = self.sms_test([ad_mo, ad_mt]) 186 sms_test_summary.append(res) 187 188 if not res: 189 continuous_fail += 1 190 if not multithread_func(self.log, tasks): 191 self.log.error("Phone Failed to Set Up Properly.") 192 result = False 193 self._take_bug_report( 194 self.test_name, begin_time=get_current_epoch_time()) 195 else: 196 time.sleep(random.randint(3,10)) 197 198 if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or ( 199 attempt == cycle - 1) or continuous_fail >= MAX_FAIL_COUNT: 200 parse_sms_delivery_time(self.log, ad_mo, ad_mt, rat=parsing) 201 try: 202 sms_test_fail_rate = sms_test_summary.count( 203 False)/len(sms_test_summary) 204 self.log.info( 205 'Fail rate of SMS test over %s: %s/%s (%.2f)', 206 wording, 207 sms_test_summary.count(False), 208 len(sms_test_summary), 209 sms_test_fail_rate) 210 except Exception as e: 211 self.log.error( 212 'Fail rate of SMS test over %s: ERROR (%s)', 213 wording, 214 e) 215 216 if continuous_fail >= MAX_FAIL_COUNT: 217 self.log.error( 218 'Failed more than %s times in succession. Test is terminated ' 219 'forcedly.', 220 MAX_FAIL_COUNT) 221 break 222 223 return result 224 225 226 @test_tracker_info(uuid="13d1a53b-66be-4ac1-b5ee-dfe4c5e4e4e1") 227 @TelephonyBaseTest.tel_test_wrap 228 def test_sms_4g_over_sgs(self): 229 """ Send/receive SMS over SGs to measure MO SMS setup time and SMS 230 delivery time. 231 232 Test steps: 233 1. Disable VoLTE. 234 2. Send a SMS from MO UE and receive it by MT UE. 235 3. Parse logcat of both MO and MT UEs to calculate MO SMS setup time 236 and SMS delivery time. 237 """ 238 return self._test_sms_4g() 239 240 241 @test_tracker_info(uuid="293e2955-b38b-4329-b686-fb31d9e46868") 242 @TelephonyBaseTest.tel_test_wrap 243 def test_sms_4g_over_ims(self): 244 """ Send/receive SMS over IMS to measure MO SMS setup time and SMS 245 delivery time. 246 247 Test steps: 248 1. Enable VoLTE. 249 2. Send a SMS from MO UE and receive it by MT UE. 250 3. Parse logcat of both MO and MT UEs to calculate MO SMS setup time 251 and SMS delivery time. 252 """ 253 return self._test_sms_4g(over_ims=True) 254 255 256 @test_tracker_info(uuid="862fec2d-8e23-482e-b45c-a42cad134022") 257 @TelephonyBaseTest.tel_test_wrap 258 def test_sms_iwlan(self): 259 """ Send/receive SMS on iwlan to measure MO SMS setup time and SMS 260 delivery time. 261 262 Test steps: 263 1. Send a SMS from MO UE and receive it by MT UE. 264 2. Parse logcat of both MO and MT UEs to calculate MO SMS setup time 265 and SMS delivery time. 266 """ 267 return self._test_sms_4g(over_iwlan=True, over_ims=True) 268 269 270 def _test_mms_4g(self, over_iwlan=False): 271 """ Send/receive MMS on LTE to measure MO and MT MMS setup time 272 273 Test steps: 274 1. Enable VoLTE when over Wi-Fi (iwlan). Otherwise disable VoLTE. 275 2. Send a MMS from MO UE and receive it by MT UE. 276 3. Parse logcat of both MO and MT UEs to calculate MO and MT MMS 277 setup time. 278 279 Args: 280 over_iwlan: True for over Wi-Fi and False for over cellular network 281 282 Returns: 283 True if both sending and reception are successful. Otherwise False. 284 """ 285 ad_mo = self.android_devices[0] 286 ad_mt = self.android_devices[1] 287 288 mo_sub_id, mt_sub_id, _ = get_subid_on_same_network_of_host_ad( 289 [ad_mo, ad_mt], 290 host_sub_id=None, 291 type="sms") 292 set_message_subid(ad_mt, mt_sub_id) 293 294 cycle = self.mms_4g_test_cycle 295 phone_setup_func = phone_setup_csfb_for_subscription 296 mo_param = (self.log, ad_mo, mo_sub_id) 297 mt_param = (self.log, ad_mt, mt_sub_id) 298 wording = "LTE" 299 if over_iwlan: 300 cycle = self.mms_iwlan_test_cycle 301 phone_setup_func = phone_setup_iwlan_for_subscription 302 wording = "iwlan" 303 304 mo_param = ( 305 self.log, 306 ad_mo, 307 mo_sub_id, 308 True, 309 WFC_MODE_CELLULAR_PREFERRED, 310 self.wifi_network_ssid, 311 self.wifi_network_pass) 312 313 mt_param = ( 314 self.log, 315 ad_mt, 316 mt_sub_id, 317 True, 318 WFC_MODE_CELLULAR_PREFERRED, 319 self.wifi_network_ssid, 320 self.wifi_network_pass) 321 322 phone_setup_tasks = [ 323 (phone_setup_func, mo_param), 324 (phone_setup_func, mt_param)] 325 if not multithread_func(self.log, phone_setup_tasks): 326 self.log.error("Phone Failed to Set Up Properly.") 327 return False 328 329 if not over_iwlan: 330 wait_for_cell_data_connection_tasks = [ 331 (wait_for_cell_data_connection, (self.log, ad_mo, True)), 332 (wait_for_cell_data_connection, (self.log, ad_mt, True))] 333 if not multithread_func(self.log, wait_for_cell_data_connection_tasks): 334 return False 335 336 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 337 338 mms_test_summary = [] 339 result = True 340 continuous_fail = 0 341 for attempt in range(cycle): 342 self.log.info( 343 '==================> MO/MT MMS on %s %s/%s <==================', 344 wording, 345 attempt+1, 346 cycle) 347 res = self.mms_test([ad_mo, ad_mt]) 348 mms_test_summary.append(res) 349 350 if not res: 351 continuous_fail += 1 352 if not multithread_func(self.log, phone_setup_tasks): 353 self.log.error("Phone Failed to Set Up Properly.") 354 result = False 355 break 356 357 if not over_iwlan: 358 if not multithread_func( 359 self.log, wait_for_cell_data_connection_tasks): 360 result = False 361 break 362 self._take_bug_report( 363 self.test_name, begin_time=get_current_epoch_time()) 364 else: 365 time.sleep(random.randint(3,10)) 366 367 if (attempt+1) % CALCULATE_EVERY_N_CYCLES == 0 or ( 368 attempt == cycle - 1) or continuous_fail >= MAX_FAIL_COUNT: 369 ( 370 mo_res, 371 mo_avg_setup_time, 372 mt_res, mt_avg_setup_time) = parse_mms(ad_mo, ad_mt) 373 374 ad_mo.log.info('================== Sent MMS ==================') 375 print_nested_dict(ad_mo, mo_res) 376 ad_mt.log.info('================== Received MMS ==================') 377 print_nested_dict(ad_mt, mt_res) 378 379 try: 380 ad_mo.log.info( 381 'Average setup time of MO MMS on %s: %.2f sec.', 382 wording, mo_avg_setup_time) 383 except Exception as e: 384 ad_mo.log.error( 385 'Average setup time of MO MMS on %s: ERROR (%s)', 386 wording, e) 387 388 try: 389 ad_mt.log.info( 390 'Average setup time of MT MMS on %s: %.2f sec.', 391 wording, mt_avg_setup_time) 392 except Exception as e: 393 ad_mt.log.error( 394 'Average setup time of MT MMS on %s: ERROR (%s)', 395 wording, e) 396 397 try: 398 mms_test_fail_rate = mms_test_summary.count( 399 False)/len(mms_test_summary) 400 self.log.info( 401 'Fail rate of MMS test on LTE: %s/%s (%.2f)', 402 mms_test_summary.count(False), 403 len(mms_test_summary), 404 mms_test_fail_rate) 405 except Exception as e: 406 self.log.error( 407 'Fail rate of MMS test on %s: ERROR (%s)', wording, e) 408 409 if continuous_fail >= MAX_FAIL_COUNT: 410 self.log.error( 411 'Failed more than %s times in succession. Test is terminated ' 412 'forcedly.', 413 MAX_FAIL_COUNT) 414 break 415 416 return result 417 418 419 @test_tracker_info(uuid="33d11da8-71f1-40d7-8fc7-86fdc83ce266") 420 @TelephonyBaseTest.tel_test_wrap 421 def test_mms_4g(self): 422 """ Send/receive MMS on LTE to measure MO and MT MMS setup time 423 424 Test steps: 425 1. Send a MMS from MO UE and receive it by MT UE. 426 2. Parse logcat of both MO and MT UEs to calculate MO and MT MMS 427 setup time. 428 """ 429 return self._test_mms_4g() 430 431 432 @test_tracker_info(uuid="b8a8affa-6559-41d8-9de7-f74406da9ed5") 433 @TelephonyBaseTest.tel_test_wrap 434 def test_mms_iwlan(self): 435 """ Send/receive MMS on iwlan to measure MO and MT MMS setup time 436 437 Test steps: 438 1. Send a MMS from MO UE and receive it by MT UE. 439 2. Parse logcat of both MO and MT UEs to calculate MO and MT MMS 440 setup time. 441 """ 442 return self._test_mms_4g(over_iwlan=True)