From 0bacd5b8e1daa2c0e721d4f956b4b667258dd717 Mon Sep 17 00:00:00 2001 From: Qinghao Shi Date: Tue, 28 Jul 2020 14:15:51 +0100 Subject: [PATCH 1/2] TESTS: update test with explicit skip message --- TESTS/mbed_hal/common_tickers_freq/main.cpp | 10 +++++++--- rtos/tests/TESTS/mbedmicro-rtos-mbed/basic/main.cpp | 8 ++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/TESTS/mbed_hal/common_tickers_freq/main.cpp b/TESTS/mbed_hal/common_tickers_freq/main.cpp index 28fa61d67f..fb4a88652f 100644 --- a/TESTS/mbed_hal/common_tickers_freq/main.cpp +++ b/TESTS/mbed_hal/common_tickers_freq/main.cpp @@ -29,10 +29,14 @@ #include "hal/lp_ticker_api.h" #include "hal/mbed_lp_ticker_wrapper.h" -#if defined(SKIP_TIME_DRIFT_TESTS) || !DEVICE_USTICKER -#error [NOT_SUPPORTED] test not supported +#if !DEVICE_USTICKER +#error [NOT_SUPPORTED] UsTicker need to be enabled for this test #else +#if defined(SKIP_TIME_DRIFT_TESTS) +#error [NOT_SUPPORTED] timing accuracy tests skipped +#endif // defined(SKIP_TIME_DRIFT_TESTS) + #define US_PER_S 1000000 using namespace utest::v1; @@ -208,4 +212,4 @@ int main() Harness::run(specification); } -#endif // defined(SKIP_TIME_DRIFT_TESTS) || !DEVICE_USTICKER +#endif // !DEVICE_USTICKER diff --git a/rtos/tests/TESTS/mbedmicro-rtos-mbed/basic/main.cpp b/rtos/tests/TESTS/mbedmicro-rtos-mbed/basic/main.cpp index a405ca7011..48839f0e4a 100644 --- a/rtos/tests/TESTS/mbedmicro-rtos-mbed/basic/main.cpp +++ b/rtos/tests/TESTS/mbedmicro-rtos-mbed/basic/main.cpp @@ -23,10 +23,14 @@ #include "utest/utest.h" #include "unity/unity.h" -#if defined(SKIP_TIME_DRIFT_TESTS) || !DEVICE_USTICKER +#if !DEVICE_USTICKER #error [NOT_SUPPORTED] UsTicker need to be enabled for this test. #else +#if defined(SKIP_TIME_DRIFT_TESTS) +#error [NOT_SUPPORTED] timing accuracy tests skipped +#endif // defined(SKIP_TIME_DRIFT_TESTS + using utest::v1::Case; using std::milli; using std::micro; @@ -122,5 +126,5 @@ int main() utest::v1::Harness::run(specification); } -#endif // defined(SKIP_TIME_DRIFT_TESTS) || !DEVICE_USTICKER +#endif // !DEVICE_USTICKER #endif // defined(MBED_RTOS_SINGLE_THREAD) || !defined(MBED_CONF_RTOS_PRESENT) From fe8e51fde2cd2c263c6681ee8cf3c9d80416175c Mon Sep 17 00:00:00 2001 From: Qinghao Shi Date: Tue, 28 Jul 2020 14:16:56 +0100 Subject: [PATCH 2/2] TESTS: fix timing drift test in rtos folder --- .../TESTS/host_tests/timing_drift_auto.py | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 rtos/tests/TESTS/host_tests/timing_drift_auto.py diff --git a/rtos/tests/TESTS/host_tests/timing_drift_auto.py b/rtos/tests/TESTS/host_tests/timing_drift_auto.py new file mode 100644 index 0000000000..65ac90a160 --- /dev/null +++ b/rtos/tests/TESTS/host_tests/timing_drift_auto.py @@ -0,0 +1,136 @@ +""" +mbed SDK +Copyright (c) 2011-2013 ARM Limited +SPDX-License-Identifier: Apache-2.0 + +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. +""" + +from mbed_host_tests import BaseHostTest +import time + + +class TimingDriftSync(BaseHostTest): + """ + This works as master-slave fashion + 1) Device says its booted up and ready to run the test, wait for host to respond + 2) Host sends the message to get the device current time i.e base time + + # + # * + # * | + #<---* DUT<- base_time | - round_trip_base_time ------ + # * | | + # * - | + # - | + # | | + # | | + # | - measurement_stretch | - nominal_time + # | | + # | | + # - | + # * - | + # * | | + #<---* DUT <-final_time | - round_trip_final_time------ + # * | + # * - + # + # + # As we increase the measurement_stretch, the error because of transport delay diminishes. + # The values of measurement_stretch is propotional to round_trip_base_time(transport delays) + # by factor time_measurement_multiplier.This multiplier is used is 80 to tolerate 2 sec of + # transport delay and test time ~ 180 secs + # + # Failure in timing can occur if we are ticking too fast or we are ticking too slow, hence we have + # min_range and max_range. if we cross on either side tests would be marked fail. The range is a function of + # tolerance/acceptable drift currently its 5%. + # + + """ + __result = None + mega = 1000000.0 + max_measurement_time = 180 + + # this value is obtained for measurements when there is 0 transport delay and we want accurancy of 5% + time_measurement_multiplier = 80 + + def _callback_timing_drift_check_start(self, key, value, timestamp): + self.round_trip_base_start = timestamp + self.send_kv("base_time", 0) + + def _callback_base_time(self, key, value, timestamp): + self.round_trip_base_end = timestamp + self.device_time_base = float(value) + self.round_trip_base_time = self.round_trip_base_end - self.round_trip_base_start + + self.log("Device base time {}".format(value)) + measurement_stretch = (self.round_trip_base_time * self.time_measurement_multiplier) + 5 + + if measurement_stretch > self.max_measurement_time: + self.log("Time required {} to determine device timer is too high due to transport delay, skipping".format(measurement_stretch)) + else: + self.log("sleeping for {} to measure drift accurately".format(measurement_stretch)) + time.sleep(measurement_stretch) + self.round_trip_final_start = time.time() + self.send_kv("final_time", 0) + + def _callback_final_time(self, key, value, timestamp): + self.round_trip_final_end = timestamp + self.device_time_final = float(value) + self.round_trip_final_time = self.round_trip_final_end - self.round_trip_final_start + self.log("Device final time {} ".format(value)) + + # compute the test results and send to device + results = "pass" if self.compute_parameter() else "fail" + self.send_kv(results, "0") + + def setup(self): + self.register_callback('timing_drift_check_start', self._callback_timing_drift_check_start) + self.register_callback('base_time', self._callback_base_time) + self.register_callback('final_time', self._callback_final_time) + + def compute_parameter(self, failure_criteria=0.05): + t_max = self.round_trip_final_end - self.round_trip_base_start + t_min = self.round_trip_final_start - self.round_trip_base_end + t_max_hi = t_max * (1 + failure_criteria) + t_max_lo = t_max * (1 - failure_criteria) + t_min_hi = t_min * (1 + failure_criteria) + t_min_lo = t_min * (1 - failure_criteria) + device_time = (self.device_time_final - self.device_time_base) / self.mega + + self.log("Compute host events") + self.log("Transport delay 0: {}".format(self.round_trip_base_time)) + self.log("Transport delay 1: {}".format(self.round_trip_final_time)) + self.log("DUT base time : {}".format(self.device_time_base)) + self.log("DUT end time : {}".format(self.device_time_final)) + + self.log("min_pass : {} , max_pass : {} for {}%%".format(t_max_lo, t_min_hi, failure_criteria * 100)) + self.log("min_inconclusive : {} , max_inconclusive : {}".format(t_min_lo, t_max_hi)) + self.log("Time reported by device: {}".format(device_time)) + + if t_max_lo <= device_time <= t_min_hi: + self.log("Test passed !!!") + self.__result = True + elif t_min_lo <= device_time <= t_max_hi: + self.log("Test inconclusive due to transport delay, retrying") + self.__result = False + else: + self.log("Time outside of passing range. Timing drift seems to be present !!!") + self.__result = False + return self.__result + + def result(self): + return self.__result + + def teardown(self): + pass