Merge pull request #12816 from rajkan01/semaphore_greentea_test

Baremetal: Enable Semaphore greentea test
pull/12841/head
Martin Kojtal 2020-04-21 09:51:07 +02:00 committed by GitHub
commit b9ab2d2f25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 117 additions and 20 deletions

View File

@ -14,10 +14,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#if defined(MBED_RTOS_SINGLE_THREAD) || !defined(MBED_CONF_RTOS_PRESENT)
#error [NOT_SUPPORTED] Semaphore test cases require RTOS with multithread to run
#else
#if !DEVICE_USTICKER #if !DEVICE_USTICKER
#error [NOT_SUPPORTED] UsTicker need to be enabled for this test. #error [NOT_SUPPORTED] UsTicker need to be enabled for this test.
#else #else
@ -30,6 +26,12 @@
using namespace utest::v1; using namespace utest::v1;
struct test_data {
Semaphore *sem;
uint32_t data;
};
#if defined(MBED_CONF_RTOS_PRESENT)
#define THREAD_DELAY 30 #define THREAD_DELAY 30
#define SEMAPHORE_SLOTS 2 #define SEMAPHORE_SLOTS 2
#define SEM_CHANGES 100 #define SEM_CHANGES 100
@ -90,12 +92,7 @@ void test_multi()
} }
} }
struct thread_data { void single_thread(struct test_data *data)
Semaphore *sem;
uint32_t data;
};
void single_thread(struct thread_data *data)
{ {
data->sem->acquire(); data->sem->acquire();
data->data++; data->data++;
@ -104,7 +101,7 @@ void single_thread(struct thread_data *data)
/** Test single thread /** Test single thread
Given a two threads A & B and a semaphore (with count of 0) and a counter (equals to 0) Given a two threads A & B and a semaphore (with count of 0) and a counter (equals to 0)
when thread B calls @a wait when thread B calls @a acquire
then thread B waits for a token to become available then thread B waits for a token to become available
then the counter is equal to 0 then the counter is equal to 0
when thread A calls @a release on the semaphore when thread A calls @a release on the semaphore
@ -115,7 +112,7 @@ void test_single_thread()
{ {
Thread t(osPriorityNormal, THREAD_STACK_SIZE); Thread t(osPriorityNormal, THREAD_STACK_SIZE);
Semaphore sem(0); Semaphore sem(0);
struct thread_data data; struct test_data data;
osStatus res; osStatus res;
data.sem = &sem; data.sem = &sem;
@ -147,8 +144,8 @@ void timeout_thread(Semaphore *sem)
/** Test timeout /** Test timeout
Given thread and a semaphore with no tokens available Given thread and a semaphore with no tokens available
when thread calls @a wait on the semaphore with timeout of 10ms when a thread calls @a try_acquire_for with a timeout of 30ms
then the thread waits for 10ms and timeouts after then the thread is blocked for up to 30ms and timeouts after.
*/ */
void test_timeout() void test_timeout()
{ {
@ -167,17 +164,112 @@ void test_timeout()
t.join(); t.join();
TEST_ASSERT_UINT32_WITHIN(5000, 30000, timer.read_us()); TEST_ASSERT_UINT32_WITHIN(5000, 30000, timer.read_us());
} }
#endif
void test_ticker_release(struct test_data *data)
{
osStatus res;
data->data++;
res = data->sem->release();
TEST_ASSERT_EQUAL(osOK, res);
}
/** Test semaphore acquire
Given a semaphore with no tokens available and ticker with the callback registered
when the main thread calls @a acquire
then the main thread is blocked
when callback calls @a release on the semaphore
then the main thread is unblocked
*/
void test_semaphore_acquire()
{
Semaphore sem(0);
struct test_data data;
data.sem = &sem;
data.data = 0;
Ticker t1;
t1.attach_us(callback(test_ticker_release, &data), 3000);
sem.acquire();
t1.detach();
TEST_ASSERT_EQUAL(1, data.data);
}
void test_ticker_try_acquire(Semaphore *sem)
{
osStatus res;
res = sem->try_acquire();
TEST_ASSERT_FALSE(res);
}
/** Test semaphore try acquire
Given a semaphore with no tokens available and ticker with the callback registered
when callback tries to acquire the semaphore, it fails.
*/
void test_semaphore_try_acquire()
{
Semaphore sem(0);
Ticker t1;
t1.attach_us(callback(test_ticker_try_acquire, &sem), 3000);
ThisThread::sleep_for(4);
t1.detach();
}
/** Test semaphore try timeout
Given a semaphore with no tokens available
when the main thread calls @a try_acquire_for with 3ms timeout
then the main thread is blocked for 3ms and timeouts after
*/
void test_semaphore_try_timeout()
{
Semaphore sem(0);
bool res;
res = sem.try_acquire_for(3);
TEST_ASSERT_FALSE(res);
}
void test_ticker_semaphore_release(struct Semaphore *sem)
{
osStatus res;
res = sem->release();
TEST_ASSERT_EQUAL(osOK, res);
}
/** Test semaphore try acquire timeout
Given a semaphore with no tokens available and ticker with the callback registered
when the main thread calls @a try_acquire_for with 10ms timeout
then the main thread is blocked for up to 10ms
when callback call @a release on the semaphore after 3ms
then the main thread is unblocked.
*/
void test_semaphore_try_acquire_timeout()
{
Semaphore sem(0);
bool res;
Ticker t1;
t1.attach_us(callback(test_ticker_semaphore_release, &sem), 3000);
res = sem.try_acquire_for(10);
t1.detach();
TEST_ASSERT_TRUE(res);
}
/** Test no timeouts /** Test no timeouts
Test 1 token no timeout Test 1 token no timeout
Given thread and a semaphore with one token available Given thread and a semaphore with one token available
when thread calls @a wait on the semaphore with timeout of 0ms when thread calls @a try_acquire with timeout of 0ms
then the thread acquires the token immediately then the thread acquires the token immediately
Test 0 tokens no timeout Test 0 tokens no timeout
Given thread and a semaphore with no tokens available Given thread and a semaphore with no tokens available
when thread calls @a wait on the semaphore with timeout of 0ms when thread calls @a try_acquire with timeout of 0ms
then the thread returns immediately without acquiring a token then the thread returns immediately without acquiring a token
*/ */
template<int T> template<int T>
@ -197,7 +289,7 @@ void test_no_timeout()
/** Test multiple tokens wait /** Test multiple tokens wait
Given a thread and a semaphore initialized with 5 tokens Given a thread and a semaphore initialized with 5 tokens
when thread calls @a wait 6 times on the semaphore when thread calls @a try_acquire 6 times in a loop
then the token counts goes to zero then the token counts goes to zero
*/ */
void test_multiple_tokens_wait() void test_multiple_tokens_wait()
@ -235,13 +327,19 @@ utest::v1::status_t test_setup(const size_t number_of_cases)
} }
Case cases[] = { Case cases[] = {
Case("Test single thread", test_single_thread),
Case("Test timeout", test_timeout),
Case("Test 1 token no timeout", test_no_timeout<1>), Case("Test 1 token no timeout", test_no_timeout<1>),
Case("Test 0 tokens no timeout", test_no_timeout<0>), Case("Test 0 tokens no timeout", test_no_timeout<0>),
Case("Test multiple tokens wait", test_multiple_tokens_wait), Case("Test multiple tokens wait", test_multiple_tokens_wait),
Case("Test multiple tokens release", test_multiple_tokens_release), Case("Test multiple tokens release", test_multiple_tokens_release),
Case("Test semaphore acquire", test_semaphore_acquire),
Case("Test semaphore try acquire", test_semaphore_try_acquire),
Case("Test semaphore try timeout", test_semaphore_try_timeout),
Case("Test semaphore try acquire timeout", test_semaphore_try_acquire_timeout),
#if defined(MBED_CONF_RTOS_PRESENT)
Case("Test single thread", test_single_thread),
Case("Test timeout", test_timeout),
Case("Test multiple threads", test_multi) Case("Test multiple threads", test_multi)
#endif
}; };
Specification specification(test_setup, cases); Specification specification(test_setup, cases);
@ -252,4 +350,3 @@ int main()
} }
#endif // !DEVICE_USTICKER #endif // !DEVICE_USTICKER
#endif // defined(MBED_RTOS_SINGLE_THREAD) || !defined(MBED_CONF_RTOS_PRESENT)