Greentea: Remove deprecated APIs and use chrono

References to time should do so using std::chrono. We reworked tests in
connectivity and drivers to use std::chrono and new APIs in order to
remove deprecation warnings resulting from deprecated API calls.
This required addition of  a macro for test assertions using std::chrono
values.

As host test "timing_drift_auto" expects time values represented as an
integral number of microseconds, we explicitly provide this in place
using "microseconds{TICKER_TIME}.count()" in the relevant ticker tests.
We recognise this is ugly, but thought it best to descriptively convert
from std::chrono to the host test's required representation.

Co-authored-by: Hari Limaye <hari.limaye@arm.com>
pull/14941/head
harmut01 2021-03-19 15:25:55 +00:00 committed by Hari Limaye
parent bfe24ce64d
commit 86c2d70a5b
3 changed files with 84 additions and 113 deletions

View File

@ -37,8 +37,9 @@
using namespace utest::v1;
using mbed::callback;
using namespace std::chrono_literals;
#define INITIALIZATION_TIMEOUT (10 * 1000)
#define INITIALIZATION_TIMEOUT 10000ms
static EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE);
@ -72,7 +73,7 @@ static void test_stack_initialization()
BLE &ble = BLE::Instance();
ble.onEventsToProcess(process_ble_events);
ble.init(on_initialization_complete);
event_queue.dispatch(INITIALIZATION_TIMEOUT);
event_queue.dispatch_for(INITIALIZATION_TIMEOUT);
// At this point ble is suppose to be initialized; inspect the various state
// of the stack.

View File

