• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
20
21from acts import asserts
22import acts_contrib.test_utils.bt.bt_test_utils as bt_utils
23from acts_contrib.test_utils.bt.BtSarBaseTest import BtSarBaseTest
24
25
26class BtSarSanityTest(BtSarBaseTest):
27    """Class to run sanity checks on BT SAR mechanisms.
28
29    This class defines sanity test cases on BT SAR. The tests include
30    a software state sanity check and a software power sanity check.
31    """
32
33    def setup_class(self):
34        super().setup_class()
35
36        self.reg_domain_dict = {
37            'US': 'bluetooth_power_limits_US.csv',
38            'EU': 'bluetooth_power_limits_EU.csv',
39            'JP': 'bluetooth_power_limits_JP.csv'
40        }
41
42        #Backup BT SAR files on the device
43        for key in self.reg_domain_dict.keys():
44            reg_file_path = os.path.join(
45                os.path.dirname(self.power_file_paths[0]),
46                self.reg_domain_dict[key])
47            self.dut.adb.shell('cp {} {}.backup'.format(
48                reg_file_path, reg_file_path))
49
50        self.log.info('Regulatory files backed up')
51
52    def setup_test(self):
53
54        #Reset SAR test result to 0 before every test
55        self.sar_test_result.metric_value = 0
56
57        # Starting BT on the master
58        self.dut.droid.bluetoothFactoryReset()
59        bt_utils.enable_bluetooth(self.dut.droid, self.dut.ed)
60
61    def teardown_class(self):
62        for key in self.reg_domain_dict.keys():
63            reg_file_path = os.path.join(
64                os.path.dirname(self.power_file_paths[0]),
65                self.reg_domain_dict[key])
66            self.dut.adb.shell('mv {}.backup {}'.format(
67                reg_file_path, reg_file_path))
68
69        self.log.info('Regulatory files restored')
70
71        self.dut.reboot()  #TODO: make this better
72        super().teardown_class()
73
74    def test_bt_sar_sanity_check_state(self):
75        """ Test for BT SAR State Sanity
76
77        BT SAR Software Sanity Test to ensure that the correct signal state
78        gets propagated to the firmware. This is done by comparing expected
79        device state with that read from device's logcat
80        """
81        #Iterating through the BT SAR scenarios
82        for scenario in range(0, self.bt_sar_df.shape[0]):
83            # Reading BT SAR table row into dict
84            read_scenario = self.bt_sar_df.loc[scenario].to_dict()
85
86            start_time = self.dut.adb.shell('date +%s.%m')
87            time.sleep(1)
88
89            #Setting SAR state to the read BT SAR row
90            enforced_state = self.set_sar_state(self.dut, read_scenario,
91                                                self.country_code)
92
93            #Reading device state from logcat after forcing SAR State
94            device_state = self.get_current_device_state(self.dut, start_time)
95
96            #Comparing read device state to expected device state
97            for key in enforced_state.keys():
98                key_regex = r'{}:\s*(\d)'.format(key)
99                try:
100                    propagated_value = int(
101                        re.findall(key_regex, device_state)[0])
102                except IndexError:
103                    propagated_value = 'NA'
104
105                if enforced_state[key] == propagated_value:
106                    self.sar_test_result.metric_value = 1
107                    self.log.info(
108                        'scenario: {}, state : {}, forced_value: {}, value:{}'.
109                        format(scenario, key, enforced_state[key],
110                               propagated_value))
111                else:
112                    self.log.error(
113                        'scenario:{}, state : {}, forced_value: {}, value:{}'.
114                        format(scenario, key, enforced_state[key],
115                               propagated_value))
116
117    def test_bt_sar_sanity_check_power(self):
118        """ Test for BT SAR Power Cap Sanity
119
120        BT SAR Power Cap Sanity Test to ensure that the correct SAR power
121        cap corresponding to the forced SAR state gets propagated to the
122        firmware. This is done by comparing expected power cap read from
123        the BT SAR file to the power cap read from logcat
124        """
125
126        power_cap_error = self.sweep_power_cap()
127
128        if power_cap_error:
129            asserts.fail("Power Caps didn't match powers in the SAR table")
130        else:
131            self.sar_test_result.metric_value = 1
132            asserts.explicit_pass('Power Caps were set according to the table')
133
134    def test_bt_sar_sanity_country_code(self):
135        """ Test for BT SAR Country Code Sanity
136
137        BT SAR Country Code Sanity Test to ensure that the correct SAR
138        regulatory domain corresponding to the forced SAR country code gets
139        propagated to the firmware. This is done by comparing forced regulatory
140        domain to regulatory domain read from logcat.
141        """
142
143        error_flag = 0
144        for country_code_tuple in self.REG_DOMAIN_DICT.keys():
145            for country_code in country_code_tuple:
146                start_time = self.dut.adb.shell('date +%s.%m')
147
148                time.sleep(1)
149                #Force country code using adb command
150                self.set_country_code(self.dut, country_code)
151
152                #Read regulatory code from logcat
153                set_regulatory_domain = self.get_country_code(
154                    self.dut, start_time)
155
156                if set_regulatory_domain != self.REG_DOMAIN_DICT[country_code_tuple]:
157                    error_flag = 1
158                    self.log.error(
159                        'Country Code: {} set to regulatory domain: {}'.format(
160                            country_code, set_regulatory_domain))
161                else:
162                    self.log.info(
163                        'Country Code: {} set to regulatory domain: {}'.format(
164                            country_code, set_regulatory_domain))
165
166        if error_flag:
167            asserts.fail(
168                'Regulatory domains not set according to country code')
169        else:
170            self.sar_test_result.metric_value = 1
171            asserts.explicit_pass(
172                'Regulatory domains set according to country code')
173
174    def test_bt_sar_sanity_reg_domain(self):
175        """ Test for BT SAR Regulatory Domain Sanity
176
177        BT SAR Regulatory Domain Sanity Test to ensure that the correct
178        SAR regulatory domain TX powers get propagated to the firmware.
179        This is done by measuring the TX power for different
180        regulatory domain files
181        """
182
183        reg_domain_test_error_flag = True
184        reg_file_phone_path = os.path.dirname(self.sar_file_path)
185
186        #For different reg domain, sweep the sar table
187        for cc, reg_domain in self.REG_DOMAIN_DICT.items():
188            self.country_code = cc[0]
189            for file in self.custom_files:
190                if 'bluetooth_power_limits_{}.csv'.format(reg_domain) in file:
191                    custom_reg_file = file
192                    reg_file_name = os.path.join(
193                        reg_file_phone_path,
194                        'bluetooth_power_limits_{}.csv'.format(reg_domain))
195                    break
196            else:
197                self.log.error(
198                    'Regulatory file for {} missing'.format(reg_domain))
199
200            self.push_table(self.dut, custom_reg_file, reg_file_name)
201
202            start_time = self.dut.adb.shell('date +%s.%m')
203            self.set_country_code(self.dut, cc[0])
204            # Read regulatory code from logcat
205            read_reg_domain = self.get_country_code(self.dut, start_time)
206            self.log.info(
207                'Regulatory domain set to {}'.format(read_reg_domain))
208            self.bt_sar_df = self.read_sar_table(self.dut, custom_reg_file)
209
210            reg_domain_error_flag = self.sweep_power_cap()
211
212            if not reg_domain_error_flag:
213                self.log.info(
214                    'Regulatory Domain Sanity Test for {} passed'.format(
215                        reg_domain))
216
217            reg_domain_test_error_flag &= reg_domain_error_flag
218
219        if reg_domain_test_error_flag:
220            asserts.fail('Regulatory domain sanity tests failed')
221        else:
222            self.sar_test_result.metric_value = 1
223            asserts.explicit_pass('Regulatory domain sanity tests passed')
224