1#!/usr/bin/env python3
2#
3#   Copyright 2019 - The Android Open Source Project
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 os
18import re
19import time
20from acts import asserts
21from acts.test_utils.bt.BtSarBaseTest import BtSarBaseTest
22
23
24class BtSarSanityTest(BtSarBaseTest):
25    """Class to run sanity checks on BT SAR mechanisms.
26
27    This class defines sanity test cases on BT SAR. The tests include
28    a software state sanity check and a software power sanity check.
29    """
30    def __init__(self, controllers):
31        super().__init__(controllers)
32
33    def test_bt_sar_sanity_check_state(self):
34        """ Test for BT SAR State Sanity
35
36        BT SAR Software Sanity Test to ensure that the correct signal state
37        gets propagated to the firmware. This is done by comparing expected
38        device state with that read from device's logcat
39        """
40        #Iterating through the BT SAR scenarios
41        for scenario in range(0, self.bt_sar_df.shape[0]):
42            # Reading BT SAR table row into dict
43            read_scenario = self.bt_sar_df.loc[scenario].to_dict()
44
45            start_time = self.dut.adb.shell('date +%s.%m')
46            time.sleep(1)
47
48            #Setting SAR state to the read BT SAR row
49            enforced_state = self.set_sar_state(self.dut, read_scenario)
50
51            #Reading device state from logcat after forcing SAR State
52            device_state = self.get_current_device_state(self.dut, start_time)
53
54            #Comparing read device state to expected device state
55            for key in enforced_state.keys():
56                key_regex = r'{}:\s*(\d)'.format(key)
57                try:
58                    propagated_value = int(
59                        re.findall(key_regex, device_state)[0])
60                except TypeError:
61                    propagated_value = 'NA'
62
63                if enforced_state[key] == propagated_value:
64                    self.log.info(
65                        'scenario: {}, state : {}, forced_value: {}, value:{}'.
66                        format(scenario, key, enforced_state[key],
67                               propagated_value))
68                else:
69                    self.log.error(
70                        'scenario:{}, state : {}, forced_value: {}, value:{}'.
71                        format(scenario, key, enforced_state[key],
72                               propagated_value))
73
74    def test_bt_sar_sanity_check_power(self):
75        """ Test for BT SAR Power Cap Sanity
76
77        BT SAR Power Cap Sanity Test to ensure that the correct SAR power
78        cap corresponding to the forced SAR state gets propagated to the
79        firmware. This is done by comparing expected power cap read from
80        the BT SAR file to the power cap read from logcat
81        """
82
83        sar_df = self.bt_sar_df
84        sar_df['power_cap'] = -128
85
86        #Iterating through the BT SAR scenarios
87        for scenario in range(0, self.bt_sar_df.shape[0]):
88
89            # Reading BT SAR table row into dict
90            read_scenario = sar_df.loc[scenario].to_dict()
91
92            start_time = self.dut.adb.shell('date +%s.%m')
93            time.sleep(1)
94
95            #Setting SAR state to the read BT SAR row
96            self.set_sar_state(self.dut, read_scenario)
97
98            #Reading device power cap from logcat after forcing SAR State
99            scenario_power_cap = self.get_current_power_cap(
100                self.dut, start_time)
101            sar_df.loc[scenario, 'power_cap'] = scenario_power_cap
102            self.log.info('scenario: {}, '
103                          'sar_power: {}, power_cap:{}'.format(
104                              scenario, sar_df.loc[scenario, 'BluetoothPower'],
105                              sar_df.loc[scenario, 'power_cap']))
106
107        results_file_path = os.path.join(
108            self.log_path, '{}.csv'.format(self.current_test_name))
109        sar_df.to_csv(results_file_path)
110
111        # Comparing read device power cap to expected device power cap
112        if sar_df['power_cap'].equals(sar_df['BluetoothPower']):
113            asserts.explicit_pass('Power Caps were set according to the table')
114        else:
115            asserts.fail("Power Caps didn't match powers in the table")
116