-
Notifications
You must be signed in to change notification settings - Fork 3k
LowPowerTimeout tests #5163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
LowPowerTimeout tests #5163
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,25 +15,205 @@ | |
*/ | ||
|
||
#if !DEVICE_LOWPOWERTIMER | ||
#error [NOT_SUPPORTED] Low power timer not supported for this target | ||
#error [NOT_SUPPORTED] Low power timer not supported for this target | ||
#endif | ||
|
||
#include "utest/utest.h" | ||
#include "unity/unity.h" | ||
#include "greentea-client/test_env.h" | ||
|
||
#include "mbed.h" | ||
#include "rtos.h" | ||
|
||
using namespace utest::v1; | ||
|
||
#define NUM_TIMEOUTS 64 | ||
const float TEST_DELAY_S = 0.01; | ||
const uint32_t TEST_DELAY_MS = 1000.0F * TEST_DELAY_S; | ||
const us_timestamp_t TEST_DELAY_US = 1000000.0F * TEST_DELAY_S; | ||
|
||
void sem_callback(Semaphore *sem) | ||
{ | ||
sem->release(); | ||
} | ||
|
||
void cnt_callback(volatile uint32_t *cnt) | ||
{ | ||
(*cnt)++; | ||
} | ||
|
||
class TimeoutAttachUSTester: public LowPowerTimeout { | ||
public: | ||
void attach_callback(Callback<void()> func, us_timestamp_t delay_us) | ||
{ | ||
attach_us(func, delay_us); | ||
} | ||
}; | ||
|
||
class TimeoutAttachTester: public LowPowerTimeout { | ||
public: | ||
void attach_callback(Callback<void()> func, us_timestamp_t delay_us) | ||
{ | ||
attach(func, (float) delay_us / 1000000.0f); | ||
} | ||
}; | ||
|
||
/** Template for tests: callback called once | ||
* | ||
* Test callback called once | ||
* Given a LowPowerTimeout object with a callback attached with @a attach() | ||
* When given time elapses | ||
* Then the callback is called exactly one time | ||
* | ||
* Test callback called once | ||
* Given a LowPowerTimeout object with a callback attached with @a attach_us() | ||
* When given time elapses | ||
* Then the callback is called exactly one time | ||
*/ | ||
template<typename T> | ||
void test_callback_fires_once(void) | ||
{ | ||
Semaphore sem(0, 1); | ||
T timeout; | ||
|
||
timeout.attach_callback(mbed::callback(sem_callback, &sem), TEST_DELAY_US); | ||
|
||
int32_t sem_slots = sem.wait(0); | ||
TEST_ASSERT_EQUAL(0, sem_slots); | ||
|
||
sem_slots = sem.wait(TEST_DELAY_MS + 1); | ||
TEST_ASSERT_EQUAL(1, sem_slots); | ||
|
||
sem_slots = sem.wait(TEST_DELAY_MS + 1); | ||
TEST_ASSERT_EQUAL(0, sem_slots); | ||
|
||
timeout.detach(); | ||
} | ||
|
||
/** Template for tests: callback not called when cancelled | ||
* | ||
* Test callback not called when cancelled | ||
* Given a LowPowerTimeout object with a callback attached with @a attach() | ||
* When the callback is detached before being called | ||
* Then the callback is never called | ||
* | ||
* Test callback not called when cancelled | ||
* Given a LowPowerTimeout object with a callback attached with @a attach_us() | ||
* When the callback is detached before being called | ||
* Then the callback is never called | ||
*/ | ||
template<typename T> | ||
void test_cancel(void) | ||
{ | ||
Semaphore sem(0, 1); | ||
T timeout; | ||
|
||
timeout.attach_callback(mbed::callback(sem_callback, &sem), 2.0f * TEST_DELAY_US); | ||
|
||
int32_t sem_slots = sem.wait(TEST_DELAY_MS); | ||
TEST_ASSERT_EQUAL(0, sem_slots); | ||
timeout.detach(); | ||
|
||
sem_slots = sem.wait(TEST_DELAY_MS + 1); | ||
TEST_ASSERT_EQUAL(0, sem_slots); | ||
} | ||
|
||
/** Template for tests: callback override | ||
* | ||
* Test callback override | ||
* Given a LowPowerTimeout object with a callback attached with @a attach() | ||
* When another callback is attached before first one is called | ||
* and second callback's delay elapses | ||
* Then the second callback is called | ||
* and the first callback is never called | ||
* | ||
* Test callback override | ||
* Given a LowPowerTimeout object with a callback attached with @a attach_us() | ||
* When another callback is attached before first one is called | ||
* and second callback's delay elapses | ||
* Then the second callback is called | ||
* and the first callback is never called | ||
*/ | ||
template<typename T> | ||
void test_override(void) | ||
{ | ||
Semaphore sem1(0, 1); | ||
Semaphore sem2(0, 1); | ||
T timeout; | ||
|
||
timeout.attach_callback(mbed::callback(sem_callback, &sem1), 2.0f * TEST_DELAY_US); | ||
|
||
int32_t sem_slots = sem1.wait(TEST_DELAY_MS); | ||
TEST_ASSERT_EQUAL(0, sem_slots); | ||
timeout.attach_callback(mbed::callback(sem_callback, &sem2), 2.0f * TEST_DELAY_US); | ||
|
||
sem_slots = sem2.wait(2 * TEST_DELAY_MS + 1); | ||
TEST_ASSERT_EQUAL(1, sem_slots); | ||
sem_slots = sem1.wait(0); | ||
TEST_ASSERT_EQUAL(0, sem_slots); | ||
|
||
timeout.detach(); | ||
} | ||
|
||
/** Template for tests: multiple LowPowerTimeouts | ||
* | ||
* Test multiple LowPowerTimeouts | ||
* Given multiple separate LowPowerTimeout objects | ||
* When a callback is attached to all of these LowPowerTimeout objects with @a attach() | ||
* and delay for every LowPowerTimeout elapses | ||
* Then all callbacks are called | ||
* | ||
* Test multiple LowPowerTimeouts | ||
* Given multiple separate LowPowerTimeout objects | ||
* When a callback is attached to all of these LowPowerTimeout objects with @a attach_us() | ||
* and delay for every LowPowerTimeout elapses | ||
* Then all callbacks are called | ||
*/ | ||
template<typename T> | ||
void test_multiple(void) | ||
{ | ||
volatile uint32_t callback_count = 0; | ||
T timeouts[NUM_TIMEOUTS]; | ||
for (size_t i = 0; i < NUM_TIMEOUTS; i++) { | ||
timeouts[i].attach_callback(mbed::callback(cnt_callback, &callback_count), TEST_DELAY_US); | ||
} | ||
Thread::wait(TEST_DELAY_MS + 1); | ||
TEST_ASSERT_EQUAL(NUM_TIMEOUTS, callback_count); | ||
} | ||
|
||
/** Template for tests: zero delay | ||
* | ||
* Test zero delay | ||
* Given a LowPowerTimeout object | ||
* When a callback is attached with 0.0 s delay, with @a attach() | ||
* Then the callback is called instantly | ||
* | ||
* Test zero delay | ||
* Given a LowPowerTimeout object | ||
* When a callback is attached with 0.0 s delay, with @a attach_us() | ||
* Then the callback is called instantly | ||
*/ | ||
template<typename T> | ||
void test_no_wait(void) | ||
{ | ||
Semaphore sem(0, 1); | ||
T timeout; | ||
timeout.attach_callback(mbed::callback(sem_callback, &sem), 0ULL); | ||
|
||
int32_t sem_slots = sem.wait(0); | ||
TEST_ASSERT_EQUAL(1, sem_slots); | ||
timeout.detach(); | ||
} | ||
|
||
volatile static bool complete; | ||
static LowPowerTimeout lpt; | ||
|
||
/* Timeouts are quite arbitrary due to large number of boards with varying level of accuracy */ | ||
#define LONG_TIMEOUT (100000) | ||
#define SHORT_TIMEOUT (600) | ||
|
||
void cb_done() { | ||
void cb_done() | ||
{ | ||
complete = true; | ||
} | ||
|
||
|
@@ -119,29 +299,48 @@ void lp_timeout_500us(void) | |
|
||
} | ||
|
||
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { | ||
utest::v1::status_t greentea_failure_handler(const Case * const source, const failure_t reason) | ||
{ | ||
greentea_case_failure_abort_handler(source, reason); | ||
return STATUS_CONTINUE; | ||
} | ||
|
||
Case cases[] = { | ||
Case("Test callback called once (with attach)", test_callback_fires_once<TimeoutAttachTester>), | ||
Case("Test callback called once (with attach_us)", test_callback_fires_once<TimeoutAttachUSTester>), | ||
|
||
Case("Test callback not called when cancelled (with attach)", test_cancel<TimeoutAttachTester>), | ||
Case("Test callback not called when cancelled (with attach_us)", test_cancel<TimeoutAttachUSTester>), | ||
|
||
Case("Test callback override (with attach)", test_override<TimeoutAttachTester>), | ||
Case("Test callback override (with attach_us)", test_override<TimeoutAttachUSTester>), | ||
|
||
Case("Test multiple timeouts running in parallel (with attach)", test_multiple<TimeoutAttachTester>), | ||
Case("Test multiple timeouts running in parallel (with attach_us)", test_multiple<TimeoutAttachUSTester>), | ||
|
||
Case("Test zero delay (with attach)", test_no_wait<TimeoutAttachTester>), | ||
Case("Test zero delay (with attach_us)", test_no_wait<TimeoutAttachUSTester>), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These tests fail on NUCLEO_F070RB, NUCLEO_F429ZI and NUCLEO_L476RG -- issue #5159. |
||
|
||
Case("500us LowPowerTimeout", lp_timeout_500us, greentea_failure_handler), | ||
Case("1ms LowPowerTimeout", lp_timeout_1ms, greentea_failure_handler), | ||
Case("1sec LowPowerTimeout", lp_timeout_1s, greentea_failure_handler), | ||
Case("5sec LowPowerTimeout", lp_timeout_5s, greentea_failure_handler), | ||
|
||
#if DEVICE_SLEEP | ||
Case("1sec LowPowerTimeout from sleep", lp_timeout_1s_sleep, greentea_failure_handler), | ||
Case("1sec LowPowerTimeout from deepsleep", lp_timeout_1s_deepsleep, greentea_failure_handler), | ||
#endif /* DEVICE_SLEEP */ | ||
}; | ||
|
||
utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { | ||
utest::v1::status_t greentea_test_setup(const size_t number_of_cases) | ||
{ | ||
GREENTEA_SETUP(20, "default_auto"); | ||
return greentea_test_setup_handler(number_of_cases); | ||
} | ||
|
||
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); | ||
|
||
int main() { | ||
int main() | ||
{ | ||
Harness::run(specification); | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two tests with multiple
LowPowerTimeout
objects fail on K64F, NUCLEO_F070RB, NUCLEO_L476RG. Waiting for the outcome of #5150.