• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3#   Copyright 2020 - 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 time
19import glob
20import errno
21
22from acts import utils
23from acts import asserts
24from acts import signals
25from acts import base_test
26from pandas import DataFrame
27from collections import namedtuple
28from acts.controllers.spectracom_lib import gsg6
29from acts.test_utils.gnss import dut_log_test_utils as diaglog
30from acts_contrib.test_utils.gnss import gnss_test_utils as gutils
31from acts_contrib.test_utils.gnss import gnss_testlog_utils as glogutils
32
33DEVICE_GPSLOG_FOLDER = '/sdcard/Android/data/com.android.gpstool/files/'
34GPS_PKG_NAME = 'com.android.gpstool'
35
36class LabTtffTest(base_test.BaseTestClass):
37
38    """ LAB TTFF Tests"""
39    GTW_GPSTOOL_APP = 'gtw_gpstool_apk'
40    SPECTRACOM_IP_KEY = 'spectracom_ip'
41    SPECTRACOM_PORT_KEY = 'spectracom_port'
42    SPECTRACOM_FILES_KEY = 'spectracom_files'
43    SPECTRACOM_POWER_KEY = 'spectracom_power_level'
44    SPIRENT_IP_KEY = 'spirent_ip'
45    SPIRENT_SCENARIO = 'sprient_scenario'
46    CUSTOM_FILES_KEY = 'custom_files'
47    CSTTFF_CRITERIA = 'cs_criteria'
48    HSTTFF_CRITERIA = 'hs_criteria'
49    WSTTFF_CRITERIA = 'ws_criteria'
50    CSTTFF_PECRITERIA = 'cs_ttff_pecriteria'
51    HSTTFF_PECRITERIA = 'hs_ttff_pecriteria'
52    WSTTFF_PECRITERIA = 'ws_ttff_pecriteria'
53    TTFF_ITERATION = 'ttff_iteration'
54    SIMULATOR_LOCATION = 'simulator_location'
55    DIAG_OPTION = 'diag_option'
56
57    def __init__(self, controllers):
58        """ Initializes class attributes. """
59
60        super().__init__(controllers)
61
62        self.dut = None
63        self.spectracom = None
64
65    def setup_class(self):
66        super().setup_class()
67
68        req_params = [
69            self.SPECTRACOM_IP_KEY, self.SPECTRACOM_PORT_KEY,
70            self.SPECTRACOM_FILES_KEY, self.SPECTRACOM_POWER_KEY,
71            self.CSTTFF_CRITERIA, self.HSTTFF_CRITERIA,
72            self.WSTTFF_CRITERIA, self.TTFF_ITERATION,
73            self.SIMULATOR_LOCATION, self.DIAG_OPTION
74        ]
75
76        for param in req_params:
77            if param not in self.user_params:
78                self.log.error('Required parameter {} is missing in config '
79                               'file.'.format(param))
80                raise signals.TestAbortClass(
81                    'Required parameter {} is missing in config '
82                               'file.'.format(param))
83        self.dut = self.android_devices[0]
84        self.spectracom_ip = self.user_params[self.SPECTRACOM_IP_KEY]
85        self.spectracom_port = self.user_params[self.SPECTRACOM_PORT_KEY]
86        self.spectracom_file = self.user_params[self.SPECTRACOM_FILES_KEY]
87        self.spectracom_power = self.user_params[self.SPECTRACOM_POWER_KEY]
88        self.gtw_gpstool_app = self.user_params[self.GTW_GPSTOOL_APP]
89        custom_files = self.user_params.get(self.CUSTOM_FILES_KEY, [])
90        self.cs_ttff_criteria = self.user_params.get(self.CSTTFF_CRITERIA, [])
91        self.hs_ttff_criteria = self.user_params.get(self.HSTTFF_CRITERIA, [])
92        self.ws_ttff_criteria = self.user_params.get(self.WSTTFF_CRITERIA, [])
93        self.cs_ttff_pecriteria = self.user_params.get(
94            self.CSTTFF_PECRITERIA, [])
95        self.hs_ttff_pecriteria = self.user_params.get(
96            self.HSTTFF_PECRITERIA, [])
97        self.ws_ttff_pecriteria = self.user_params.get(
98            self.WSTTFF_PECRITERIA, [])
99        self.ttff_iteration = self.user_params.get(self.TTFF_ITERATION, [])
100        self.simulator_location = self.user_params.get(
101            self.SIMULATOR_LOCATION, [])
102	self.diag_option = self.user_params.get(self.DIAG_OPTION, [])
103
104        test_type = namedtuple('Type', ['command', 'criteria'])
105        self.test_types = {
106            'cs': test_type('Cold Start', self.cs_ttff_criteria),
107            'ws': test_type('Warm Start', self.ws_ttff_criteria),
108            'hs': test_type('Hot Start', self.hs_ttff_criteria)
109        }
110
111        # Unpack the rockbottom script or fail class setup if it can't be found
112        for file in custom_files:
113            if 'rockbottom_' + self.dut.model in file:
114                self.rockbottom_script = file
115                break
116        else:
117            raise signals.TestAbortClass(
118                'Required rockbottom script is missing.')
119
120    def setup_test(self):
121
122	self.clear_gps_log()
123        self.spectracom = gsg6.GSG6(self.spectracom_ip, self.spectracom_port)
124
125        self.spectracom.stop_scenario()
126        time.sleep(10)
127        self.spectracom.close()
128
129        self.dut_rockbottom()
130        utils.set_location_service(self.dut, True)
131        gutils.reinstall_package_apk(self.dut, GPS_PKG_NAME,
132                                     self.gtw_gpstool_app)
133        self.spectracom = gsg6.GSG6(self.spectracom_ip, self.spectracom_port)
134        self.spectracom.connect()
135
136    def dut_rockbottom(self):
137        """
138        Set the dut to rockbottom state
139
140        """
141        # The rockbottom script might include a device reboot, so it is
142        # necessary to stop SL4A during its execution.
143        self.dut.stop_services()
144        self.log.info('Executing rockbottom script for ' + self.dut.model)
145        os.chmod(self.rockbottom_script, 0o777)
146        os.system('{} {}'.format(self.rockbottom_script, self.dut.serial))
147        # Make sure the DUT is in root mode after coming back
148        self.dut.root_adb()
149        # Restart SL4A
150        self.dut.start_services()
151
152    def teardown_class(self):
153        """ Executed after completing all selected test cases."""
154        self.clear_gps_log()
155        if self.spectracom:
156            self.spectracom.stop_scenario()
157            time.sleep(10)
158            self.spectracom.close()
159
160    def start_and_set_spectracom_power(self):
161        """
162        Start spectracom secnario and set power level.
163
164        """
165
166        self.spectracom.start_scenario(self.spectracom_file)
167        time.sleep(25)
168        self.spectracom.set_power(self.spectracom_power)
169
170    def get_and_verify_ttff(self, mode):
171        """Retrieve ttff with designate mode.
172
173            Args:
174                mode: A string for identify gnss test mode.
175        """
176        if mode not in self.test_types:
177            raise signals.TestError('Unrecognized mode %s' % mode)
178        test_type = self.test_types.get(mode)
179
180        gutils.process_gnss_by_gtw_gpstool(self.dut,
181                                           self.test_types['cs'].criteria)
182        begin_time = gutils.get_current_epoch_time()
183        gutils.start_ttff_by_gtw_gpstool(
184            self.dut, ttff_mode=mode,
185            iteration=self.ttff_iteration, aid_data=True)
186        ttff_data = gutils.process_ttff_by_gtw_gpstool(self.dut, begin_time,
187                                                       self.simulator_location)
188
189        gps_log_path = os.path.join(self.log_path, 'GPSLogs')
190        self.dut.adb.pull("{} {}".format(DEVICE_GPSLOG_FOLDER, gps_log_path))
191
192        gps_api_log = glob.glob(gps_log_path + '/GPS_API_*.txt')
193        ttff_loop_log = glob.glob(gps_log_path + '/GPS_{}_*.txt'.
194                                  format(mode.upper()))
195
196        if not gps_api_log and ttff_loop_log:
197            raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
198                                    gps_log_path)
199
200        df = DataFrame(glogutils.parse_gpstool_ttfflog_to_df(gps_api_log[0]))
201
202        ttff_dict = {}
203        for i in ttff_data:
204            d = ttff_data[i]._asdict()
205            ttff_dict[i] = dict(d)
206
207        ttff_time =[]
208        ttff_pe = []
209        for i, k in ttff_dict.items():
210            ttff_time.append(ttff_dict[i]['ttff_time'])
211            ttff_pe.append(ttff_dict[i]['ttff_pe'])
212        df['ttff_time'] = ttff_time
213        df['ttff_pe'] = ttff_pe
214        df.to_json(gps_log_path + '/gps_log.json', orient='table')
215        result = gutils.check_ttff_data(
216            self.dut,
217            ttff_data,
218            ttff_mode=test_type.command,
219            criteria=test_type.criteria)
220        if not result:
221            raise signals.TestFailure('%s TTFF fails to reach '
222                                      'designated criteria'
223                                      % test_type.command)
224        return ttff_data
225
226    def verify_pe(self, mode):
227        """
228        Verify ttff Position Error with designate mode.
229
230        Args:
231             mode: A string for identify gnss test mode.
232        """
233
234        ffpe_type = namedtuple('Type', ['command', 'pecriteria'])
235        ffpe_types = {
236            'cs': ffpe_type('Cold Start', self.cs_ttff_pecriteria),
237            'ws': ffpe_type('Warm Start', self.ws_ttff_pecriteria),
238            'hs': ffpe_type('Hot Start', self.hs_ttff_pecriteria)
239        }
240
241        if mode not in self.test_types:
242            raise signals.TestError('Unrecognized mode %s' % mode)
243        test_type = self.test_types.get(mode)
244
245        ttff_data = self.get_and_verify_ttff(mode)
246        result = gutils.check_ttff_pe(
247            self.dut,
248            ttff_data,
249            ttff_mode=test_type.command,
250            pecriteria=test_type.pecriteria
251        )
252        if not result:
253            raise signals.TestFailure('%s TTFF fails to reach '
254                                      'designated criteria'
255                                      % test_type.command)
256        return ttff_data
257
258    def clear_gps_log(self):
259        """
260        Delete the existing GPS GTW Log from DUT.
261
262        """
263        self.dut.adb.shell("rm -rf {}".format(DEVICE_GPSLOG_FOLDER))
264
265    def test_gnss_cold_ttff_ffpe(self):
266
267        self.start_and_set_spectracom_power()
268        if self.diag_option is "QCOM":
269                diaglog.start_diagmdlog_background(self.dut, maskfile=self.maskfile)
270        else:
271                #start_tbdlog() yet to add for Broadcom
272                pass
273	self.verify_pe('cs')
274        diaglog.stop_background_diagmdlog(self.dut, self.qxdm_log_path, keep_logs=False)
275
276    def test_gnss_warm_ttff_ffpe(self):
277
278        self.start_and_set_spectracom_power()
279	if self.diag_option is "QCOM":
280	        diaglog.start_diagmdlog_background(self.dut, maskfile=self.maskfile)
281	else:
282		#start_tbdlog() yet to add for Broadcom
283		pass
284        self.verify_pe('ws')
285        diaglog.stop_background_diagmdlog(self.dut, self.qxdm_log_path, keep_logs=False)
286
287    def test_gnss_hot_ttff_ffpe(self):
288
289        self.start_and_set_spectracom_power()
290        if self.diag_option is "QCOM":
291                diaglog.start_diagmdlog_background(self.dut, maskfile=self.maskfile)
292        else:
293                #start_tbdlog() yet to add for Broadcom
294                pass
295        self.verify_pe('hs')
296        diaglog.stop_background_diagmdlog(self.dut, self.qxdm_log_path, keep_logs=False)
297
298