1#!/usr/bin/env python3.4
2#
3#   Copyright 2020 - 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 Factory Data Reset In Sanity
18"""
19
20import collections
21import time
22
23from acts import signals
24from acts.test_decorators import test_tracker_info
25from acts.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
26from acts.test_utils.tel.tel_data_utils import wifi_tethering_setup_teardown
27from acts.test_utils.tel.tel_defines import CAPABILITY_VOLTE
28from acts.test_utils.tel.tel_defines import CAPABILITY_WFC
29from acts.test_utils.tel.tel_defines import CAPABILITY_OMADM
30from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_TETHERING_ENTITLEMENT_CHECK
31from acts.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
32from acts.test_utils.tel.tel_defines import GEN_4G
33from acts.test_utils.tel.tel_defines import TETHERING_MODE_WIFI
34from acts.test_utils.tel.tel_defines import WAIT_TIME_AFTER_FDR
35from acts.test_utils.tel.tel_test_utils import call_setup_teardown
36from acts.test_utils.tel.tel_test_utils import ensure_phone_subscription
37from acts.test_utils.tel.tel_test_utils import get_model_name
38from acts.test_utils.tel.tel_test_utils import get_outgoing_voice_sub_id
39from acts.test_utils.tel.tel_test_utils import is_droid_in_network_generation
40from acts.test_utils.tel.tel_test_utils import mms_send_receive_verify
41from acts.test_utils.tel.tel_test_utils import fastboot_wipe
42from acts.test_utils.tel.tel_test_utils import sms_send_receive_verify
43from acts.test_utils.tel.tel_test_utils import wait_for_network_generation
44from acts.test_utils.tel.tel_test_utils import verify_internet_connection
45from acts.test_utils.tel.tel_test_utils import wait_for_state
46from acts.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
47from acts.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
48from acts.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
49from acts.test_utils.tel.tel_voice_utils import phone_idle_volte
50from acts.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
51from acts.test_utils.tel.tel_voice_utils import phone_setup_csfb
52from acts.test_utils.tel.tel_voice_utils import phone_setup_volte
53
54from acts.utils import get_current_epoch_time
55from acts.utils import rand_ascii_str
56
57
58class TelLiveStressFdrTest(TelephonyBaseTest):
59    def setup_class(self):
60        TelephonyBaseTest.setup_class(self)
61
62        self.stress_test_number = int(
63            self.user_params.get("stress_test_number", 100))
64        self.skip_reset_between_cases = False
65
66        self.dut = self.android_devices[0]
67        if len(self.android_devices) > 1:
68            self.ad_reference = self.android_devices[1]
69        else:
70            raise signals.TestSkip("Single DUT is not supported")
71        self.user_params["check_crash"] = False
72        self.skip_reset_between_cases = False
73
74        # self.dut_capabilities = self.dut.telephony.get("capabilities", [])
75        sub_id = get_outgoing_voice_sub_id(self.dut)
76        self.dut_capabilities = self.dut.telephony["subscription"][sub_id].get("capabilities", [])
77        self.dut.log.info("dut_capabilitiese: %s", self.dut_capabilities)
78
79        self.dut_wfc_modes = self.dut.telephony.get("wfc_modes", [])
80        self.default_testing_func_names = []
81        for method in ("_check_volte", "_check_csfb",
82                       "_check_tethering", "_check_3g"):
83            func = getattr(self, method)
84            try:
85                check_result = func()
86            except Exception as e:
87                self.dut.log.error("%s failed with %s", method, e)
88                check_result = False
89            self.dut.log.info("%s is %s before tests start", method,
90                              check_result)
91            if check_result:
92                self.default_testing_func_names.append(method)
93        self.dut.log.info("To be tested: %s", self.default_testing_func_names)
94
95    def teardown_test(self):
96        self._set_volte_provisioning()
97
98    def feature_validator(self, *args):
99        failed_tests = []
100        for method in ("_check_subscription", "_check_data", "_check_mms_mt",
101                       "_check_sms_mt", "_check_call_setup_teardown",
102                       "_check_sms", "_check_mms"):
103            func = getattr(self, method)
104            if not func():
105                self.log.error("%s failed", method)
106                failed_tests.append(method)
107        for method in args:
108            func = getattr(self, method)
109            try:
110                func_result = func()
111            except Exception as e:
112                self.log.error("%s check failed with %s", method, e)
113                func_result = False
114            if not func_result:
115                self.log.error("%s failed", method)
116                failed_tests.append(method)
117            else:
118                self.log.info("%s succeeded", method)
119        if failed_tests:
120            self.log.error("%s failed", failed_tests)
121        return failed_tests
122
123    def _check_subscription(self):
124        if not ensure_phone_subscription(self.log, self.dut):
125            self.dut.log.error("Subscription check failed")
126            return False
127        else:
128            return True
129
130    def _check_volte_provisioning(self):
131        if CAPABILITY_OMADM in self.dut_capabilities:
132            if not wait_for_state(self.dut.droid.imsIsVolteProvisionedOnDevice,
133                                  True):
134                self.dut.log.error("VoLTE provisioning is disabled.")
135                return False
136            else:
137                self.dut.log.info("VoLTE provision is enabled")
138                return True
139        return True
140
141    def _set_volte_provisioning(self):
142        if CAPABILITY_OMADM in self.dut_capabilities:
143            provisioned = self.dut.droid.imsIsVolteProvisionedOnDevice()
144            if provisioned:
145                self.dut.log.info("Volte is provioned")
146                return
147            self.dut.log.info("VoLTE provisioning is not set, setting\
148                VoLTE provision")
149            self.dut.droid.imsSetVolteProvisioning(True)
150
151    def _check_call_setup_teardown(self):
152        if not call_setup_teardown(self.log, self.dut, self.ad_reference,
153                                   self.dut):
154            self.log.error("Phone call test failed.")
155            return False
156        return True
157
158    def _check_sms(self):
159        if not sms_send_receive_verify(self.log, self.dut, self.ad_reference,
160                                       [rand_ascii_str(180)]):
161            self.log.error("SMS send test failed")
162            return False
163        else:
164            self.log.info("SMS send test passed")
165            return True
166
167    def _check_mms(self):
168        message_array = [("Test Message", rand_ascii_str(180), None)]
169        if not mms_send_receive_verify(self.log, self.dut, self.ad_reference,
170                                       message_array):
171            self.log.error("MMS test sendfailed")
172            return False
173        else:
174            self.log.info("MMS send test passed")
175            return True
176
177    def _check_sms_mt(self):
178        if not sms_send_receive_verify(self.log, self.ad_reference, self.dut,
179                                       [rand_ascii_str(180)]):
180            self.log.error("SMS receive test failed")
181            return False
182        else:
183            self.log.info("SMS receive test passed")
184            return True
185
186    def _check_mms_mt(self):
187        message_array = [("Test Message", rand_ascii_str(180), None)]
188        if not mms_send_receive_verify(self.log, self.ad_reference, self.dut,
189                                       message_array):
190            self.log.error("MMS receive test failed")
191            return False
192        else:
193            self.log.info("MMS receive test passed")
194            return True
195
196    def _check_data(self):
197        if not verify_internet_connection(self.log, self.dut):
198            self.dut.log.error("Data connection is not available.")
199            return False
200        return True
201
202    def _check_lte_data(self):
203        if not is_droid_in_network_generation(self.log, self.dut, GEN_4G,
204                                              NETWORK_SERVICE_DATA):
205            self.dut.log.error("Data is not on 4G network")
206            return False
207        if not verify_internet_connection(self.log, self.dut):
208            self.log.error("Data not available on cell.")
209            return False
210        return True
211
212    def _check_volte(self):
213        if CAPABILITY_VOLTE in self.dut_capabilities:
214            self._set_volte_provisioning()
215            if not self._check_volte_provisioning():
216                return False
217            self.log.info("Check VoLTE")
218            if not wait_for_state(self.dut.droid.imsIsVolteProvisionedOnDevice,
219                                  True):
220                self.dut.log.error("VoLTE provisioning is disabled.")
221                return False
222            if not phone_setup_volte(self.log, self.dut):
223                self.log.error("Failed to setup VoLTE.")
224                return False
225            time.sleep(5)
226            if not call_setup_teardown(self.log, self.dut, self.ad_reference,
227                                       self.dut, is_phone_in_call_volte):
228                self.log.error("VoLTE Call Failed.")
229                return False
230            if not self._check_lte_data():
231                return False
232        else:
233            self.dut.log.info("VoLTE is not supported")
234            return False
235        return True
236
237    def _check_csfb(self):
238        if not phone_setup_csfb(self.log, self.dut):
239            self.log.error("Failed to setup CSFB.")
240            return False
241        if not call_setup_teardown(self.log, self.dut, self.ad_reference,
242                                   self.dut, is_phone_in_call_csfb):
243            self.dut.log.error("CSFB Call Failed.")
244            return False
245        if not wait_for_network_generation(
246                self.log, self.dut, GEN_4G,
247                voice_or_data=NETWORK_SERVICE_DATA):
248            self.dut.log.error("Data service failed to camp to 4G")
249            return False
250        if not verify_internet_connection(self.log, self.dut):
251            self.log.error("Data not available on cell.")
252            return False
253        return True
254
255    def _check_volte_enabled(self):
256        if phone_idle_volte(self.log, self.dut):
257            self.dut.log.info("VoLTE is enabled")
258        else:
259            self.dut.log.error("VoLTE is not enabled")
260            return False
261        if not call_setup_teardown(self.log, self.dut, self.ad_reference,
262                                   self.dut, is_phone_in_call_volte):
263            self.log.error("VoLTE Call Failed.")
264            return False
265        if not self._check_lte_data():
266            return False
267        return True
268
269    def _check_csfb_enabled(self):
270        if not call_setup_teardown(self.log, self.dut, self.ad_reference,
271                                   self.dut, is_phone_in_call_csfb):
272            self.log.error("CSFB Call Failed.")
273            return False
274        if not wait_for_network_generation(
275                self.log, self.dut, GEN_4G,
276                voice_or_data=NETWORK_SERVICE_DATA):
277            self.dut.log.error("Data service failed to camp to 4G")
278            return False
279        if not verify_internet_connection(self.log, self.dut):
280            self.log.error("Data not available on cell.")
281            return False
282        return True
283
284    def _check_3g(self):
285        self.log.info("Check 3G data and CS call")
286        if not phone_setup_voice_3g(self.log, self.dut):
287            self.log.error("Failed to setup 3G")
288            return False
289        if not verify_internet_connection(self.log, self.dut):
290            self.log.error("Data not available on cell.")
291            return False
292        if not call_setup_teardown(self.log, self.dut, self.ad_reference,
293                                   self.dut, is_phone_in_call_3g):
294            self.log.error("WFC Call Failed.")
295            return False
296        if not sms_send_receive_verify(self.log, self.dut, self.ad_reference,
297                                       [rand_ascii_str(50)]):
298            self.log.error("SMS failed in 3G")
299            return False
300        return True
301
302    def _check_tethering(self):
303        self.log.info("Check tethering")
304        for retries in range(3):
305            try:
306                if not self.dut.droid.carrierConfigIsTetheringModeAllowed(
307                        TETHERING_MODE_WIFI,
308                        MAX_WAIT_TIME_TETHERING_ENTITLEMENT_CHECK):
309                    self.log.error("Tethering Entitlement check failed.")
310                    if retries == 2: return False
311                    time.sleep(10)
312            except Exception as e:
313                if retries == 2:
314                    self.dut.log.error(e)
315                    return False
316                time.sleep(10)
317        if not wifi_tethering_setup_teardown(
318                self.log,
319                self.dut, [self.ad_reference],
320                check_interval=5,
321                check_iteration=1):
322            self.log.error("Tethering check failed.")
323            return False
324        return True
325
326    def _fdr_stress_test(self, *args):
327        """Fdr Reliability Test
328
329        Arguments:
330            function_name: function to be checked
331
332        Expected Results:
333            No crash happens in stress test.
334
335        Returns:
336            True is pass, False if fail.
337        """
338        self.number_of_devices = 2
339        fail_count = collections.defaultdict(int)
340        test_result = True
341
342        for i in range(1, self.stress_test_number + 1):
343            begin_time = get_current_epoch_time()
344            test_name = "%s_iteration_%s" % (self.test_name, i)
345            log_msg = "[Test Case] %s" % test_name
346            self.log.info("%s begin", log_msg)
347            self.dut.droid.logI("%s begin" % log_msg)
348            test_msg = "FDR Stress Test %s Iteration <%s> / <%s>" % (
349                self.test_name, i, self.stress_test_number)
350            self.log.info(test_msg)
351            fastboot_wipe(self.dut)
352            self.log.info("%s wait %s secs for radio up.",
353                self.dut.serial, WAIT_TIME_AFTER_FDR)
354            time.sleep(WAIT_TIME_AFTER_FDR)
355            failed_tests = self.feature_validator(*args)
356            for test in failed_tests:
357                fail_count[test] += 1
358
359            crash_report = self.dut.check_crash_report(
360                "%s_%s" % (self.test_name, i),
361                begin_time,
362                log_crash_report=True)
363            if crash_report:
364                fail_count["crashes"] += 1
365            if failed_tests or crash_report:
366                self.log.error("%s FAIL with %s and crashes %s", test_msg,
367                               failed_tests, crash_report)
368                self._take_bug_report(test_name, begin_time)
369            else:
370                self.log.info("%s PASS", test_msg)
371            self.log.info("Total failure count: %s", dict(fail_count))
372            self.log.info("%s end", log_msg)
373            self.dut.droid.logI("%s end" % log_msg)
374
375        for failure, count in fail_count.items():
376            if count:
377                self.log.error("%s failure count = %s in total %s iterations",
378                               failure, count, self.stress_test_number)
379                test_result = False
380        return test_result
381
382
383    """ Tests Begin """
384
385
386    @test_tracker_info(uuid="a09a5d44-ffcc-4890-b0ba-a30a75e05fbd")
387    @TelephonyBaseTest.tel_test_wrap
388    def test_fdr_stress_volte(self):
389        """FDR with VoLTE Test
390
391        Steps:
392            1. Fdr DUT.
393            2. Wait for DUT to camp on LTE, Verify Data.
394            3. Check VoLTE is enabled by default, check IMS registration.
395               Wait for DUT report VoLTE enabled, make VoLTE call.
396               And verify VoLTE SMS. (if support VoLTE)
397            4. Check crashes.
398            5. Repeat Step 1~4 for N times.
399
400        Expected Results:
401            No crash happens in stress test.
402
403        Returns:
404            True is pass, False if fail.
405        """
406        if CAPABILITY_VOLTE not in self.dut_capabilities:
407            raise signals.TestSkip("VOLTE is not supported")
408        if not self._check_volte():
409            self.dut.log.error("VoLTE test failed before fdr test")
410            return False
411        func_names = ["_check_volte_enabled"]
412        return self._fdr_stress_test(*func_names)
413
414    """ Tests End """
415