blob: 5c05fa9f81bff82d118d60daacaad914c585f340 [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright 2020 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import time
import glob
import errno
from acts import utils
from acts import asserts
from acts import signals
from acts import base_test
from pandas import DataFrame
from collections import namedtuple
from acts.controllers.spectracom_lib import gsg6
from acts.test_utils.gnss import dut_log_test_utils as diaglog
from acts_contrib.test_utils.gnss import gnss_test_utils as gutils
from acts_contrib.test_utils.gnss import gnss_testlog_utils as glogutils
DEVICE_GPSLOG_FOLDER = '/sdcard/Android/data/com.android.gpstool/files/'
GPS_PKG_NAME = 'com.android.gpstool'
class LabTtffTest(base_test.BaseTestClass):
""" LAB TTFF Tests"""
GTW_GPSTOOL_APP = 'gtw_gpstool_apk'
SPECTRACOM_IP_KEY = 'spectracom_ip'
SPECTRACOM_PORT_KEY = 'spectracom_port'
SPECTRACOM_FILES_KEY = 'spectracom_files'
SPECTRACOM_POWER_KEY = 'spectracom_power_level'
SPIRENT_IP_KEY = 'spirent_ip'
SPIRENT_SCENARIO = 'sprient_scenario'
CUSTOM_FILES_KEY = 'custom_files'
CSTTFF_CRITERIA = 'cs_criteria'
HSTTFF_CRITERIA = 'hs_criteria'
WSTTFF_CRITERIA = 'ws_criteria'
CSTTFF_PECRITERIA = 'cs_ttff_pecriteria'
HSTTFF_PECRITERIA = 'hs_ttff_pecriteria'
WSTTFF_PECRITERIA = 'ws_ttff_pecriteria'
TTFF_ITERATION = 'ttff_iteration'
SIMULATOR_LOCATION = 'simulator_location'
DIAG_OPTION = 'diag_option'
def __init__(self, controllers):
""" Initializes class attributes. """
super().__init__(controllers)
self.dut = None
self.spectracom = None
def setup_class(self):
super().setup_class()
req_params = [
self.SPECTRACOM_IP_KEY, self.SPECTRACOM_PORT_KEY,
self.SPECTRACOM_FILES_KEY, self.SPECTRACOM_POWER_KEY,
self.CSTTFF_CRITERIA, self.HSTTFF_CRITERIA,
self.WSTTFF_CRITERIA, self.TTFF_ITERATION,
self.SIMULATOR_LOCATION, self.DIAG_OPTION
]
for param in req_params:
if param not in self.user_params:
self.log.error('Required parameter {} is missing in config '
'file.'.format(param))
raise signals.TestAbortClass(
'Required parameter {} is missing in config '
'file.'.format(param))
self.dut = self.android_devices[0]
self.spectracom_ip = self.user_params[self.SPECTRACOM_IP_KEY]
self.spectracom_port = self.user_params[self.SPECTRACOM_PORT_KEY]
self.spectracom_file = self.user_params[self.SPECTRACOM_FILES_KEY]
self.spectracom_power = self.user_params[self.SPECTRACOM_POWER_KEY]
self.gtw_gpstool_app = self.user_params[self.GTW_GPSTOOL_APP]
custom_files = self.user_params.get(self.CUSTOM_FILES_KEY, [])
self.cs_ttff_criteria = self.user_params.get(self.CSTTFF_CRITERIA, [])
self.hs_ttff_criteria = self.user_params.get(self.HSTTFF_CRITERIA, [])
self.ws_ttff_criteria = self.user_params.get(self.WSTTFF_CRITERIA, [])
self.cs_ttff_pecriteria = self.user_params.get(
self.CSTTFF_PECRITERIA, [])
self.hs_ttff_pecriteria = self.user_params.get(
self.HSTTFF_PECRITERIA, [])
self.ws_ttff_pecriteria = self.user_params.get(
self.WSTTFF_PECRITERIA, [])
self.ttff_iteration = self.user_params.get(self.TTFF_ITERATION, [])
self.simulator_location = self.user_params.get(
self.SIMULATOR_LOCATION, [])
self.diag_option = self.user_params.get(self.DIAG_OPTION, [])
test_type = namedtuple('Type', ['command', 'criteria'])
self.test_types = {
'cs': test_type('Cold Start', self.cs_ttff_criteria),
'ws': test_type('Warm Start', self.ws_ttff_criteria),
'hs': test_type('Hot Start', self.hs_ttff_criteria)
}
# Unpack the rockbottom script or fail class setup if it can't be found
for file in custom_files:
if 'rockbottom_' + self.dut.model in file:
self.rockbottom_script = file
break
else:
raise signals.TestAbortClass(
'Required rockbottom script is missing.')
def setup_test(self):
self.clear_gps_log()
self.spectracom = gsg6.GSG6(self.spectracom_ip, self.spectracom_port)
self.spectracom.stop_scenario()
time.sleep(10)
self.spectracom.close()
self.dut_rockbottom()
utils.set_location_service(self.dut, True)
gutils.reinstall_package_apk(self.dut, GPS_PKG_NAME,
self.gtw_gpstool_app)
self.spectracom = gsg6.GSG6(self.spectracom_ip, self.spectracom_port)
self.spectracom.connect()
def dut_rockbottom(self):
"""
Set the dut to rockbottom state
"""
# The rockbottom script might include a device reboot, so it is
# necessary to stop SL4A during its execution.
self.dut.stop_services()
self.log.info('Executing rockbottom script for ' + self.dut.model)
os.chmod(self.rockbottom_script, 0o777)
os.system('{} {}'.format(self.rockbottom_script, self.dut.serial))
# Make sure the DUT is in root mode after coming back
self.dut.root_adb()
# Restart SL4A
self.dut.start_services()
def teardown_class(self):
""" Executed after completing all selected test cases."""
self.clear_gps_log()
if self.spectracom:
self.spectracom.stop_scenario()
time.sleep(10)
self.spectracom.close()
def start_and_set_spectracom_power(self):
"""
Start spectracom secnario and set power level.
"""
self.spectracom.start_scenario(self.spectracom_file)
time.sleep(25)
self.spectracom.set_power(self.spectracom_power)
def get_and_verify_ttff(self, mode):
"""Retrieve ttff with designate mode.
Args:
mode: A string for identify gnss test mode.
"""
if mode not in self.test_types:
raise signals.TestError('Unrecognized mode %s' % mode)
test_type = self.test_types.get(mode)
gutils.process_gnss_by_gtw_gpstool(self.dut,
self.test_types['cs'].criteria)
begin_time = gutils.get_current_epoch_time()
gutils.start_ttff_by_gtw_gpstool(
self.dut, ttff_mode=mode,
iteration=self.ttff_iteration, aid_data=True)
ttff_data = gutils.process_ttff_by_gtw_gpstool(self.dut, begin_time,
self.simulator_location)
gps_log_path = os.path.join(self.log_path, 'GPSLogs')
self.dut.adb.pull("{} {}".format(DEVICE_GPSLOG_FOLDER, gps_log_path))
gps_api_log = glob.glob(gps_log_path + '/GPS_API_*.txt')
ttff_loop_log = glob.glob(gps_log_path + '/GPS_{}_*.txt'.
format(mode.upper()))
if not gps_api_log and ttff_loop_log:
raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
gps_log_path)
df = DataFrame(glogutils.parse_gpstool_ttfflog_to_df(gps_api_log[0]))
ttff_dict = {}
for i in ttff_data:
d = ttff_data[i]._asdict()
ttff_dict[i] = dict(d)
ttff_time =[]
ttff_pe = []
for i, k in ttff_dict.items():
ttff_time.append(ttff_dict[i]['ttff_time'])
ttff_pe.append(ttff_dict[i]['ttff_pe'])
df['ttff_time'] = ttff_time
df['ttff_pe'] = ttff_pe
df.to_json(gps_log_path + '/gps_log.json', orient='table')
result = gutils.check_ttff_data(
self.dut,
ttff_data,
ttff_mode=test_type.command,
criteria=test_type.criteria)
if not result:
raise signals.TestFailure('%s TTFF fails to reach '
'designated criteria'
% test_type.command)
return ttff_data
def verify_pe(self, mode):
"""
Verify ttff Position Error with designate mode.
Args:
mode: A string for identify gnss test mode.
"""
ffpe_type = namedtuple('Type', ['command', 'pecriteria'])
ffpe_types = {
'cs': ffpe_type('Cold Start', self.cs_ttff_pecriteria),
'ws': ffpe_type('Warm Start', self.ws_ttff_pecriteria),
'hs': ffpe_type('Hot Start', self.hs_ttff_pecriteria)
}
if mode not in self.test_types:
raise signals.TestError('Unrecognized mode %s' % mode)
test_type = self.test_types.get(mode)
ttff_data = self.get_and_verify_ttff(mode)
result = gutils.check_ttff_pe(
self.dut,
ttff_data,
ttff_mode=test_type.command,
pecriteria=test_type.pecriteria
)
if not result:
raise signals.TestFailure('%s TTFF fails to reach '
'designated criteria'
% test_type.command)
return ttff_data
def clear_gps_log(self):
"""
Delete the existing GPS GTW Log from DUT.
"""
self.dut.adb.shell("rm -rf {}".format(DEVICE_GPSLOG_FOLDER))
def test_gnss_cold_ttff_ffpe(self):
self.start_and_set_spectracom_power()
if self.diag_option is "QCOM":
diaglog.start_diagmdlog_background(self.dut, maskfile=self.maskfile)
else:
#start_tbdlog() yet to add for Broadcom
pass
self.verify_pe('cs')
diaglog.stop_background_diagmdlog(self.dut, self.qxdm_log_path, keep_logs=False)
def test_gnss_warm_ttff_ffpe(self):
self.start_and_set_spectracom_power()
if self.diag_option is "QCOM":
diaglog.start_diagmdlog_background(self.dut, maskfile=self.maskfile)
else:
#start_tbdlog() yet to add for Broadcom
pass
self.verify_pe('ws')
diaglog.stop_background_diagmdlog(self.dut, self.qxdm_log_path, keep_logs=False)
def test_gnss_hot_ttff_ffpe(self):
self.start_and_set_spectracom_power()
if self.diag_option is "QCOM":
diaglog.start_diagmdlog_background(self.dut, maskfile=self.maskfile)
else:
#start_tbdlog() yet to add for Broadcom
pass
self.verify_pe('hs')
diaglog.stop_background_diagmdlog(self.dut, self.qxdm_log_path, keep_logs=False)