Convert Timeout test to Chrono

Now tests only the Chrono `attach(duration)` method, not the deprecated
`attach` and `attach_us` calls.
pull/12942/head
Kevin Bracey 2020-05-07 17:40:06 +03:00
parent 25fad5d2a3
commit 8a5f58bf55
3 changed files with 56 additions and 107 deletions

View File

@ -37,54 +37,37 @@ utest::v1::status_t greentea_failure_handler(const Case *const source, const fai
} }
Case cases[] = { Case cases[] = {
Case("Callback called once (attach)", test_single_call<AttachTester<LowPowerTimeout> >), Case("Callback called once", test_single_call<LowPowerTimeout>),
Case("Callback called once (attach_us)", test_single_call<AttachUSTester<LowPowerTimeout> >),
Case("Callback not called when cancelled (attach)", test_cancel<AttachTester<LowPowerTimeout> >), Case("Callback not called when cancelled", test_cancel<LowPowerTimeout>),
Case("Callback not called when cancelled (attach_us)", test_cancel<AttachUSTester<LowPowerTimeout> >),
Case("Callback override (attach)", test_override<AttachTester<LowPowerTimeout> >), Case("Callback override", test_override<LowPowerTimeout>),
Case("Callback override (attach_us)", test_override<AttachUSTester<LowPowerTimeout> >),
Case("Multiple timeouts running in parallel (attach)", test_multiple<AttachTester<LowPowerTimeout> >), Case("Multiple timeouts running in parallel", test_multiple<LowPowerTimeout>),
Case("Multiple timeouts running in parallel (attach_us)", test_multiple<AttachUSTester<LowPowerTimeout> >),
Case("Zero delay (attach)", test_no_wait<AttachTester<LowPowerTimeout> >), Case("Zero delay", test_no_wait<LowPowerTimeout>),
Case("Zero delay (attach_us)", test_no_wait<AttachUSTester<LowPowerTimeout> >),
Case("Reschedule in callback (attach)", test_reschedule<AttachTester<LowPowerTimeout> >), Case("Reschedule in callback", test_reschedule<LowPowerTimeout>),
Case("Reschedule in callback (attach_us)", test_reschedule<AttachUSTester<LowPowerTimeout> >),
Case("10 ms delay accuracy (attach)", test_delay_accuracy<AttachTester<LowPowerTimeout>, 10000, SHORT_DELTA_US>, Case("10 ms delay accuracy", test_delay_accuracy<LowPowerTimeout, 10000, SHORT_DELTA_US>,
greentea_failure_handler),
Case("10 ms delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<LowPowerTimeout>, 10000, SHORT_DELTA_US>,
greentea_failure_handler), greentea_failure_handler),
Case("1 s delay accuracy (attach)", test_delay_accuracy<AttachTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>, Case("1 s delay accuracy (attach)", test_delay_accuracy<LowPowerTimeout, 1000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("1 s delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler), greentea_failure_handler),
Case("5 s delay accuracy (attach)", test_delay_accuracy<AttachTester<LowPowerTimeout>, 5000000, LONG_DELTA_US>, Case("5 s delay accuracy (attach)", test_delay_accuracy<LowPowerTimeout, 5000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("5 s delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<LowPowerTimeout>, 5000000, LONG_DELTA_US>,
greentea_failure_handler), greentea_failure_handler),
#if DEVICE_SLEEP #if DEVICE_SLEEP
Case("1 s delay during sleep (attach)", test_sleep<AttachTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>, Case("1 s delay during sleep (attach)", test_sleep<LowPowerTimeout, 1000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("1 s delay during sleep (attach_us)", test_sleep<AttachUSTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler), greentea_failure_handler),
Case("1 s delay during deepsleep (attach)", test_deepsleep<AttachTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>, Case("1 s delay during deepsleep (attach)", test_deepsleep<LowPowerTimeout, 1000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("1 s delay during deepsleep (attach_us)", test_deepsleep<AttachUSTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler), greentea_failure_handler),
#endif #endif
#if !defined(SKIP_TIME_DRIFT_TESTS) #if !defined(SKIP_TIME_DRIFT_TESTS)
Case("Timing drift (attach)", test_drift<AttachTester<LowPowerTimeout> >), Case("Timing drift (attach)", test_drift<LowPowerTimeout>),
Case("Timing drift (attach_us)", test_drift<AttachUSTester<LowPowerTimeout> >),
#endif #endif
}; };

View File

@ -33,49 +33,34 @@ utest::v1::status_t greentea_failure_handler(const Case *const source, const fai
} }
Case cases[] = { Case cases[] = {
Case("Callback called once (attach)", test_single_call<AttachTester<Timeout> >), Case("Callback called once", test_single_call<Timeout>),
Case("Callback called once (attach_us)", test_single_call<AttachUSTester<Timeout> >),
Case("Callback not called when cancelled (attach)", test_cancel<AttachTester<Timeout> >), Case("Callback not called when cancelled", test_cancel<Timeout>),
Case("Callback not called when cancelled (attach_us)", test_cancel<AttachUSTester<Timeout> >),
Case("Callback override (attach)", test_override<AttachTester<Timeout> >), Case("Callback override", test_override<Timeout>),
Case("Callback override (attach_us)", test_override<AttachUSTester<Timeout> >),
Case("Multiple timeouts running in parallel (attach)", test_multiple<AttachTester<Timeout> >), Case("Multiple timeouts running in parallel", test_multiple<Timeout>),
Case("Multiple timeouts running in parallel (attach_us)", test_multiple<AttachUSTester<Timeout> >),
Case("Zero delay (attach)", test_no_wait<AttachTester<Timeout> >), Case("Zero delay", test_no_wait<Timeout>),
Case("Zero delay (attach_us)", test_no_wait<AttachUSTester<Timeout> >),
Case("Reschedule in callback (attach)", test_reschedule<AttachTester<Timeout> >), Case("Reschedule in callback", test_reschedule<Timeout>),
Case("Reschedule in callback (attach_us)", test_reschedule<AttachUSTester<Timeout> >),
Case("10 ms delay accuracy (attach)", test_delay_accuracy<AttachTester<Timeout>, 10000, SHORT_DELTA_US>, Case("10 ms delay accuracy", test_delay_accuracy<Timeout, 10000, SHORT_DELTA_US>,
greentea_failure_handler),
Case("10 ms delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<Timeout>, 10000, SHORT_DELTA_US>,
greentea_failure_handler), greentea_failure_handler),
Case("1 s delay accuracy (attach)", test_delay_accuracy<AttachTester<Timeout>, 1000000, LONG_DELTA_US>, Case("1 s delay accuracy", test_delay_accuracy<Timeout, 1000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("1 s delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<Timeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler), greentea_failure_handler),
Case("5 s delay accuracy (attach)", test_delay_accuracy<AttachTester<Timeout>, 5000000, LONG_DELTA_US>, Case("5 s delay accuracy", test_delay_accuracy<Timeout, 5000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("5 s delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<Timeout>, 5000000, LONG_DELTA_US>,
greentea_failure_handler), greentea_failure_handler),
#if DEVICE_SLEEP #if DEVICE_SLEEP
Case("1 s delay during sleep (attach)", test_sleep<AttachTester<Timeout>, 1000000, LONG_DELTA_US>, Case("1 s delay during sleep", test_sleep<Timeout, 1000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("1 s delay during sleep (attach_us)", test_sleep<AttachUSTester<Timeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler), greentea_failure_handler),
#endif #endif
#if !defined(SKIP_TIME_DRIFT_TESTS) #if !defined(SKIP_TIME_DRIFT_TESTS)
Case("Timing drift (attach)", test_drift<AttachTester<Timeout> >), Case("Timing drift", test_drift<Timeout>),
Case("Timing drift (attach_us)", test_drift<AttachUSTester<Timeout> >),
#endif #endif
}; };

View File

@ -20,12 +20,12 @@
#include "mbed.h" #include "mbed.h"
#include "unity/unity.h" #include "unity/unity.h"
#define NUM_TIMEOUTS 16 using namespace std::chrono;
#define DRIFT_TEST_PERIOD_US 10000
const float TEST_DELAY_S = 0.01; #define NUM_TIMEOUTS 16
const uint32_t TEST_DELAY_MS = 1000.0F * TEST_DELAY_S; const microseconds DRIFT_TEST_PERIOD = 10ms;
const us_timestamp_t TEST_DELAY_US = 1000000.0F * TEST_DELAY_S;
const milliseconds TEST_DELAY = 10ms;
/* Timeouts are quite arbitrary due to large number of boards with varying level of accuracy */ /* Timeouts are quite arbitrary due to large number of boards with varying level of accuracy */
#define LONG_DELTA_US (100000) #define LONG_DELTA_US (100000)
@ -41,24 +41,6 @@ void cnt_callback(volatile uint32_t *cnt)
(*cnt)++; (*cnt)++;
} }
template<typename TimeoutType>
class AttachTester: public TimeoutType {
public:
void attach_callback(Callback<void()> func, us_timestamp_t delay_us)
{
TimeoutType::attach(func, (float) delay_us / 1000000.0f);
}
};
template<typename TimeoutType>
class AttachUSTester: public TimeoutType {
public:
void attach_callback(Callback<void()> func, us_timestamp_t delay_us)
{
TimeoutType::attach_us(func, delay_us);
}
};
/** Template for tests: callback called once /** Template for tests: callback called once
* *
* Test callback called once * Test callback called once
@ -77,15 +59,15 @@ void test_single_call(void)
Semaphore sem(0, 1); Semaphore sem(0, 1);
T timeout; T timeout;
timeout.attach_callback(mbed::callback(sem_callback, &sem), TEST_DELAY_US); timeout.attach(mbed::callback(sem_callback, &sem), TEST_DELAY);
bool acquired = sem.try_acquire(); bool acquired = sem.try_acquire();
TEST_ASSERT_FALSE(acquired); TEST_ASSERT_FALSE(acquired);
acquired = sem.try_acquire_for(TEST_DELAY_MS + 2); acquired = sem.try_acquire_for(TEST_DELAY + 2ms);
TEST_ASSERT_TRUE(acquired); TEST_ASSERT_TRUE(acquired);
acquired = sem.try_acquire_for(TEST_DELAY_MS + 2); acquired = sem.try_acquire_for(TEST_DELAY + 2ms);
TEST_ASSERT_FALSE(acquired); TEST_ASSERT_FALSE(acquired);
timeout.detach(); timeout.detach();
@ -109,13 +91,13 @@ void test_cancel(void)
Semaphore sem(0, 1); Semaphore sem(0, 1);
T timeout; T timeout;
timeout.attach_callback(mbed::callback(sem_callback, &sem), 2.0f * TEST_DELAY_US); timeout.attach(mbed::callback(sem_callback, &sem), 2 * TEST_DELAY);
bool acquired = sem.try_acquire_for(TEST_DELAY_MS); bool acquired = sem.try_acquire_for(TEST_DELAY);
TEST_ASSERT_FALSE(acquired); TEST_ASSERT_FALSE(acquired);
timeout.detach(); timeout.detach();
acquired = sem.try_acquire_for(TEST_DELAY_MS + 2); acquired = sem.try_acquire_for(TEST_DELAY + 2ms);
TEST_ASSERT_FALSE(acquired); TEST_ASSERT_FALSE(acquired);
} }
@ -142,13 +124,13 @@ void test_override(void)
Semaphore sem2(0, 1); Semaphore sem2(0, 1);
T timeout; T timeout;
timeout.attach_callback(mbed::callback(sem_callback, &sem1), 2.0f * TEST_DELAY_US); timeout.attach(mbed::callback(sem_callback, &sem1), 2 * TEST_DELAY);
bool acquired = sem1.try_acquire_for(TEST_DELAY_MS); bool acquired = sem1.try_acquire_for(TEST_DELAY);
TEST_ASSERT_FALSE(acquired); TEST_ASSERT_FALSE(acquired);
timeout.attach_callback(mbed::callback(sem_callback, &sem2), 2.0f * TEST_DELAY_US); timeout.attach(mbed::callback(sem_callback, &sem2), 2 * TEST_DELAY);
acquired = sem2.try_acquire_for(2 * TEST_DELAY_MS + 2); acquired = sem2.try_acquire_for(2 * TEST_DELAY + 2ms);
TEST_ASSERT_TRUE(acquired); TEST_ASSERT_TRUE(acquired);
acquired = sem1.try_acquire(); acquired = sem1.try_acquire();
TEST_ASSERT_FALSE(acquired); TEST_ASSERT_FALSE(acquired);
@ -176,9 +158,9 @@ void test_multiple(void)
volatile uint32_t callback_count = 0; volatile uint32_t callback_count = 0;
T timeouts[NUM_TIMEOUTS]; T timeouts[NUM_TIMEOUTS];
for (size_t i = 0; i < NUM_TIMEOUTS; i++) { for (size_t i = 0; i < NUM_TIMEOUTS; i++) {
timeouts[i].attach_callback(mbed::callback(cnt_callback, &callback_count), TEST_DELAY_US); timeouts[i].attach(mbed::callback(cnt_callback, &callback_count), TEST_DELAY);
} }
ThisThread::sleep_for(TEST_DELAY_MS + 2); ThisThread::sleep_for(TEST_DELAY + 2ms);
TEST_ASSERT_EQUAL(NUM_TIMEOUTS, callback_count); TEST_ASSERT_EQUAL(NUM_TIMEOUTS, callback_count);
} }
@ -200,7 +182,7 @@ void test_no_wait(void)
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
Semaphore sem(0, 1); Semaphore sem(0, 1);
T timeout; T timeout;
timeout.attach_callback(mbed::callback(sem_callback, &sem), 0ULL); timeout.attach(mbed::callback(sem_callback, &sem), 0s);
bool sem_acquired = sem.try_acquire(); bool sem_acquired = sem.try_acquire();
TEST_ASSERT_EQUAL(true, sem_acquired); TEST_ASSERT_EQUAL(true, sem_acquired);
timeout.detach(); timeout.detach();
@ -227,11 +209,11 @@ void test_delay_accuracy(void)
Timer timer; Timer timer;
timer.start(); timer.start();
timeout.attach_callback(mbed::callback(sem_callback, &sem), delay_us); timeout.attach(mbed::callback(sem_callback, &sem), microseconds(delay_us));
sem.acquire(); sem.acquire();
timer.stop(); timer.stop();
TEST_ASSERT_UINT64_WITHIN(delta_us, delay_us, timer.read_high_resolution_us()); TEST_ASSERT_UINT64_WITHIN(delta_us, delay_us, timer.elapsed_time().count());
timeout.detach(); timeout.detach();
} }
@ -262,7 +244,7 @@ void test_sleep(void)
sleep_manager_lock_deep_sleep(); sleep_manager_lock_deep_sleep();
timer.start(); timer.start();
timeout.attach_callback(mbed::callback(sem_callback, &sem), delay_us); timeout.attach(mbed::callback(sem_callback, &sem), microseconds(delay_us));
bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check(); bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
TEST_ASSERT_FALSE_MESSAGE(deep_sleep_allowed, "Deep sleep should be disallowed"); TEST_ASSERT_FALSE_MESSAGE(deep_sleep_allowed, "Deep sleep should be disallowed");
@ -270,7 +252,7 @@ void test_sleep(void)
timer.stop(); timer.stop();
sleep_manager_unlock_deep_sleep(); sleep_manager_unlock_deep_sleep();
TEST_ASSERT_UINT64_WITHIN(delta_us, delay_us, timer.read_high_resolution_us()); TEST_ASSERT_UINT64_WITHIN(delta_us, delay_us, timer.elapsed_time().count());
timeout.detach(); timeout.detach();
} }
@ -316,17 +298,17 @@ void test_deepsleep(void)
* hardware buffers are empty. However, such an API does not exist now, * hardware buffers are empty. However, such an API does not exist now,
* so we'll use the ThisThread::sleep_for() function for now. * so we'll use the ThisThread::sleep_for() function for now.
*/ */
ThisThread::sleep_for(20); ThisThread::sleep_for(20ms);
timer.start(); timer.start();
timeout.attach_callback(mbed::callback(sem_callback, &sem), delay_us); timeout.attach(mbed::callback(sem_callback, &sem), microseconds(delay_us));
bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check(); bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
TEST_ASSERT_TRUE_MESSAGE(deep_sleep_allowed, "Deep sleep should be allowed"); TEST_ASSERT_TRUE_MESSAGE(deep_sleep_allowed, "Deep sleep should be allowed");
sem.acquire(); sem.acquire();
timer.stop(); timer.stop();
TEST_ASSERT_UINT64_WITHIN(delta_us, delay_us, timer.read_high_resolution_us()); TEST_ASSERT_UINT64_WITHIN(delta_us, delay_us, timer.elapsed_time().count());
timeout.detach(); timeout.detach();
} }
@ -336,14 +318,14 @@ void test_deepsleep(void)
template<typename TimeoutTesterType> template<typename TimeoutTesterType>
class TimeoutDriftTester { class TimeoutDriftTester {
public: public:
TimeoutDriftTester(us_timestamp_t period = 1000) : TimeoutDriftTester(microseconds period = 1ms) :
_callback_count(0), _period(period), _timeout() _callback_count(0), _period(period), _timeout()
{ {
} }
void reschedule_callback(void) void reschedule_callback(void)
{ {
_timeout.attach_callback(mbed::callback(this, &TimeoutDriftTester::reschedule_callback), _period); _timeout.attach(mbed::callback(this, &TimeoutDriftTester::reschedule_callback), _period);
_callback_count++; _callback_count++;
} }
@ -359,7 +341,7 @@ public:
private: private:
volatile uint32_t _callback_count; volatile uint32_t _callback_count;
us_timestamp_t _period; microseconds _period;
TimeoutTesterType _timeout; TimeoutTesterType _timeout;
}; };
@ -376,11 +358,10 @@ private:
template<typename T> template<typename T>
void test_reschedule(void) void test_reschedule(void)
{ {
volatile uint32_t callback_count = 0; TimeoutDriftTester<T> timeout(TEST_DELAY);
TimeoutDriftTester<T> timeout;
timeout.reschedule_callback(); timeout.reschedule_callback();
ThisThread::sleep_for(TEST_DELAY_MS * 5); ThisThread::sleep_for(TEST_DELAY * 5);
TEST_ASSERT(timeout.get_callback_count() >= 3); TEST_ASSERT(timeout.get_callback_count() >= 3);
} }
@ -410,7 +391,7 @@ void test_drift(void)
char _key[11] = { }; char _key[11] = { };
char _value[128] = { }; char _value[128] = { };
int expected_key = 1; int expected_key = 1;
TimeoutDriftTester<T> timeout(DRIFT_TEST_PERIOD_US); TimeoutDriftTester<T> timeout(DRIFT_TEST_PERIOD);
greentea_send_kv("timing_drift_check_start", 0); greentea_send_kv("timing_drift_check_start", 0);
timeout.reschedule_callback(); timeout.reschedule_callback();
@ -421,11 +402,11 @@ void test_drift(void)
expected_key = strcmp(_key, "base_time"); expected_key = strcmp(_key, "base_time");
} while (expected_key); } while (expected_key);
greentea_send_kv(_key, timeout.get_callback_count() * DRIFT_TEST_PERIOD_US); greentea_send_kv(_key, timeout.get_callback_count() * DRIFT_TEST_PERIOD.count());
// wait for 2nd signal from host // wait for 2nd signal from host
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
greentea_send_kv(_key, timeout.get_callback_count() * DRIFT_TEST_PERIOD_US); greentea_send_kv(_key, timeout.get_callback_count() * DRIFT_TEST_PERIOD.count());
timeout.detach_callback(); timeout.detach_callback();