309 lines
14 KiB
Python
309 lines
14 KiB
Python
|
|
#!/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 time
|
||
|
|
import statistics
|
||
|
|
|
||
|
|
from acts import asserts
|
||
|
|
from acts import signals
|
||
|
|
from acts.base_test import BaseTestClass
|
||
|
|
from acts_contrib.test_utils.gnss.testtracker_util import log_testtracker_uuid
|
||
|
|
from acts_contrib.test_utils.gnss import gnss_test_utils as gutils
|
||
|
|
from acts_contrib.test_utils.tel import tel_logging_utils as tutils
|
||
|
|
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
|
||
|
|
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
|
||
|
|
from acts.utils import get_current_epoch_time
|
||
|
|
from acts_contrib.test_utils.gnss.gnss_test_utils import delete_lto_file, pair_to_wearable
|
||
|
|
from acts_contrib.test_utils.gnss.gnss_test_utils import process_gnss_by_gtw_gpstool
|
||
|
|
from acts_contrib.test_utils.gnss.gnss_test_utils import start_gnss_by_gtw_gpstool
|
||
|
|
from acts_contrib.test_utils.gnss.gnss_test_utils import check_tracking_file
|
||
|
|
from uiautomator import Device
|
||
|
|
|
||
|
|
|
||
|
|
class GnssWearableTetherFunctionTest(BaseTestClass):
|
||
|
|
""" GNSS Wearable Tether Function Tests"""
|
||
|
|
def setup_class(self):
|
||
|
|
super().setup_class()
|
||
|
|
self.watch = self.android_devices[0]
|
||
|
|
self.phone = self.android_devices[1]
|
||
|
|
self.phone.uia = Device(self.phone.serial)
|
||
|
|
req_params = ["pixel_lab_network", "standalone_cs_criteria",
|
||
|
|
"flp_ttff_max_threshold", "pixel_lab_location",
|
||
|
|
"flp_ttff_cycle", "default_gnss_signal_attenuation",
|
||
|
|
"flp_waiting_time", "tracking_test_time",
|
||
|
|
"far_start_criteria", "ttff_test_cycle"]
|
||
|
|
self.unpack_userparams(req_param_names=req_params)
|
||
|
|
# create hashmap for SSID
|
||
|
|
self.ssid_map = {}
|
||
|
|
for network in self.pixel_lab_network:
|
||
|
|
SSID = network["SSID"]
|
||
|
|
self.ssid_map[SSID] = network
|
||
|
|
self.ttff_mode = {"cs": "Cold Start",
|
||
|
|
"ws": "Warm Start",
|
||
|
|
"hs": "Hot Start"}
|
||
|
|
gutils._init_device(self.watch)
|
||
|
|
pair_to_wearable(self.watch, self.phone)
|
||
|
|
|
||
|
|
def teardown_class(self):
|
||
|
|
super().teardown_class()
|
||
|
|
gutils.reboot(self.phone)
|
||
|
|
|
||
|
|
def setup_test(self):
|
||
|
|
gutils.log_current_epoch_time(self.watch, "test_start_time")
|
||
|
|
log_testtracker_uuid(self.watch, self.current_test_name)
|
||
|
|
gutils.get_baseband_and_gms_version(self.watch)
|
||
|
|
gutils.clear_logd_gnss_qxdm_log(self.watch)
|
||
|
|
gutils.clear_logd_gnss_qxdm_log(self.phone)
|
||
|
|
gutils.set_attenuator_gnss_signal(self.watch, self.attenuators,
|
||
|
|
self.default_gnss_signal_attenuation)
|
||
|
|
if not verify_internet_connection(self.watch.log, self.watch, retries=5,
|
||
|
|
expected_state=True):
|
||
|
|
time.sleep(60)
|
||
|
|
if not verify_internet_connection(self.watch.log, self.watch, retries=3,
|
||
|
|
expected_state=True):
|
||
|
|
raise signals.TestFailure("Fail to connect to LTE network.")
|
||
|
|
|
||
|
|
def teardown_test(self):
|
||
|
|
gutils.stop_pixel_logger(self.watch)
|
||
|
|
tutils.stop_adb_tcpdump(self.watch)
|
||
|
|
gutils.set_attenuator_gnss_signal(self.watch, self.attenuators,
|
||
|
|
self.default_gnss_signal_attenuation)
|
||
|
|
if self.watch.droid.connectivityCheckAirplaneMode():
|
||
|
|
self.watch.log.info("Force airplane mode off")
|
||
|
|
toggle_airplane_mode(self.watch.log, self.watch, new_state=False)
|
||
|
|
gutils.log_current_epoch_time(self.watch, "test_end_time")
|
||
|
|
|
||
|
|
def on_fail(self, test_name, begin_time):
|
||
|
|
self.watch.take_bug_report(test_name, begin_time)
|
||
|
|
gutils.get_gnss_qxdm_log(self.watch)
|
||
|
|
tutils.get_tcpdump_log(self.watch, test_name, begin_time)
|
||
|
|
|
||
|
|
def start_qxdm_and_tcpdump_log(self):
|
||
|
|
"""Start QXDM and adb tcpdump if collect_logs is True."""
|
||
|
|
gutils.start_pixel_logger(self.watch)
|
||
|
|
tutils.start_adb_tcpdump(self.watch)
|
||
|
|
|
||
|
|
def flp_ttff(self, mode, criteria, location):
|
||
|
|
self.start_qxdm_and_tcpdump_log()
|
||
|
|
start_gnss_by_gtw_gpstool(self.phone, True, api_type="FLP")
|
||
|
|
time.sleep(self.flp_waiting_time)
|
||
|
|
self.watch.unlock_screen(password=None)
|
||
|
|
begin_time = get_current_epoch_time()
|
||
|
|
process_gnss_by_gtw_gpstool(
|
||
|
|
self.watch, self.standalone_cs_criteria, api_type="flp")
|
||
|
|
gutils.start_ttff_by_gtw_gpstool(
|
||
|
|
self.watch, mode, iteration=self.flp_ttff_cycle)
|
||
|
|
results = gutils.process_ttff_by_gtw_gpstool(
|
||
|
|
self.watch, begin_time, location, api_type="flp")
|
||
|
|
gutils.check_ttff_data(self.watch, results, mode, criteria)
|
||
|
|
self.check_location_from_phone()
|
||
|
|
start_gnss_by_gtw_gpstool(self.phone, False, api_type="FLP")
|
||
|
|
|
||
|
|
def check_location_from_phone(self):
|
||
|
|
watch_file = check_tracking_file(self.watch)
|
||
|
|
phone_file = check_tracking_file(self.phone)
|
||
|
|
return gutils.compare_watch_phone_location(self, watch_file, phone_file)
|
||
|
|
|
||
|
|
def run_ttff_via_gtw_gpstool(self, mode, criteria):
|
||
|
|
"""Run GNSS TTFF test with selected mode and parse the results.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
mode: "cs", "ws" or "hs"
|
||
|
|
criteria: Criteria for the TTFF.
|
||
|
|
"""
|
||
|
|
begin_time = get_current_epoch_time()
|
||
|
|
gutils.process_gnss_by_gtw_gpstool(self.watch, self.standalone_cs_criteria, clear_data=False)
|
||
|
|
gutils.start_ttff_by_gtw_gpstool(self.watch, mode, self.ttff_test_cycle)
|
||
|
|
ttff_data = gutils.process_ttff_by_gtw_gpstool(
|
||
|
|
self.watch, begin_time, self.pixel_lab_location)
|
||
|
|
result = gutils.check_ttff_data(
|
||
|
|
self.watch, ttff_data, self.ttff_mode.get(mode), criteria)
|
||
|
|
asserts.assert_true(
|
||
|
|
result, "TTFF %s fails to reach designated criteria of %d "
|
||
|
|
"seconds." % (self.ttff_mode.get(mode), criteria))
|
||
|
|
|
||
|
|
""" Test Cases """
|
||
|
|
def test_flp_ttff_cs(self):
|
||
|
|
"""Verify FLP TTFF Cold Start while tether with phone.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Pair with phone via Bluetooth.
|
||
|
|
2. FLP TTFF Cold Start for 10 iteration.
|
||
|
|
3. Check location source is from Phone.
|
||
|
|
|
||
|
|
Expected Results:
|
||
|
|
1. FLP TTFF Cold Start results should be within
|
||
|
|
flp_ttff_max_threshold.
|
||
|
|
2. Watch uses phone's FLP location.
|
||
|
|
"""
|
||
|
|
self.flp_ttff("cs", self.flp_ttff_max_threshold, self.pixel_lab_location)
|
||
|
|
|
||
|
|
def test_flp_ttff_ws(self):
|
||
|
|
"""Verify FLP TTFF Warm Start while tether with phone.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Pair with phone via Bluetooth.
|
||
|
|
2. FLP TTFF Warm Start for 10 iteration.
|
||
|
|
3. Check location source is from Phone.
|
||
|
|
|
||
|
|
Expected Results:
|
||
|
|
1. FLP TTFF Warm Start results should be within
|
||
|
|
flp_ttff_max_threshold.
|
||
|
|
2. Watch uses phone's FLP location.
|
||
|
|
"""
|
||
|
|
self.flp_ttff("ws", self.flp_ttff_max_threshold, self.pixel_lab_location)
|
||
|
|
|
||
|
|
def test_flp_ttff_hs(self):
|
||
|
|
"""Verify FLP TTFF Hot Start while tether with phone.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Pair with phone via Bluetooth.
|
||
|
|
2. FLP TTFF Hot Start for 10 iteration.
|
||
|
|
3. Check location source is from Phone.
|
||
|
|
|
||
|
|
Expected Results:
|
||
|
|
1. FLP TTFF Hot Start results should be within
|
||
|
|
flp_ttff_max_threshold.
|
||
|
|
2. Watch uses phone's FLP location.
|
||
|
|
"""
|
||
|
|
self.flp_ttff("hs", self.flp_ttff_max_threshold, self.pixel_lab_location)
|
||
|
|
|
||
|
|
def test_tracking_during_bt_disconnect_resume(self):
|
||
|
|
"""Verify tracking is correct during Bluetooth disconnect and resume.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Make sure watch Bluetooth is on and in paired status.
|
||
|
|
2. Do 1 min tracking.
|
||
|
|
3. After 1 min tracking, check location source is using phone's FLP.
|
||
|
|
4. Turn off watch Bluetooth, and do 1 min tracking.
|
||
|
|
5. After 1 min tracking, check tracking results.
|
||
|
|
6. Repeat Step 1 to Step 5 for 5 times.
|
||
|
|
|
||
|
|
Expected Results:
|
||
|
|
1. Watch uses phone's FLP location in Bluetooth connect state.
|
||
|
|
2. Tracking results should be within pixel_lab_location criteria.
|
||
|
|
"""
|
||
|
|
self.start_qxdm_and_tcpdump_log()
|
||
|
|
for i in range(1, 4):
|
||
|
|
if not self.watch.droid.bluetoothCheckState():
|
||
|
|
self.watch.droid.bluetoothToggleState(True)
|
||
|
|
self.watch.log.info("Turn Bluetooth on")
|
||
|
|
self.watch.log.info("Wait 40s for Bluetooth auto re-connect")
|
||
|
|
time.sleep(40)
|
||
|
|
if not gutils.is_bluetooth_connected(self.watch, self.phone):
|
||
|
|
raise signals.TestFailure("Fail to connect to device via Bluetooth.")
|
||
|
|
start_gnss_by_gtw_gpstool(self.phone, True, api_type="FLP")
|
||
|
|
time.sleep(self.flp_waiting_time)
|
||
|
|
start_gnss_by_gtw_gpstool(self.watch, True, api_type="FLP")
|
||
|
|
time.sleep(self.flp_waiting_time)
|
||
|
|
self.watch.log.info("Wait 1 min for tracking")
|
||
|
|
time.sleep(self.tracking_test_time)
|
||
|
|
if not self.check_location_from_phone():
|
||
|
|
raise signals.TestFailure("Watch is not using phone location")
|
||
|
|
self.watch.droid.bluetoothToggleState(False)
|
||
|
|
self.watch.log.info("Turn off Watch Bluetooth")
|
||
|
|
self.watch.log.info("Wait 1 min for tracking")
|
||
|
|
time.sleep(self.tracking_test_time)
|
||
|
|
if self.check_location_from_phone():
|
||
|
|
raise signals.TestError("Watch should not use phone location")
|
||
|
|
gutils.parse_gtw_gpstool_log(self.watch, self.pixel_lab_location, api_type="FLP")
|
||
|
|
start_gnss_by_gtw_gpstool(self.phone, False, api_type="FLP")
|
||
|
|
|
||
|
|
def test_oobe_first_fix(self):
|
||
|
|
"""Verify first fix after OOBE pairing within the criteria
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Pair watch to phone during OOBE.
|
||
|
|
2. Ensure LTO file download in watch.
|
||
|
|
3. Ensure UTC time inject in watch.
|
||
|
|
4. Enable AirPlane mode to untether to phone.
|
||
|
|
5. Open GPSTool to get first fix in LTO and UTC time injected.
|
||
|
|
6. Repeat Step1 ~ Step5 for 5 times.
|
||
|
|
|
||
|
|
Expected Results:
|
||
|
|
1. First fix should be within far_start_threshold.
|
||
|
|
"""
|
||
|
|
oobe_results_all = []
|
||
|
|
for i in range(1,4):
|
||
|
|
self.watch.log.info("First fix after OOBE pairing - attempts %s" % i)
|
||
|
|
pair_to_wearable(self.watch, self.phone)
|
||
|
|
self.start_qxdm_and_tcpdump_log()
|
||
|
|
begin_time = get_current_epoch_time()
|
||
|
|
gutils.check_xtra_download(self.watch, begin_time)
|
||
|
|
gutils.check_inject_time(self.watch)
|
||
|
|
self.watch.log.info("Turn airplane mode on")
|
||
|
|
# self.watch.droid.connectivityToggleAirplaneMode(True)
|
||
|
|
toggle_airplane_mode(self.watch.log, self.watch, new_state=True)
|
||
|
|
oobe_results = gutils.process_gnss(
|
||
|
|
self.watch, self.far_start_criteria, clear_data=False)
|
||
|
|
oobe_results_all.append(oobe_results)
|
||
|
|
self.watch.log.info(f"TestResult Max_OOBE_First_Fix {max(oobe_results_all)}")
|
||
|
|
self.watch.log.info(f"TestResult Avg_OOBE_First_Fix {statistics.mean(oobe_results_all)}")
|
||
|
|
# self.watch.droid.connectivityToggleAirplaneMode(False)
|
||
|
|
toggle_airplane_mode(self.watch.log, self.watch, new_state=False)
|
||
|
|
self.watch.log.info("Turn airplane mode off")
|
||
|
|
|
||
|
|
def test_oobe_first_fix_with_network_connection(self):
|
||
|
|
"""Verify first fix after OOBE pairing within the criteria
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Pair watch to phone during OOBE.
|
||
|
|
2. Ensure LTO file download in watch.
|
||
|
|
3. Ensure UTC time inject in watch.
|
||
|
|
4. Turn off Bluetooth to untether to phone.
|
||
|
|
5. Open GPSTool to get first fix in LTO and UTC time injected.
|
||
|
|
6. Repeat Step1 ~ Step5 for 5 times.
|
||
|
|
|
||
|
|
Expected Results:
|
||
|
|
1. First fix should be within far_start_threshold.
|
||
|
|
"""
|
||
|
|
oobe_results_all = []
|
||
|
|
for i in range(1,4):
|
||
|
|
self.watch.log.info("First fix after OOBE pairing - attempts %s" % i)
|
||
|
|
pair_to_wearable(self.watch, self.phone)
|
||
|
|
self.start_qxdm_and_tcpdump_log()
|
||
|
|
begin_time = get_current_epoch_time()
|
||
|
|
gutils.check_xtra_download(self.watch, begin_time)
|
||
|
|
gutils.check_inject_time(self.watch)
|
||
|
|
self.watch.log.info("Turn off Bluetooth to disconnect to phone")
|
||
|
|
self.watch.droid.bluetoothToggleState(False)
|
||
|
|
oobe_results = gutils.process_gnss(
|
||
|
|
self.watch, self.far_start_criteria, clear_data=False)
|
||
|
|
oobe_results_all.append(oobe_results)
|
||
|
|
self.watch.log.info(f"TestResult Max_OOBE_First_Fix {max(oobe_results_all)}")
|
||
|
|
self.watch.log.info(f"TestResult Avg_OOBE_First_Fix {statistics.mean(oobe_results_all)}")
|
||
|
|
|
||
|
|
def test_far_start_ttff(self):
|
||
|
|
"""Verify Far Start (Warm Start v4) TTFF within the criteria
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Pair watch to phone during OOBE.
|
||
|
|
2. Ensure LTO file download in watch.
|
||
|
|
3. Ensure UTC time inject in watch.
|
||
|
|
4. Enable AirPlane mode to untether to phone.
|
||
|
|
5. TTFF Warm Start for 10 iteration.
|
||
|
|
|
||
|
|
Expected Results:
|
||
|
|
1. TTFF should be within far_start_threshold.
|
||
|
|
"""
|
||
|
|
pair_to_wearable(self.watch, self.phone)
|
||
|
|
self.start_qxdm_and_tcpdump_log()
|
||
|
|
begin_time = get_current_epoch_time()
|
||
|
|
gutils.check_xtra_download(self.watch, begin_time)
|
||
|
|
gutils.check_inject_time(self.watch)
|
||
|
|
self.watch.log.info("Turn airplane mode on")
|
||
|
|
toggle_airplane_mode(self.watch.log, self.watch, new_state=True)
|
||
|
|
self.run_ttff_via_gtw_gpstool("ws", self.far_start_criteria)
|