mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Merge pull request #4945 from maciejbocianski/mail_tests
Extends test set for Mail classpull/4968/head
						commit
						81437732dd
					
				| 
						 | 
				
			
			@ -15,69 +15,472 @@
 | 
			
		|||
 */
 | 
			
		||||
#include "mbed.h"
 | 
			
		||||
#include "greentea-client/test_env.h"
 | 
			
		||||
#include "unity.h"
 | 
			
		||||
#include "utest.h"
 | 
			
		||||
#include "rtos.h"
 | 
			
		||||
 | 
			
		||||
#if defined(MBED_RTOS_SINGLE_THREAD)
 | 
			
		||||
  #error [NOT_SUPPORTED] test not supported
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using namespace utest::v1;
 | 
			
		||||
 | 
			
		||||
#define THREAD_STACK_SIZE   384 /* larger stack cause out of memory on some 16kB RAM boards in multi thread test*/
 | 
			
		||||
#define QUEUE_SIZE          16
 | 
			
		||||
#define THREAD_1_ID         1
 | 
			
		||||
#define THREAD_2_ID         2
 | 
			
		||||
#define THREAD_3_ID         3
 | 
			
		||||
#define QUEUE_PUT_DELAY_1   5
 | 
			
		||||
#define QUEUE_PUT_DELAY_2   50
 | 
			
		||||
#define QUEUE_PUT_DELAY_3   100
 | 
			
		||||
#define DATA_BASE           100
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    float    voltage;   /* AD result of measured voltage */
 | 
			
		||||
    float    current;   /* AD result of measured current */
 | 
			
		||||
    uint32_t counter;   /* A counter value               */
 | 
			
		||||
    uint16_t data;
 | 
			
		||||
    uint8_t thread_id;
 | 
			
		||||
} mail_t;
 | 
			
		||||
 | 
			
		||||
#define CREATE_VOLTAGE(COUNTER) (COUNTER * 0.1) * 33
 | 
			
		||||
#define CREATE_CURRENT(COUNTER) (COUNTER * 0.1) * 11
 | 
			
		||||
#define QUEUE_SIZE       16
 | 
			
		||||
#define QUEUE_PUT_DELAY  100
 | 
			
		||||
 | 
			
		||||
#define STACK_SIZE 1024
 | 
			
		||||
template<uint8_t thread_id, uint32_t wait_ms, uint32_t send_count>
 | 
			
		||||
void send_thread(Mail<mail_t, QUEUE_SIZE> *m)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t data = thread_id * DATA_BASE;
 | 
			
		||||
 | 
			
		||||
Mail<mail_t, QUEUE_SIZE> mail_box;
 | 
			
		||||
 | 
			
		||||