@ -25,20 +25,31 @@
#else
using utest::v1::Case;
using namespace std::chrono;
static const int test_timeout = 10;
#define TEST_ASSERT_EQUAL_DURATION(expected, actual) \
do { \
using ct = std::common_type_t<decltype(expected), decltype(actual)>; \
TEST_ASSERT_EQUAL(ct(expected).count(), ct(actual).count()); \
} while (0)
#define TEST_ASSERT_DURATION_WITHIN(delta, expected, actual) \
do { \
using ct = std::common_type_t<decltype(delta), decltype(expected), decltype(actual)>; \
TEST_ASSERT_INT_WITHIN(ct(delta).count(), ct(expected).count(), ct(actual).count()); \
} while (0)
#define TICKER_COUNT 16
#define MULTI_TICKER_TIME_MS 100
#define MULTI_TICKER_TIME 100ms
/* Due to poor accuracy of LowPowerTicker on many platforms
there is no sense to tune tolerance value as it was in Ticker tests.
Tolerance value is set to 600us for measurement inaccuracy + 5% tolerance
for LowPowerTicker. */
#define TOLERANCE_US(DELAY) (600 + DELAY / 20)
#define TOLERANCE(DELAY) (600us + DELAY / 20)
static const int test_timeout = 10;
volatile uint32_t ticker_callback_flag;
volatile uint32_t multi_counter;
Timer gtimer;
@ -73,14 +84,14 @@ void increment_multi_counter(void)
void test_multi_ticker(void)
{
LowPowerTicker ticker[TICKER_COUNT];
const uint32_t extra_wait = 10; // extra 10ms wait time
const milliseconds extra_wait = 10ms; // extra 10ms wait time
multi_counter = 0;
for (int i = 0; i < TICKER_COUNT; i++) {
ticker[i].attach_us(callback(increment_multi_counter), MULTI_TICKER_TIME_MS * 1000);
ticker[i].attach(callback(increment_multi_counter), MULTI_TICKER_TIME);
}
ThisThread::sleep_for(MULTI_TICKER_TIME_MS + extra_wait);
ThisThread::sleep_for(MULTI_TICKER_TIME + extra_wait);
TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter);
for (int i = 0; i < TICKER_COUNT; i++) {
@ -93,10 +104,10 @@ void test_multi_ticker(void)
multi_counter = 0;
for (int i = 0; i < TICKER_COUNT; i++) {
ticker[i].attach_us(callback(increment_multi_counter), (MULTI_TICKER_TIME_MS + i) * 1000);
ticker[i].attach(callback(increment_multi_counter), MULTI_TICKER_TIME + milliseconds{i});
}
ThisThread::sleep_for(MULTI_TICKER_TIME_MS + TICKER_COUNT + extra_wait);
ThisThread::sleep_for(MULTI_TICKER_TIME + milliseconds{TICKER_COUNT} + extra_wait);
TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter);
for (int i = 0; i < TICKER_COUNT; i++) {
@ -117,7 +128,6 @@ void test_multi_ticker(void)
void test_multi_call_time(void)
{
LowPowerTicker ticker;
int time_diff;
const int attach_count = 10;
for (int i = 0; i < attach_count; i++) {
@ -125,11 +135,11 @@ void test_multi_call_time(void)
gtimer.reset();
gtimer.start();
ticker.attach_us(callback(stop_gtimer_set_flag), MULTI_TICKER_TIME_MS * 1000);
ticker.attach(callback(stop_gtimer_set_flag), MULTI_TICKER_TIME);
while (!ticker_callback_flag);
time_diff = gtimer.read_us();
const auto time_diff = gtimer.elapsed_time();
TEST_ASSERT_UINT32_WITHIN(TOLERANCE_US(MULTI_TICKER_TIME_MS * 1000), MULTI_TICKER_TIME_MS * 1000, time_diff);
TEST_ASSERT_DURATION_WITHIN(TOLERANCE(MULTI_TICKER_TIME), MULTI_TICKER_TIME, time_diff);
}
}
@ -142,20 +152,16 @@ void test_multi_call_time(void)
void test_detach(void)
{
LowPowerTicker ticker;
bool ret;
const float ticker_time_s = 0.1f;
const uint32_t wait_time_ms = 500;
Semaphore sem(0, 1);
ticker.attach(callback(sem_release, &sem), ticker_time_s);
ticker.attach(callback(sem_release, &sem), 100ms);
sem.acquire();
sem.acquire();
ticker.detach(); /* cancel */
ret = sem.try_acquire_for(wait_time_ms);
TEST_ASSERT_FALSE(ret);
TEST_ASSERT_FALSE(sem.try_acquire_for(500ms));
}
/** Test single callback time via attach
@ -164,54 +170,29 @@ void test_detach(void)
When callback attached with time interval specified
Then ticker properly executes callback within a specified time interval
*/
template<us_timestamp_t DELAY_US>
template<typename Duration, uint64_t DELAY>
void test_attach_time(void)
{
LowPowerTicker ticker;
ticker_callback_flag = 0;
const auto delay = Duration{DELAY};
gtimer.reset();
gtimer.start();
ticker.attach(callback(stop_gtimer_set_flag), ((float)DELAY_US) / 1000000.0f);
ticker.attach(callback(stop_gtimer_set_flag), delay);
while (!ticker_callback_flag);
ticker.detach();
const int time_diff = gtimer.read_us();
const auto time_diff = gtimer.elapsed_time();
TEST_ASSERT_UINT64_WITHIN(TOLERANCE_US(DELAY_US), DELAY_US, time_diff);
}
/** Test single callback time via attach_us
Given a Ticker
When callback attached with time interval specified
Then ticker properly executes callback within a specified time interval
*/
template<us_timestamp_t DELAY_US>
void test_attach_us_time(void)
{
LowPowerTicker ticker;
ticker_callback_flag = 0;
gtimer.reset();
gtimer.start();
ticker.attach_us(callback(stop_gtimer_set_flag), DELAY_US);
while (!ticker_callback_flag);
ticker.detach();
const int time_diff = gtimer.read_us();
TEST_ASSERT_UINT64_WITHIN(TOLERANCE_US(DELAY_US), DELAY_US, time_diff);
TEST_ASSERT_DURATION_WITHIN(TOLERANCE(delay), delay, time_diff);
}
// Test cases
Case cases[] = {
Case("Test attach for 0.001s and time measure", test_attach_time<1000>),
Case("Test attach_us for 1ms and time measure", test_attach_us_time<1000>),
Case("Test attach for 0.01s and time measure", test_attach_time<10000>),
Case("Test attach_us for 10ms and time measure", test_attach_us_time<10000>),
Case("Test attach for 0.1s and time measure", test_attach_time<100000>),
Case("Test attach_us for 100ms and time measure", test_attach_us_time<100000>),
Case("Test attach for 0.5s and time measure", test_attach_time<500000>),
Case("Test attach_us for 500ms and time measure", test_attach_us_time<500000>),
Case("Test attach for 1ms and time measure", test_attach_time<milliseconds, 1>),
Case("Test attach for 10ms and time measure", test_attach_time<milliseconds, 10>),
Case("Test attach for 100ms and time measure", test_attach_time<milliseconds, 100>),
Case("Test attach for 500ms and time measure", test_attach_time<milliseconds, 500>),
Case("Test detach", test_detach),
Case("Test multi call and time measure", test_multi_call_time),
Case("Test multi ticker", test_multi_ticker),

View File

@ -25,15 +25,31 @@
using utest::v1::Case;
#define ONE_MILLI_SEC 1000
using namespace std::chrono;
#define TEST_ASSERT_EQUAL_DURATION(expected, actual) \
do { \
using ct = std::common_type_t<decltype(expected), decltype(actual)>; \
TEST_ASSERT_EQUAL(ct(expected).count(), ct(actual).count()); \
} while (0)
#define TEST_ASSERT_DURATION_WITHIN(delta, expected, actual) \
do { \
using ct = std::common_type_t<decltype(delta), decltype(expected), decltype(actual)>; \
TEST_ASSERT_INT_WITHIN(ct(delta).count(), ct(expected).count(), ct(actual).count()); \
} while (0)
#define TICKER_TIME 1ms
#define DOUBLE_TICKER_TIME 2ms
#define MULTI_TICKER_TIME 100ms
#define TICKER_COUNT 16
#define MULTI_TICKER_TIME_MS 100
volatile uint32_t callback_trigger_count = 0;
static const int test_timeout = 240;
/* Tolerance is quite arbitrary due to large number of boards with varying level of accuracy */
#define TOLERANCE_US 1000
#define TOLERANCE 1000us
volatile uint32_t ticker_callback_flag;
volatile uint32_t multi_counter;
@ -89,18 +105,18 @@ void test_case_1x_ticker()
callback_trigger_count = 0;
greentea_send_kv("timing_drift_check_start", 0);
ticker.attach_us(&ticker_callback_1, ONE_MILLI_SEC);
ticker.attach(&ticker_callback_1, TICKER_TIME);
// wait for 1st signal from host
do {
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
expected_key = strcmp(_key, "base_time");
} while (expected_key);
greentea_send_kv(_key, callback_trigger_count * ONE_MILLI_SEC);
greentea_send_kv(_key, callback_trigger_count * microseconds{TICKER_TIME}.count());
// wait for 2nd signal from host
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
greentea_send_kv(_key, callback_trigger_count * ONE_MILLI_SEC);
greentea_send_kv(_key, callback_trigger_count * microseconds{TICKER_TIME}.count());
//get the results from host
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
@ -127,22 +143,22 @@ void test_case_2x_ticker()
callback_trigger_count = 0;
ticker1.attach_us(ticker_callback_1, 2 * ONE_MILLI_SEC);
ticker1.attach(ticker_callback_1, DOUBLE_TICKER_TIME);
// delay second ticker to have a pair of tickers tick every one millisecond
wait_us(ONE_MILLI_SEC);
ThisThread::sleep_for(TICKER_TIME);
greentea_send_kv("timing_drift_check_start", 0);
ticker2.attach_us(ticker_callback_2, 2 * ONE_MILLI_SEC);
ticker2.attach(ticker_callback_2, DOUBLE_TICKER_TIME);
// wait for 1st signal from host
do {
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
expected_key = strcmp(_key, "base_time");
} while (expected_key);
greentea_send_kv(_key, callback_trigger_count * ONE_MILLI_SEC);
greentea_send_kv(_key, callback_trigger_count * microseconds{TICKER_TIME}.count());
// wait for 2nd signal from host
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
greentea_send_kv(_key, callback_trigger_count * ONE_MILLI_SEC);
greentea_send_kv(_key, callback_trigger_count * microseconds{TICKER_TIME}.count());
//get the results from host
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
@ -161,14 +177,14 @@ void test_case_2x_ticker()
void test_multi_ticker(void)
{
Ticker ticker[TICKER_COUNT];
const uint32_t extra_wait = 5; // extra 5ms wait time
const milliseconds extra_wait = 5ms; // extra 5ms wait time
multi_counter = 0;
for (int i = 0; i < TICKER_COUNT; i++) {
ticker[i].attach_us(callback(increment_multi_counter), MULTI_TICKER_TIME_MS * 1000);
ticker[i].attach(callback(increment_multi_counter), MULTI_TICKER_TIME);
}
ThisThread::sleep_for(MULTI_TICKER_TIME_MS + extra_wait);
ThisThread::sleep_for(MULTI_TICKER_TIME + extra_wait);
TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter);
for (int i = 0; i < TICKER_COUNT; i++) {
@ -181,10 +197,10 @@ void test_multi_ticker(void)
multi_counter = 0;
for (int i = 0; i < TICKER_COUNT; i++) {
ticker[i].attach_us(callback(increment_multi_counter), (MULTI_TICKER_TIME_MS + i) * 1000);
ticker[i].attach(callback(increment_multi_counter), MULTI_TICKER_TIME + milliseconds{i});
}
ThisThread::sleep_for(MULTI_TICKER_TIME_MS + TICKER_COUNT + extra_wait);
ThisThread::sleep_for(MULTI_TICKER_TIME + milliseconds{TICKER_COUNT} + extra_wait);
TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter);
for (int i = 0; i < TICKER_COUNT; i++) {
@ -205,7 +221,6 @@ void test_multi_ticker(void)
void test_multi_call_time(void)
{
Ticker ticker;
int time_diff;
const int attach_count = 10;
for (int i = 0; i < attach_count; i++) {
@ -213,11 +228,11 @@ void test_multi_call_time(void)
gtimer.reset();
gtimer.start();
ticker.attach_us(callback(stop_gtimer_set_flag), MULTI_TICKER_TIME_MS * 1000);
ticker.attach(callback(stop_gtimer_set_flag), MULTI_TICKER_TIME);
while (!ticker_callback_flag);
time_diff = gtimer.read_us();
const auto time_diff = gtimer.elapsed_time();
TEST_ASSERT_UINT32_WITHIN(TOLERANCE_US, MULTI_TICKER_TIME_MS * 1000, time_diff);
TEST_ASSERT_DURATION_WITHIN(TOLERANCE, MULTI_TICKER_TIME, time_diff);
}
}
@ -230,20 +245,18 @@ void test_multi_call_time(void)
void test_detach(void)
{
Ticker ticker;
bool ret;
const float ticker_time_s = 0.1f;
const uint32_t wait_time_ms = 500;
const milliseconds ticker_time = 100ms;
const milliseconds wait_time = 500ms;
Semaphore sem(0, 1);
ticker.attach(callback(sem_release, &sem), ticker_time_s);
ticker.attach(callback(sem_release, &sem), ticker_time);
sem.acquire();
sem.acquire();
ticker.detach(); /* cancel */
ret = sem.try_acquire_for(wait_time_ms);
TEST_ASSERT_FALSE(ret);
TEST_ASSERT_FALSE(sem.try_acquire_for(wait_time));
}
/** Test single callback time via attach
@ -252,53 +265,29 @@ void test_detach(void)
When callback attached with time interval specified
Then ticker properly executes callback within a specified time interval
*/
template<us_timestamp_t DELAY_US>
template<typename Duration, uint64_t DELAY>
void test_attach_time(void)
{
Ticker ticker;
ticker_callback_flag = 0;
const auto delay = Duration{DELAY};
gtimer.reset();
gtimer.start();
ticker.attach(callback(stop_gtimer_set_flag), ((float)DELAY_US) / 1000000.0f);
ticker.attach(callback(stop_gtimer_set_flag), delay);
while (!ticker_callback_flag);
ticker.detach();
const int time_diff = gtimer.read_us();
const auto time_diff = gtimer.elapsed_time();
TEST_ASSERT_UINT64_WITHIN(TOLERANCE_US, DELAY_US, time_diff);
}
/** Test single callback time via attach_us
Given a Ticker
When callback attached with time interval specified
Then ticker properly executes callback within a specified time interval
*/
template<us_timestamp_t DELAY_US>
void test_attach_us_time(void)
{
Ticker ticker;
ticker_callback_flag = 0;
gtimer.reset();
gtimer.start();
ticker.attach_us(callback(stop_gtimer_set_flag), DELAY_US);
while (!ticker_callback_flag);
ticker.detach();
const int time_diff = gtimer.read_us();
TEST_ASSERT_UINT64_WITHIN(TOLERANCE_US, DELAY_US, time_diff);
TEST_ASSERT_DURATION_WITHIN(TOLERANCE, delay, time_diff);
}
// Test cases
Case cases[] = {
Case("Test attach for 0.01s and time measure", test_attach_time<10000>),
Case("Test attach_us for 10ms and time measure", test_attach_us_time<10000>),
Case("Test attach for 0.1s and time measure", test_attach_time<100000>),
Case("Test attach_us for 100ms and time measure", test_attach_us_time<100000>),
Case("Test attach for 0.5s and time measure", test_attach_time<500000>),
Case("Test attach_us for 500ms and time measure", test_attach_us_time<500000>),
Case("Test attach for 10ms and time measure", test_attach_time<milliseconds, 10>),
Case("Test attach for 100ms and time measure", test_attach_time<milliseconds, 100>),
Case("Test attach for 500ms and time measure", test_attach_time<milliseconds, 500>),
Case("Test detach", test_detach),
Case("Test multi call and time measure", test_multi_call_time),
Case("Test multi ticker", test_multi_ticker),