void send_thread () {
 | 
			
		||||
    static uint32_t i = 10;
 | 
			
		||||
    while (true) {
 | 
			
		||||
        i++; // fake data update
 | 
			
		||||
        mail_t *mail = mail_box.alloc();
 | 
			
		||||
        mail->voltage = CREATE_VOLTAGE(i);
 | 
			
		||||
        mail->current = CREATE_CURRENT(i);
 | 
			
		||||
        mail->counter = i;
 | 
			
		||||
        mail_box.put(mail);
 | 
			
		||||
        Thread::wait(QUEUE_PUT_DELAY);
 | 
			
		||||
    for (uint32_t i = 0; i < send_count; i++) {
 | 
			
		||||
        mail_t *mail = m->alloc();
 | 
			
		||||
        mail->thread_id = thread_id;
 | 
			
		||||
        mail->data = data++;
 | 
			
		||||
        m->put(mail);
 | 
			
		||||
        Thread::wait(wait_ms);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main (void) {
 | 
			
		||||
    GREENTEA_SETUP(20, "default_auto");
 | 
			
		||||
 | 
			
		||||
    Thread thread(osPriorityNormal, STACK_SIZE);
 | 
			
		||||
    thread.start(send_thread);
 | 
			
		||||
    bool result = true;
 | 
			
		||||
template<uint8_t thread_id, uint32_t queue_size, uint32_t wait_ms>
 | 
			
		||||
void receive_thread(Mail<mail_t, queue_size> *m)
 | 
			
		||||
{
 | 
			
		||||
    int result_counter = 0;
 | 
			
		||||
    uint32_t data = thread_id * DATA_BASE;
 | 
			
		||||
 | 
			
		||||
    while (true) {
 | 
			
		||||
    Thread::wait(wait_ms);
 | 
			
		||||
    for (uint32_t i = 0; i < queue_size; i++) {
 | 
			
		||||
        osEvent evt = m->get();
 | 
			
		||||
        if (evt.status == osEventMail) {
 | 
			
		||||
            mail_t *mail = (mail_t*)evt.value.p;
 | 
			
		||||
            const uint8_t id = mail->thread_id;
 | 
			
		||||
 | 
			
		||||
            // verify thread id
 | 
			
		||||
            TEST_ASSERT_TRUE(id == thread_id);
 | 
			
		||||
            // verify sent data
 | 
			
		||||
            TEST_ASSERT_TRUE(mail->data == data++);
 | 
			
		||||
 | 
			
		||||
            m->free(mail);
 | 
			
		||||
            result_counter++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    TEST_ASSERT_EQUAL(queue_size, result_counter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Test single thread Mail usage and order
 | 
			
		||||
 | 
			
		||||
    Given mailbox and one additional thread
 | 
			
		||||
    When messages are put in to the Mail box by this thread
 | 
			
		||||
    Then messages are received in main thread in the same order as was sent and the data sent is valid
 | 
			
		||||
 */
 | 
			
		||||
void test_single_thread_order(void)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t data = DATA_BASE;
 | 
			
		||||
    int result_counter = 0;
 | 
			
		||||
    Mail<mail_t, QUEUE_SIZE> mail_box;
 | 
			
		||||
 | 
			
		||||
    // mail send thread creation
 | 
			
		||||
    Thread thread(osPriorityNormal, THREAD_STACK_SIZE);
 | 
			
		||||
    thread.start(callback(send_thread<THREAD_1_ID, QUEUE_PUT_DELAY_1, QUEUE_SIZE>, &mail_box));
 | 
			
		||||
 | 
			
		||||
    // wait for some mail to be collected
 | 
			
		||||
    Thread::wait(10);
 | 
			
		||||
 | 
			
		||||
    for (uint32_t i = 0; i < QUEUE_SIZE; i++) {
 | 
			
		||||
        // mail receive (main thread)
 | 
			
		||||
        osEvent evt = mail_box.get();
 | 
			
		||||
        if (evt.status == osEventMail) {
 | 
			
		||||
            mail_t *mail = (mail_t*)evt.value.p;
 | 
			
		||||
            const float expected_voltage = CREATE_VOLTAGE(mail->counter);
 | 
			
		||||
            const float expected_current = CREATE_CURRENT(mail->counter);
 | 
			
		||||
            // Check using macros if received values correspond to values sent via queue
 | 
			
		||||
            bool expected_values = (expected_voltage == mail->voltage) &&
 | 
			
		||||
                                   (expected_current == mail->current);
 | 
			
		||||
            result = result && expected_values;
 | 
			
		||||
            const char *result_msg = expected_values ? "OK" : "FAIL";
 | 
			
		||||
            printf("%3d %.2fV %.2fA ... [%s]\r\n", mail->counter,
 | 
			
		||||
                                                   mail->voltage,
 | 
			
		||||
                                                   mail->current,
 | 
			
		||||
                                                   result_msg);
 | 
			
		||||
            const uint8_t id = mail->thread_id;
 | 
			
		||||
 | 
			
		||||
            // verify thread id
 | 
			
		||||
            TEST_ASSERT_TRUE(id == THREAD_1_ID);
 | 
			
		||||
            // verify sent data
 | 
			
		||||
            TEST_ASSERT_TRUE(mail->data == data++);
 | 
			
		||||
            mail_box.free(mail);
 | 
			
		||||
            if (result == false || ++result_counter == QUEUE_SIZE) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            result_counter++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    GREENTEA_TESTSUITE_RESULT(result);
 | 
			
		||||
    return 0;
 | 
			
		||||
    TEST_ASSERT_EQUAL(QUEUE_SIZE, result_counter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Test multi thread Mail usage and order
 | 
			
		||||
 | 
			
		||||
    Given mailbox and three additional threads
 | 
			
		||||
    When messages are put in to the Mail box by these threads
 | 
			
		||||
    Then messages are received in main thread in the same per thread order as was sent and the data sent is valid
 | 
			
		||||
 */
 | 
			
		||||
void test_multi_thread_order(void)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t data[4] = { 0, DATA_BASE, DATA_BASE * 2, DATA_BASE * 3 };
 | 
			
		||||
    int result_counter = 0;
 | 
			
		||||
    Mail<mail_t, QUEUE_SIZE> mail_box;
 | 
			
		||||
 | 
			
		||||
    // mail send threads creation
 | 
			
		||||
    Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
 | 
			
		||||
    Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
 | 
			
		||||
    Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
 | 
			
		||||
    thread1.start(callback(send_thread<THREAD_1_ID, QUEUE_PUT_DELAY_1, 7>, &mail_box));
 | 
			
		||||
    thread2.start(callback(send_thread<THREAD_2_ID, QUEUE_PUT_DELAY_2, 5>, &mail_box));
 | 
			
		||||
    thread3.start(callback(send_thread<THREAD_3_ID, QUEUE_PUT_DELAY_3, 4>, &mail_box));
 | 
			
		||||
 | 
			
		||||
    // wait for some mail to be collected
 | 
			
		||||
    Thread::wait(10);
 | 
			
		||||
 | 
			
		||||
    for (uint32_t i = 0; i < QUEUE_SIZE; i++) {
 | 
			
		||||
        // mail receive (main thread)
 | 
			
		||||
        osEvent evt = mail_box.get();
 | 
			
		||||
        if (evt.status == osEventMail) {
 | 
			
		||||
            mail_t *mail = (mail_t*)evt.value.p;
 | 
			
		||||
            const uint8_t id = mail->thread_id;
 | 
			
		||||
 | 
			
		||||
            // verify thread id
 | 
			
		||||
            TEST_ASSERT_TRUE((id == THREAD_1_ID) || (id == THREAD_2_ID) || (id == THREAD_3_ID));
 | 
			
		||||
            // verify sent data
 | 
			
		||||
            TEST_ASSERT_TRUE(mail->data == data[id]++);
 | 
			
		||||
            mail_box.free(mail);
 | 
			
		||||
 | 
			
		||||
            result_counter++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    TEST_ASSERT_EQUAL(QUEUE_SIZE, result_counter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Test multi thread multi Mail usage and order
 | 
			
		||||
 | 
			
		||||
    Given 3 mailbox and three additional threads
 | 
			
		||||
    When messages are put in to the mail boxes by main thread
 | 
			
		||||
    Then messages are received by threads in the same per mail box order as was sent and the data sent is valid
 | 
			
		||||
 */
 | 
			
		||||
void test_multi_thread_multi_mail_order(void)
 | 
			
		||||
{
 | 
			
		||||
    Mail<mail_t, 4> mail_box[4]; /* mail_box[0] not used */
 | 
			
		||||
    uint16_t data[4] = { 0, DATA_BASE, DATA_BASE * 2, DATA_BASE * 3 };
 | 
			
		||||
    mail_t *mail;
 | 
			
		||||
    uint8_t id;
 | 
			
		||||
 | 
			
		||||
    // mail receive threads creation
 | 
			
		||||
    Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
 | 
			
		||||
    Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
 | 
			
		||||
    Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
 | 
			
		||||
    thread1.start(callback(receive_thread<THREAD_1_ID, 4, 0>, mail_box + 1));
 | 
			
		||||
    thread2.start(callback(receive_thread<THREAD_2_ID, 4, 10>, mail_box + 2));
 | 
			
		||||
    thread3.start(callback(receive_thread<THREAD_3_ID, 4, 100>, mail_box + 3));
 | 
			
		||||
 | 
			
		||||
    for (uint32_t i = 0; i < 4; i++) {
 | 
			
		||||
        id = THREAD_1_ID;
 | 
			
		||||
        mail = mail_box[id].alloc();
 | 
			
		||||
        mail->thread_id = id;
 | 
			
		||||
        mail->data = data[id]++;
 | 
			
		||||
        mail_box[id].put(mail);
 | 
			
		||||
 | 
			
		||||
        id = THREAD_2_ID;
 | 
			
		||||
        mail = mail_box[id].alloc();
 | 
			
		||||
        mail->thread_id = id;
 | 
			
		||||
        mail->data = data[id]++;
 | 
			
		||||
        mail_box[id].put(mail);
 | 
			
		||||
 | 
			
		||||
        id = THREAD_3_ID;
 | 
			
		||||
        mail = mail_box[id].alloc();
 | 
			
		||||
        mail->thread_id = id;
 | 
			
		||||
        mail->data = data[id]++;
 | 
			
		||||
        mail_box[id].put(mail);
 | 
			
		||||
 | 
			
		||||
        Thread::wait(i * 10);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    thread1.join();
 | 
			
		||||
    thread2.join();
 | 
			
		||||
    thread3.join();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Test message memory deallocation with block out of the scope
 | 
			
		||||
 | 
			
		||||
    Given an empty mailbox
 | 
			
		||||
    When try to free out of the scope memory block
 | 
			
		||||
    Then it return appropriate error code
 | 
			
		||||
 */
 | 
			
		||||
void test_free_wrong()
 | 
			
		||||
{
 | 
			
		||||
    osStatus status;
 | 
			
		||||
    Mail<uint32_t, 4> mail_box;
 | 
			
		||||
    uint32_t *mail, data;
 | 
			
		||||
 | 
			
		||||
    mail = &data;
 | 
			
		||||
    status = mail_box.free(mail);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osErrorParameter, status);
 | 
			
		||||
 | 
			
		||||
    mail = mail_box.alloc();
 | 
			
		||||
    TEST_ASSERT_NOT_EQUAL(NULL, mail);
 | 
			
		||||
 | 
			
		||||
    mail = &data;
 | 
			
		||||
    status = mail_box.free(mail);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osErrorParameter, status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Test message memory deallocation with null block
 | 
			
		||||
 | 
			
		||||
    Given an empty mailbox
 | 
			
		||||
    When try to free null ptr
 | 
			
		||||
    Then it return appropriate error code
 | 
			
		||||
 */
 | 
			
		||||
void test_free_null()
 | 
			
		||||
{
 | 
			
		||||
    osStatus status;
 | 
			
		||||
    Mail<uint32_t, 4> mail_box;
 | 
			
		||||
    uint32_t *mail;
 | 
			
		||||
 | 
			
		||||
    mail = NULL;
 | 
			
		||||
    status = mail_box.free(mail);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osErrorParameter, status);
 | 
			
		||||
 | 
			
		||||
    mail = mail_box.alloc();
 | 
			
		||||
    TEST_ASSERT_NOT_EQUAL(NULL, mail);
 | 
			
		||||
 | 
			
		||||
    mail = NULL;
 | 
			
		||||
    status = mail_box.free(mail);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osErrorParameter, status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Test same message memory deallocation twice
 | 
			
		||||
 | 
			
		||||
    Given an empty mailbox
 | 
			
		||||
    Then allocate message memory
 | 
			
		||||
    When try to free it second time
 | 
			
		||||
    Then it return appropriate error code
 | 
			
		||||
 */
 | 
			
		||||
void test_free_twice()
 | 
			
		||||
{
 | 
			
		||||
    osStatus status;
 | 
			
		||||
    Mail<uint32_t, 4> mail_box;
 | 
			
		||||
 | 
			
		||||
    uint32_t *mail = mail_box.alloc();
 | 
			
		||||
    TEST_ASSERT_NOT_EQUAL(NULL, mail);
 | 
			
		||||
 | 
			
		||||
    status = mail_box.free(mail);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osOK, status);
 | 
			
		||||
 | 
			
		||||
    status = mail_box.free(mail);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osErrorResource, status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Test get from empty mailbox with timeout set
 | 
			
		||||
 | 
			
		||||
    Given an empty mailbox
 | 
			
		||||
    When @a get is called on the mailbox with timeout of 50
 | 
			
		||||
    Then mailbox returns status of osOK, but no data after specified amount of time
 | 
			
		||||
 */
 | 
			
		||||
void test_get_empty_timeout()
 | 
			
		||||
{
 | 
			
		||||
    Mail<uint32_t, 4> mail_box;
 | 
			
		||||
    Timer timer;
 | 
			
		||||
 | 
			
		||||
    timer.start();
 | 
			
		||||
    osEvent evt = mail_box.get(50);
 | 
			
		||||
    TEST_ASSERT_UINT32_WITHIN(5000, 50000, timer.read_us());
 | 
			
		||||
    TEST_ASSERT_EQUAL(osEventTimeout, evt.status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Test get from empty mailbox with 0 timeout
 | 
			
		||||
 | 
			
		||||
    Given an empty mailbox
 | 
			
		||||
    When @a get is called on the mailbox with timeout of 0
 | 
			
		||||
    Then mailbox returns status of osOK, but no data
 | 
			
		||||
 */
 | 
			
		||||
void test_get_empty_no_timeout()
 | 
			
		||||
{
 | 
			
		||||
    Mail<uint32_t, 4> mail_box;
 | 
			
		||||
 | 
			
		||||
    osEvent evt = mail_box.get(0);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osOK, evt.status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Test mail order
 | 
			
		||||
 | 
			
		||||
    Given an mailbox for uint32_t values
 | 
			
		||||
    Then allocate two mails and put them in to mailbox
 | 
			
		||||
    When call @a get it returns previously put mails
 | 
			
		||||
    Then mails should be in the same order as put
 | 
			
		||||
 */
 | 
			
		||||
void test_order(void)
 | 
			
		||||
{
 | 
			
		||||
    osStatus status;
 | 
			
		||||
    osEvent evt;
 | 
			
		||||
    Mail<int32_t, 4> mail_box;
 | 
			
		||||
    const int32_t TEST_VAL1 = 123;
 | 
			
		||||
    const int32_t TEST_VAL2 = 456;
 | 
			
		||||
 | 
			
		||||
    int32_t *mail1 = mail_box.alloc();
 | 
			
		||||
    TEST_ASSERT_NOT_EQUAL(NULL, mail1);
 | 
			
		||||
 | 
			
		||||
    *mail1 = TEST_VAL1;
 | 
			
		||||
    status = mail_box.put(mail1);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osOK, status);
 | 
			
		||||
 | 
			
		||||
    int32_t *mail2 = mail_box.alloc();
 | 
			
		||||
    TEST_ASSERT_NOT_EQUAL(NULL, mail2);
 | 
			
		||||
 | 
			
		||||
    *mail2 = TEST_VAL2;
 | 
			
		||||
    status = mail_box.put(mail2);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osOK, status);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    evt = mail_box.get();
 | 
			
		||||
    TEST_ASSERT_EQUAL(evt.status, osEventMail);
 | 
			
		||||
 | 
			
		||||
    mail1 = (int32_t*)evt.value.p;
 | 
			
		||||
    TEST_ASSERT_EQUAL(TEST_VAL1, *mail1);
 | 
			
		||||
 | 
			
		||||
    evt = mail_box.get();
 | 
			
		||||
    TEST_ASSERT_EQUAL(evt.status, osEventMail);
 | 
			
		||||
 | 
			
		||||
    mail2 = (int32_t*)evt.value.p;
 | 
			
		||||
    TEST_ASSERT_EQUAL(TEST_VAL2, *mail2);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    status = mail_box.free(mail1);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osOK, status);
 | 
			
		||||
 | 
			
		||||
    status = mail_box.free(mail2);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osOK, status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Test Mail box max size limit
 | 
			
		||||
 | 
			
		||||
    Given an Mail box with max size of 4 elements
 | 
			
		||||
    When call @a alloc four times it returns memory blocks
 | 
			
		||||
    Then the memory blocks should be valid
 | 
			
		||||
    When call @a alloc one more time it returns memory blocks
 | 
			
		||||
    Then the memory blocks should be not valid (NULL - no memory available)
 | 
			
		||||
 */
 | 
			
		||||
void test_max_size()
 | 
			
		||||
{
 | 
			
		||||
    osStatus status;
 | 
			
		||||
    Mail<uint32_t, 4> mail_box;
 | 
			
		||||
    const uint32_t TEST_VAL = 123;
 | 
			
		||||
 | 
			
		||||
    // 1 OK
 | 
			
		||||
    uint32_t *mail1 = mail_box.alloc();
 | 
			
		||||
    TEST_ASSERT_NOT_EQUAL(NULL, mail1);
 | 
			
		||||
 | 
			
		||||
    // 2 OK
 | 
			
		||||
    uint32_t *mail2 = mail_box.alloc();
 | 
			
		||||
    TEST_ASSERT_NOT_EQUAL(NULL, mail2);
 | 
			
		||||
 | 
			
		||||
    // 3 OK
 | 
			
		||||
    uint32_t *mail3 = mail_box.alloc();
 | 
			
		||||
    TEST_ASSERT_NOT_EQUAL(NULL, mail3);
 | 
			
		||||
 | 
			
		||||
    // 4 OK
 | 
			
		||||
    uint32_t *mail4 = mail_box.alloc();
 | 
			
		||||
    TEST_ASSERT_NOT_EQUAL(NULL, mail4);
 | 
			
		||||
 | 
			
		||||
    // 5 KO
 | 
			
		||||
    uint32_t *mail5 = mail_box.alloc();
 | 
			
		||||
    TEST_ASSERT_EQUAL(NULL, mail5);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    status = mail_box.free(mail1);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osOK, status);
 | 
			
		||||
 | 
			
		||||
    status = mail_box.free(mail2);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osOK, status);
 | 
			
		||||
 | 
			
		||||
    status = mail_box.free(mail3);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osOK, status);
 | 
			
		||||
 | 
			
		||||
    status = mail_box.free(mail4);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osOK, status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Test mailbox of T type data
 | 
			
		||||
 | 
			
		||||
    Given an mailbox with T memory block type
 | 
			
		||||
    When allocate/put/get/free memory block
 | 
			
		||||
    Then all operations should succeed
 | 
			
		||||
 */
 | 
			
		||||
template<typename T>
 | 
			
		||||
void test_data_type(void)
 | 
			
		||||
{
 | 
			
		||||
    osStatus status;
 | 
			
		||||
    Mail<T, 4> mail_box;
 | 
			
		||||
    const T TEST_VAL = 123;
 | 
			
		||||
 | 
			
		||||
    T *mail = mail_box.alloc();
 | 
			
		||||
    TEST_ASSERT_NOT_EQUAL(NULL, mail);
 | 
			
		||||
 | 
			
		||||
    *mail = TEST_VAL;
 | 
			
		||||
    status = mail_box.put(mail);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osOK, status);
 | 
			
		||||
 | 
			
		||||
    osEvent evt = mail_box.get();
 | 
			
		||||
    TEST_ASSERT_EQUAL(evt.status, osEventMail);
 | 
			
		||||
 | 
			
		||||
    mail = (T*)evt.value.p;
 | 
			
		||||
    TEST_ASSERT_EQUAL(TEST_VAL, *mail);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    status = mail_box.free(mail);
 | 
			
		||||
    TEST_ASSERT_EQUAL(osOK, status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Test calloc - memory block allocation with resetting
 | 
			
		||||
 | 
			
		||||
    Given an empty Mail box
 | 
			
		||||
    When call @a calloc it returns allocated memory block
 | 
			
		||||
    Then the memory block should be valid and filled with zeros
 | 
			
		||||
 */
 | 
			
		||||
void test_calloc()
 | 
			
		||||
{
 | 
			
		||||
    Mail<uint32_t, 1> mail_box;
 | 
			
		||||
 | 
			
		||||
    uint32_t *mail = mail_box.calloc();
 | 
			
		||||
    TEST_ASSERT_NOT_EQUAL(NULL, mail);
 | 
			
		||||
    TEST_ASSERT_EQUAL(0, *mail);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
utest::v1::status_t test_setup(const size_t number_of_cases)
 | 
			
		||||
{
 | 
			
		||||
    GREENTEA_SETUP(10, "default_auto");
 | 
			
		||||
    return verbose_test_setup_handler(number_of_cases);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Case cases[] = {
 | 
			
		||||
    Case("Test calloc", test_calloc),
 | 
			
		||||
    Case("Test message type uint8", test_data_type<uint8_t>),
 | 
			
		||||
    Case("Test message type uint16", test_data_type<uint16_t>),
 | 
			
		||||
    Case("Test message type uint32", test_data_type<uint32_t>),
 | 
			
		||||
    Case("Test mailbox max size", test_max_size),
 | 
			
		||||
    Case("Test message send order", test_order),
 | 
			
		||||
    Case("Test get with timeout on empty mailbox", test_get_empty_timeout),
 | 
			
		||||
    Case("Test get without timeout on empty mailbox", test_get_empty_no_timeout),
 | 
			
		||||
    Case("Test message free twice", test_free_twice),
 | 
			
		||||
    Case("Test null message free", test_free_null),
 | 
			
		||||
    Case("Test invalid message free", test_free_wrong),
 | 
			
		||||
    Case("Test message send/receive single thread and order", test_single_thread_order),
 | 
			
		||||
    Case("Test message send/receive multi-thread and per thread order", test_multi_thread_order),
 | 
			
		||||
    Case("Test message send/receive multi-thread, multi-Mail and per thread order", test_multi_thread_multi_mail_order)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Specification specification(test_setup, cases);
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    return !Harness::run(specification);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue