1

Committer:
valeyev
Date:
Tue Mar 13 07:17:50 2018 +0000
Revision:
0:e056ac8fecf8
looking for...

Who changed what in which revision?

UserRevisionLine numberNew contents of line
valeyev 0:e056ac8fecf8 1 /* mbed Microcontroller Library
valeyev 0:e056ac8fecf8 2 * Copyright (c) 2017 ARM Limited
valeyev 0:e056ac8fecf8 3 *
valeyev 0:e056ac8fecf8 4 * Licensed under the Apache License, Version 2.0 (the "License");
valeyev 0:e056ac8fecf8 5 * you may not use this file except in compliance with the License.
valeyev 0:e056ac8fecf8 6 * You may obtain a copy of the License at
valeyev 0:e056ac8fecf8 7 *
valeyev 0:e056ac8fecf8 8 * http://www.apache.org/licenses/LICENSE-2.0
valeyev 0:e056ac8fecf8 9 *
valeyev 0:e056ac8fecf8 10 * Unless required by applicable law or agreed to in writing, software
valeyev 0:e056ac8fecf8 11 * distributed under the License is distributed on an "AS IS" BASIS,
valeyev 0:e056ac8fecf8 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
valeyev 0:e056ac8fecf8 13 * See the License for the specific language governing permissions and
valeyev 0:e056ac8fecf8 14 * limitations under the License.
valeyev 0:e056ac8fecf8 15 */
valeyev 0:e056ac8fecf8 16 #include "mbed.h"
valeyev 0:e056ac8fecf8 17 #include "greentea-client/test_env.h"
valeyev 0:e056ac8fecf8 18 #include "unity.h"
valeyev 0:e056ac8fecf8 19 #include "utest.h"
valeyev 0:e056ac8fecf8 20 #include "rtos.h"
valeyev 0:e056ac8fecf8 21
valeyev 0:e056ac8fecf8 22 #if defined(MBED_RTOS_SINGLE_THREAD)
valeyev 0:e056ac8fecf8 23 #error [NOT_SUPPORTED] test not supported
valeyev 0:e056ac8fecf8 24 #endif
valeyev 0:e056ac8fecf8 25
valeyev 0:e056ac8fecf8 26 using namespace utest::v1;
valeyev 0:e056ac8fecf8 27
valeyev 0:e056ac8fecf8 28 #define THREAD_STACK_SIZE 320 /* larger stack cause out of heap memory on some 16kB RAM boards in multi thread test*/
valeyev 0:e056ac8fecf8 29 #define QUEUE_SIZE 16
valeyev 0:e056ac8fecf8 30 #define THREAD_1_ID 1
valeyev 0:e056ac8fecf8 31 #define THREAD_2_ID 2
valeyev 0:e056ac8fecf8 32 #define THREAD_3_ID 3
valeyev 0:e056ac8fecf8 33 #define QUEUE_PUT_DELAY_1 5
valeyev 0:e056ac8fecf8 34 #define QUEUE_PUT_DELAY_2 50
valeyev 0:e056ac8fecf8 35 #define QUEUE_PUT_DELAY_3 100
valeyev 0:e056ac8fecf8 36 #define DATA_BASE 100
valeyev 0:e056ac8fecf8 37
valeyev 0:e056ac8fecf8 38
valeyev 0:e056ac8fecf8 39 typedef struct {
valeyev 0:e056ac8fecf8 40 uint16_t data;
valeyev 0:e056ac8fecf8 41 uint8_t thread_id;
valeyev 0:e056ac8fecf8 42 } mail_t;
valeyev 0:e056ac8fecf8 43
valeyev 0:e056ac8fecf8 44
valeyev 0:e056ac8fecf8 45 template<uint8_t thread_id, uint32_t wait_ms, uint32_t send_count>
valeyev 0:e056ac8fecf8 46 void send_thread(Mail<mail_t, QUEUE_SIZE> *m)
valeyev 0:e056ac8fecf8 47 {
valeyev 0:e056ac8fecf8 48 uint32_t data = thread_id * DATA_BASE;
valeyev 0:e056ac8fecf8 49
valeyev 0:e056ac8fecf8 50 for (uint32_t i = 0; i < send_count; i++) {
valeyev 0:e056ac8fecf8 51 mail_t *mail = m->alloc();
valeyev 0:e056ac8fecf8 52 mail->thread_id = thread_id;
valeyev 0:e056ac8fecf8 53 mail->data = data++;
valeyev 0:e056ac8fecf8 54 m->put(mail);
valeyev 0:e056ac8fecf8 55 Thread::wait(wait_ms);
valeyev 0:e056ac8fecf8 56 }
valeyev 0:e056ac8fecf8 57 }
valeyev 0:e056ac8fecf8 58
valeyev 0:e056ac8fecf8 59 template<uint8_t thread_id, uint32_t queue_size, uint32_t wait_ms>
valeyev 0:e056ac8fecf8 60 void receive_thread(Mail<mail_t, queue_size> *m)
valeyev 0:e056ac8fecf8 61 {
valeyev 0:e056ac8fecf8 62 int result_counter = 0;
valeyev 0:e056ac8fecf8 63 uint32_t data = thread_id * DATA_BASE;
valeyev 0:e056ac8fecf8 64
valeyev 0:e056ac8fecf8 65 Thread::wait(wait_ms);
valeyev 0:e056ac8fecf8 66 for (uint32_t i = 0; i < queue_size; i++) {
valeyev 0:e056ac8fecf8 67 osEvent evt = m->get();
valeyev 0:e056ac8fecf8 68 if (evt.status == osEventMail) {
valeyev 0:e056ac8fecf8 69 mail_t *mail = (mail_t*)evt.value.p;
valeyev 0:e056ac8fecf8 70 const uint8_t id = mail->thread_id;
valeyev 0:e056ac8fecf8 71
valeyev 0:e056ac8fecf8 72 // verify thread id
valeyev 0:e056ac8fecf8 73 TEST_ASSERT_TRUE(id == thread_id);
valeyev 0:e056ac8fecf8 74 // verify sent data
valeyev 0:e056ac8fecf8 75 TEST_ASSERT_TRUE(mail->data == data++);
valeyev 0:e056ac8fecf8 76
valeyev 0:e056ac8fecf8 77 m->free(mail);
valeyev 0:e056ac8fecf8 78 result_counter++;
valeyev 0:e056ac8fecf8 79 }
valeyev 0:e056ac8fecf8 80 }
valeyev 0:e056ac8fecf8 81 TEST_ASSERT_EQUAL(queue_size, result_counter);
valeyev 0:e056ac8fecf8 82 }
valeyev 0:e056ac8fecf8 83
valeyev 0:e056ac8fecf8 84 /** Test single thread Mail usage and order
valeyev 0:e056ac8fecf8 85
valeyev 0:e056ac8fecf8 86 Given mailbox and one additional thread
valeyev 0:e056ac8fecf8 87 When messages are put in to the Mail box by this thread
valeyev 0:e056ac8fecf8 88 Then messages are received in main thread in the same order as was sent and the data sent is valid
valeyev 0:e056ac8fecf8 89 */
valeyev 0:e056ac8fecf8 90 void test_single_thread_order(void)
valeyev 0:e056ac8fecf8 91 {
valeyev 0:e056ac8fecf8 92 uint16_t data = DATA_BASE;
valeyev 0:e056ac8fecf8 93 int result_counter = 0;
valeyev 0:e056ac8fecf8 94 Mail<mail_t, QUEUE_SIZE> mail_box;
valeyev 0:e056ac8fecf8 95
valeyev 0:e056ac8fecf8 96 // mail send thread creation
valeyev 0:e056ac8fecf8 97 Thread thread(osPriorityNormal, THREAD_STACK_SIZE);
valeyev 0:e056ac8fecf8 98 thread.start(callback(send_thread<THREAD_1_ID, QUEUE_PUT_DELAY_1, QUEUE_SIZE>, &mail_box));
valeyev 0:e056ac8fecf8 99
valeyev 0:e056ac8fecf8 100 // wait for some mail to be collected
valeyev 0:e056ac8fecf8 101 Thread::wait(10);
valeyev 0:e056ac8fecf8 102
valeyev 0:e056ac8fecf8 103 for (uint32_t i = 0; i < QUEUE_SIZE; i++) {
valeyev 0:e056ac8fecf8 104 // mail receive (main thread)
valeyev 0:e056ac8fecf8 105 osEvent evt = mail_box.get();
valeyev 0:e056ac8fecf8 106 if (evt.status == osEventMail) {
valeyev 0:e056ac8fecf8 107 mail_t *mail = (mail_t*)evt.value.p;
valeyev 0:e056ac8fecf8 108 const uint8_t id = mail->thread_id;
valeyev 0:e056ac8fecf8 109
valeyev 0:e056ac8fecf8 110 // verify thread id
valeyev 0:e056ac8fecf8 111 TEST_ASSERT_TRUE(id == THREAD_1_ID);
valeyev 0:e056ac8fecf8 112 // verify sent data
valeyev 0:e056ac8fecf8 113 TEST_ASSERT_TRUE(mail->data == data++);
valeyev 0:e056ac8fecf8 114 mail_box.free(mail);
valeyev 0:e056ac8fecf8 115
valeyev 0:e056ac8fecf8 116 result_counter++;
valeyev 0:e056ac8fecf8 117 }
valeyev 0:e056ac8fecf8 118 }
valeyev 0:e056ac8fecf8 119 TEST_ASSERT_EQUAL(QUEUE_SIZE, result_counter);
valeyev 0:e056ac8fecf8 120 }
valeyev 0:e056ac8fecf8 121
valeyev 0:e056ac8fecf8 122 /** Test multi thread Mail usage and order
valeyev 0:e056ac8fecf8 123
valeyev 0:e056ac8fecf8 124 Given mailbox and three additional threads
valeyev 0:e056ac8fecf8 125 When messages are put in to the Mail box by these threads
valeyev 0:e056ac8fecf8 126 Then messages are received in main thread in the same per thread order as was sent and the data sent is valid
valeyev 0:e056ac8fecf8 127 */
valeyev 0:e056ac8fecf8 128 void test_multi_thread_order(void)
valeyev 0:e056ac8fecf8 129 {
valeyev 0:e056ac8fecf8 130 uint16_t data[4] = { 0, DATA_BASE, DATA_BASE * 2, DATA_BASE * 3 };
valeyev 0:e056ac8fecf8 131 int result_counter = 0;
valeyev 0:e056ac8fecf8 132 Mail<mail_t, QUEUE_SIZE> mail_box;
valeyev 0:e056ac8fecf8 133
valeyev 0:e056ac8fecf8 134 // mail send threads creation
valeyev 0:e056ac8fecf8 135 Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
valeyev 0:e056ac8fecf8 136 Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
valeyev 0:e056ac8fecf8 137 Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
valeyev 0:e056ac8fecf8 138 thread1.start(callback(send_thread<THREAD_1_ID, QUEUE_PUT_DELAY_1, 7>, &mail_box));
valeyev 0:e056ac8fecf8 139 thread2.start(callback(send_thread<THREAD_2_ID, QUEUE_PUT_DELAY_2, 5>, &mail_box));
valeyev 0:e056ac8fecf8 140 thread3.start(callback(send_thread<THREAD_3_ID, QUEUE_PUT_DELAY_3, 4>, &mail_box));
valeyev 0:e056ac8fecf8 141
valeyev 0:e056ac8fecf8 142 // wait for some mail to be collected
valeyev 0:e056ac8fecf8 143 Thread::wait(10);
valeyev 0:e056ac8fecf8 144
valeyev 0:e056ac8fecf8 145 for (uint32_t i = 0; i < QUEUE_SIZE; i++) {
valeyev 0:e056ac8fecf8 146 // mail receive (main thread)
valeyev 0:e056ac8fecf8 147 osEvent evt = mail_box.get();
valeyev 0:e056ac8fecf8 148 if (evt.status == osEventMail) {
valeyev 0:e056ac8fecf8 149 mail_t *mail = (mail_t*)evt.value.p;
valeyev 0:e056ac8fecf8 150 const uint8_t id = mail->thread_id;
valeyev 0:e056ac8fecf8 151
valeyev 0:e056ac8fecf8 152 // verify thread id
valeyev 0:e056ac8fecf8 153 TEST_ASSERT_TRUE((id == THREAD_1_ID) || (id == THREAD_2_ID) || (id == THREAD_3_ID));
valeyev 0:e056ac8fecf8 154 // verify sent data
valeyev 0:e056ac8fecf8 155 TEST_ASSERT_TRUE(mail->data == data[id]++);
valeyev 0:e056ac8fecf8 156 mail_box.free(mail);
valeyev 0:e056ac8fecf8 157
valeyev 0:e056ac8fecf8 158 result_counter++;
valeyev 0:e056ac8fecf8 159 }
valeyev 0:e056ac8fecf8 160 }
valeyev 0:e056ac8fecf8 161 TEST_ASSERT_EQUAL(QUEUE_SIZE, result_counter);
valeyev 0:e056ac8fecf8 162 }
valeyev 0:e056ac8fecf8 163
valeyev 0:e056ac8fecf8 164 /** Test multi thread multi Mail usage and order
valeyev 0:e056ac8fecf8 165
valeyev 0:e056ac8fecf8 166 Given 3 mailbox and three additional threads
valeyev 0:e056ac8fecf8 167 When messages are put in to the mail boxes by main thread
valeyev 0:e056ac8fecf8 168 Then messages are received by threads in the same per mail box order as was sent and the data sent is valid
valeyev 0:e056ac8fecf8 169 */
valeyev 0:e056ac8fecf8 170 void test_multi_thread_multi_mail_order(void)
valeyev 0:e056ac8fecf8 171 {
valeyev 0:e056ac8fecf8 172 Mail<mail_t, 4> mail_box[4]; /* mail_box[0] not used */
valeyev 0:e056ac8fecf8 173 uint16_t data[4] = { 0, DATA_BASE, DATA_BASE * 2, DATA_BASE * 3 };
valeyev 0:e056ac8fecf8 174 mail_t *mail;
valeyev 0:e056ac8fecf8 175 uint8_t id;
valeyev 0:e056ac8fecf8 176
valeyev 0:e056ac8fecf8 177 // mail receive threads creation
valeyev 0:e056ac8fecf8 178 Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
valeyev 0:e056ac8fecf8 179 Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
valeyev 0:e056ac8fecf8 180 Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
valeyev 0:e056ac8fecf8 181 thread1.start(callback(receive_thread<THREAD_1_ID, 4, 0>, mail_box + 1));
valeyev 0:e056ac8fecf8 182 thread2.start(callback(receive_thread<THREAD_2_ID, 4, 10>, mail_box + 2));
valeyev 0:e056ac8fecf8 183 thread3.start(callback(receive_thread<THREAD_3_ID, 4, 100>, mail_box + 3));
valeyev 0:e056ac8fecf8 184
valeyev 0:e056ac8fecf8 185 for (uint32_t i = 0; i < 4; i++) {
valeyev 0:e056ac8fecf8 186 id = THREAD_1_ID;
valeyev 0:e056ac8fecf8 187 mail = mail_box[id].alloc();
valeyev 0:e056ac8fecf8 188 mail->thread_id = id;
valeyev 0:e056ac8fecf8 189 mail->data = data[id]++;
valeyev 0:e056ac8fecf8 190 mail_box[id].put(mail);
valeyev 0:e056ac8fecf8 191
valeyev 0:e056ac8fecf8 192 id = THREAD_2_ID;
valeyev 0:e056ac8fecf8 193 mail = mail_box[id].alloc();
valeyev 0:e056ac8fecf8 194 mail->thread_id = id;
valeyev 0:e056ac8fecf8 195 mail->data = data[id]++;
valeyev 0:e056ac8fecf8 196 mail_box[id].put(mail);
valeyev 0:e056ac8fecf8 197
valeyev 0:e056ac8fecf8 198 id = THREAD_3_ID;
valeyev 0:e056ac8fecf8 199 mail = mail_box[id].alloc();
valeyev 0:e056ac8fecf8 200 mail->thread_id = id;
valeyev 0:e056ac8fecf8 201 mail->data = data[id]++;
valeyev 0:e056ac8fecf8 202 mail_box[id].put(mail);
valeyev 0:e056ac8fecf8 203
valeyev 0:e056ac8fecf8 204 Thread::wait(i * 10);
valeyev 0:e056ac8fecf8 205 }
valeyev 0:e056ac8fecf8 206
valeyev 0:e056ac8fecf8 207 thread1.join();
valeyev 0:e056ac8fecf8 208 thread2.join();
valeyev 0:e056ac8fecf8 209 thread3.join();
valeyev 0:e056ac8fecf8 210 }
valeyev 0:e056ac8fecf8 211
valeyev 0:e056ac8fecf8 212 /** Test message memory deallocation with block out of the scope
valeyev 0:e056ac8fecf8 213
valeyev 0:e056ac8fecf8 214 Given an empty mailbox
valeyev 0:e056ac8fecf8 215 When try to free out of the scope memory block
valeyev 0:e056ac8fecf8 216 Then it return appropriate error code
valeyev 0:e056ac8fecf8 217 */
valeyev 0:e056ac8fecf8 218 void test_free_wrong()
valeyev 0:e056ac8fecf8 219 {
valeyev 0:e056ac8fecf8 220 osStatus status;
valeyev 0:e056ac8fecf8 221 Mail<uint32_t, 4> mail_box;
valeyev 0:e056ac8fecf8 222 uint32_t *mail, data;
valeyev 0:e056ac8fecf8 223
valeyev 0:e056ac8fecf8 224 mail = &data;
valeyev 0:e056ac8fecf8 225 status = mail_box.free(mail);
valeyev 0:e056ac8fecf8 226 TEST_ASSERT_EQUAL(osErrorParameter, status);
valeyev 0:e056ac8fecf8 227
valeyev 0:e056ac8fecf8 228 mail = mail_box.alloc();
valeyev 0:e056ac8fecf8 229 TEST_ASSERT_NOT_EQUAL(NULL, mail);
valeyev 0:e056ac8fecf8 230
valeyev 0:e056ac8fecf8 231 mail = &data;
valeyev 0:e056ac8fecf8 232 status = mail_box.free(mail);
valeyev 0:e056ac8fecf8 233 TEST_ASSERT_EQUAL(osErrorParameter, status);
valeyev 0:e056ac8fecf8 234 }
valeyev 0:e056ac8fecf8 235
valeyev 0:e056ac8fecf8 236 /** Test message memory deallocation with null block
valeyev 0:e056ac8fecf8 237
valeyev 0:e056ac8fecf8 238 Given an empty mailbox
valeyev 0:e056ac8fecf8 239 When try to free null ptr
valeyev 0:e056ac8fecf8 240 Then it return appropriate error code
valeyev 0:e056ac8fecf8 241 */
valeyev 0:e056ac8fecf8 242 void test_free_null()
valeyev 0:e056ac8fecf8 243 {
valeyev 0:e056ac8fecf8 244 osStatus status;
valeyev 0:e056ac8fecf8 245 Mail<uint32_t, 4> mail_box;
valeyev 0:e056ac8fecf8 246 uint32_t *mail;
valeyev 0:e056ac8fecf8 247
valeyev 0:e056ac8fecf8 248 mail = NULL;
valeyev 0:e056ac8fecf8 249 status = mail_box.free(mail);
valeyev 0:e056ac8fecf8 250 TEST_ASSERT_EQUAL(osErrorParameter, status);
valeyev 0:e056ac8fecf8 251
valeyev 0:e056ac8fecf8 252 mail = mail_box.alloc();
valeyev 0:e056ac8fecf8 253 TEST_ASSERT_NOT_EQUAL(NULL, mail);
valeyev 0:e056ac8fecf8 254
valeyev 0:e056ac8fecf8 255 mail = NULL;
valeyev 0:e056ac8fecf8 256 status = mail_box.free(mail);
valeyev 0:e056ac8fecf8 257 TEST_ASSERT_EQUAL(osErrorParameter, status);
valeyev 0:e056ac8fecf8 258 }
valeyev 0:e056ac8fecf8 259
valeyev 0:e056ac8fecf8 260 /** Test same message memory deallocation twice
valeyev 0:e056ac8fecf8 261
valeyev 0:e056ac8fecf8 262 Given an empty mailbox
valeyev 0:e056ac8fecf8 263 Then allocate message memory
valeyev 0:e056ac8fecf8 264 When try to free it second time
valeyev 0:e056ac8fecf8 265 Then it return appropriate error code
valeyev 0:e056ac8fecf8 266 */
valeyev 0:e056ac8fecf8 267 void test_free_twice()
valeyev 0:e056ac8fecf8 268 {
valeyev 0:e056ac8fecf8 269 osStatus status;
valeyev 0:e056ac8fecf8 270 Mail<uint32_t, 4> mail_box;
valeyev 0:e056ac8fecf8 271
valeyev 0:e056ac8fecf8 272 uint32_t *mail = mail_box.alloc();
valeyev 0:e056ac8fecf8 273 TEST_ASSERT_NOT_EQUAL(NULL, mail);
valeyev 0:e056ac8fecf8 274
valeyev 0:e056ac8fecf8 275 status = mail_box.free(mail);
valeyev 0:e056ac8fecf8 276 TEST_ASSERT_EQUAL(osOK, status);
valeyev 0:e056ac8fecf8 277
valeyev 0:e056ac8fecf8 278 status = mail_box.free(mail);
valeyev 0:e056ac8fecf8 279 TEST_ASSERT_EQUAL(osErrorResource, status);
valeyev 0:e056ac8fecf8 280 }
valeyev 0:e056ac8fecf8 281
valeyev 0:e056ac8fecf8 282 /** Test get from empty mailbox with timeout set
valeyev 0:e056ac8fecf8 283
valeyev 0:e056ac8fecf8 284 Given an empty mailbox
valeyev 0:e056ac8fecf8 285 When @a get is called on the mailbox with timeout of 50
valeyev 0:e056ac8fecf8 286 Then mailbox returns status of osOK, but no data after specified amount of time
valeyev 0:e056ac8fecf8 287 */
valeyev 0:e056ac8fecf8 288 void test_get_empty_timeout()
valeyev 0:e056ac8fecf8 289 {
valeyev 0:e056ac8fecf8 290 Mail<uint32_t, 4> mail_box;
valeyev 0:e056ac8fecf8 291 Timer timer;
valeyev 0:e056ac8fecf8 292
valeyev 0:e056ac8fecf8 293 timer.start();
valeyev 0:e056ac8fecf8 294 osEvent evt = mail_box.get(50);
valeyev 0:e056ac8fecf8 295 TEST_ASSERT_UINT32_WITHIN(5000, 50000, timer.read_us());
valeyev 0:e056ac8fecf8 296 TEST_ASSERT_EQUAL(osEventTimeout, evt.status);
valeyev 0:e056ac8fecf8 297 }
valeyev 0:e056ac8fecf8 298
valeyev 0:e056ac8fecf8 299 /** Test get from empty mailbox with 0 timeout
valeyev 0:e056ac8fecf8 300
valeyev 0:e056ac8fecf8 301 Given an empty mailbox
valeyev 0:e056ac8fecf8 302 When @a get is called on the mailbox with timeout of 0
valeyev 0:e056ac8fecf8 303 Then mailbox returns status of osOK, but no data
valeyev 0:e056ac8fecf8 304 */
valeyev 0:e056ac8fecf8 305 void test_get_empty_no_timeout()
valeyev 0:e056ac8fecf8 306 {
valeyev 0:e056ac8fecf8 307 Mail<uint32_t, 4> mail_box;
valeyev 0:e056ac8fecf8 308
valeyev 0:e056ac8fecf8 309 osEvent evt = mail_box.get(0);
valeyev 0:e056ac8fecf8 310 TEST_ASSERT_EQUAL(osOK, evt.status);
valeyev 0:e056ac8fecf8 311 }
valeyev 0:e056ac8fecf8 312
valeyev 0:e056ac8fecf8 313 /** Test mail order
valeyev 0:e056ac8fecf8 314
valeyev 0:e056ac8fecf8 315 Given an mailbox for uint32_t values
valeyev 0:e056ac8fecf8 316 Then allocate two mails and put them in to mailbox
valeyev 0:e056ac8fecf8 317 When call @a get it returns previously put mails
valeyev 0:e056ac8fecf8 318 Then mails should be in the same order as put
valeyev 0:e056ac8fecf8 319 */
valeyev 0:e056ac8fecf8 320 void test_order(void)
valeyev 0:e056ac8fecf8 321 {
valeyev 0:e056ac8fecf8 322 osStatus status;
valeyev 0:e056ac8fecf8 323 osEvent evt;
valeyev 0:e056ac8fecf8 324 Mail<int32_t, 4> mail_box;
valeyev 0:e056ac8fecf8 325 const int32_t TEST_VAL1 = 123;
valeyev 0:e056ac8fecf8 326 const int32_t TEST_VAL2 = 456;
valeyev 0:e056ac8fecf8 327
valeyev 0:e056ac8fecf8 328 int32_t *mail1 = mail_box.alloc();
valeyev 0:e056ac8fecf8 329 TEST_ASSERT_NOT_EQUAL(NULL, mail1);
valeyev 0:e056ac8fecf8 330
valeyev 0:e056ac8fecf8 331 *mail1 = TEST_VAL1;
valeyev 0:e056ac8fecf8 332 status = mail_box.put(mail1);
valeyev 0:e056ac8fecf8 333 TEST_ASSERT_EQUAL(osOK, status);
valeyev 0:e056ac8fecf8 334
valeyev 0:e056ac8fecf8 335 int32_t *mail2 = mail_box.alloc();
valeyev 0:e056ac8fecf8 336 TEST_ASSERT_NOT_EQUAL(NULL, mail2);
valeyev 0:e056ac8fecf8 337
valeyev 0:e056ac8fecf8 338 *mail2 = TEST_VAL2;
valeyev 0:e056ac8fecf8 339 status = mail_box.put(mail2);
valeyev 0:e056ac8fecf8 340 TEST_ASSERT_EQUAL(osOK, status);
valeyev 0:e056ac8fecf8 341
valeyev 0:e056ac8fecf8 342
valeyev 0:e056ac8fecf8 343 evt = mail_box.get();
valeyev 0:e056ac8fecf8 344 TEST_ASSERT_EQUAL(evt.status, osEventMail);
valeyev 0:e056ac8fecf8 345
valeyev 0:e056ac8fecf8 346 mail1 = (int32_t*)evt.value.p;
valeyev 0:e056ac8fecf8 347 TEST_ASSERT_EQUAL(TEST_VAL1, *mail1);
valeyev 0:e056ac8fecf8 348
valeyev 0:e056ac8fecf8 349 evt = mail_box.get();
valeyev 0:e056ac8fecf8 350 TEST_ASSERT_EQUAL(evt.status, osEventMail);
valeyev 0:e056ac8fecf8 351
valeyev 0:e056ac8fecf8 352 mail2 = (int32_t*)evt.value.p;
valeyev 0:e056ac8fecf8 353 TEST_ASSERT_EQUAL(TEST_VAL2, *mail2);
valeyev 0:e056ac8fecf8 354
valeyev 0:e056ac8fecf8 355
valeyev 0:e056ac8fecf8 356 status = mail_box.free(mail1);
valeyev 0:e056ac8fecf8 357 TEST_ASSERT_EQUAL(osOK, status);
valeyev 0:e056ac8fecf8 358
valeyev 0:e056ac8fecf8 359 status = mail_box.free(mail2);
valeyev 0:e056ac8fecf8 360 TEST_ASSERT_EQUAL(osOK, status);
valeyev 0:e056ac8fecf8 361 }
valeyev 0:e056ac8fecf8 362
valeyev 0:e056ac8fecf8 363 /** Test Mail box max size limit
valeyev 0:e056ac8fecf8 364
valeyev 0:e056ac8fecf8 365 Given an Mail box with max size of 4 elements
valeyev 0:e056ac8fecf8 366 When call @a alloc four times it returns memory blocks
valeyev 0:e056ac8fecf8 367 Then the memory blocks should be valid
valeyev 0:e056ac8fecf8 368 When call @a alloc one more time it returns memory blocks
valeyev 0:e056ac8fecf8 369 Then the memory blocks should be not valid (NULL - no memory available)
valeyev 0:e056ac8fecf8 370 */
valeyev 0:e056ac8fecf8 371 void test_max_size()
valeyev 0:e056ac8fecf8 372 {
valeyev 0:e056ac8fecf8 373 osStatus status;
valeyev 0:e056ac8fecf8 374 Mail<uint32_t, 4> mail_box;
valeyev 0:e056ac8fecf8 375 const uint32_t TEST_VAL = 123;
valeyev 0:e056ac8fecf8 376
valeyev 0:e056ac8fecf8 377 // 1 OK
valeyev 0:e056ac8fecf8 378 uint32_t *mail1 = mail_box.alloc();
valeyev 0:e056ac8fecf8 379 TEST_ASSERT_NOT_EQUAL(NULL, mail1);
valeyev 0:e056ac8fecf8 380
valeyev 0:e056ac8fecf8 381 // 2 OK
valeyev 0:e056ac8fecf8 382 uint32_t *mail2 = mail_box.alloc();
valeyev 0:e056ac8fecf8 383 TEST_ASSERT_NOT_EQUAL(NULL, mail2);
valeyev 0:e056ac8fecf8 384
valeyev 0:e056ac8fecf8 385 // 3 OK
valeyev 0:e056ac8fecf8 386 uint32_t *mail3 = mail_box.alloc();
valeyev 0:e056ac8fecf8 387 TEST_ASSERT_NOT_EQUAL(NULL, mail3);
valeyev 0:e056ac8fecf8 388
valeyev 0:e056ac8fecf8 389 // 4 OK
valeyev 0:e056ac8fecf8 390 uint32_t *mail4 = mail_box.alloc();
valeyev 0:e056ac8fecf8 391 TEST_ASSERT_NOT_EQUAL(NULL, mail4);
valeyev 0:e056ac8fecf8 392
valeyev 0:e056ac8fecf8 393 // 5 KO
valeyev 0:e056ac8fecf8 394 uint32_t *mail5 = mail_box.alloc();
valeyev 0:e056ac8fecf8 395 TEST_ASSERT_EQUAL(NULL, mail5);
valeyev 0:e056ac8fecf8 396
valeyev 0:e056ac8fecf8 397
valeyev 0:e056ac8fecf8 398 status = mail_box.free(mail1);
valeyev 0:e056ac8fecf8 399 TEST_ASSERT_EQUAL(osOK, status);
valeyev 0:e056ac8fecf8 400
valeyev 0:e056ac8fecf8 401 status = mail_box.free(mail2);
valeyev 0:e056ac8fecf8 402 TEST_ASSERT_EQUAL(osOK, status);
valeyev 0:e056ac8fecf8 403
valeyev 0:e056ac8fecf8 404 status = mail_box.free(mail3);
valeyev 0:e056ac8fecf8 405 TEST_ASSERT_EQUAL(osOK, status);
valeyev 0:e056ac8fecf8 406
valeyev 0:e056ac8fecf8 407 status = mail_box.free(mail4);
valeyev 0:e056ac8fecf8 408 TEST_ASSERT_EQUAL(osOK, status);
valeyev 0:e056ac8fecf8 409 }
valeyev 0:e056ac8fecf8 410
valeyev 0:e056ac8fecf8 411 /** Test mailbox of T type data
valeyev 0:e056ac8fecf8 412
valeyev 0:e056ac8fecf8 413 Given an mailbox with T memory block type
valeyev 0:e056ac8fecf8 414 When allocate/put/get/free memory block
valeyev 0:e056ac8fecf8 415 Then all operations should succeed
valeyev 0:e056ac8fecf8 416 */
valeyev 0:e056ac8fecf8 417 template<typename T>
valeyev 0:e056ac8fecf8 418 void test_data_type(void)
valeyev 0:e056ac8fecf8 419 {
valeyev 0:e056ac8fecf8 420 osStatus status;
valeyev 0:e056ac8fecf8 421 Mail<T, 4> mail_box;
valeyev 0:e056ac8fecf8 422 const T TEST_VAL = 123;
valeyev 0:e056ac8fecf8 423
valeyev 0:e056ac8fecf8 424 T *mail = mail_box.alloc();
valeyev 0:e056ac8fecf8 425 TEST_ASSERT_NOT_EQUAL(NULL, mail);
valeyev 0:e056ac8fecf8 426
valeyev 0:e056ac8fecf8 427 *mail = TEST_VAL;
valeyev 0:e056ac8fecf8 428 status = mail_box.put(mail);
valeyev 0:e056ac8fecf8 429 TEST_ASSERT_EQUAL(osOK, status);
valeyev 0:e056ac8fecf8 430
valeyev 0:e056ac8fecf8 431 osEvent evt = mail_box.get();
valeyev 0:e056ac8fecf8 432 TEST_ASSERT_EQUAL(evt.status, osEventMail);
valeyev 0:e056ac8fecf8 433
valeyev 0:e056ac8fecf8 434 mail = (T*)evt.value.p;
valeyev 0:e056ac8fecf8 435 TEST_ASSERT_EQUAL(TEST_VAL, *mail);
valeyev 0:e056ac8fecf8 436
valeyev 0:e056ac8fecf8 437
valeyev 0:e056ac8fecf8 438 status = mail_box.free(mail);
valeyev 0:e056ac8fecf8 439 TEST_ASSERT_EQUAL(osOK, status);
valeyev 0:e056ac8fecf8 440 }
valeyev 0:e056ac8fecf8 441
valeyev 0:e056ac8fecf8 442 /** Test calloc - memory block allocation with resetting
valeyev 0:e056ac8fecf8 443
valeyev 0:e056ac8fecf8 444 Given an empty Mail box
valeyev 0:e056ac8fecf8 445 When call @a calloc it returns allocated memory block
valeyev 0:e056ac8fecf8 446 Then the memory block should be valid and filled with zeros
valeyev 0:e056ac8fecf8 447 */
valeyev 0:e056ac8fecf8 448 void test_calloc()
valeyev 0:e056ac8fecf8 449 {
valeyev 0:e056ac8fecf8 450 Mail<uint32_t, 1> mail_box;
valeyev 0:e056ac8fecf8 451
valeyev 0:e056ac8fecf8 452 uint32_t *mail = mail_box.calloc();
valeyev 0:e056ac8fecf8 453 TEST_ASSERT_NOT_EQUAL(NULL, mail);
valeyev 0:e056ac8fecf8 454 TEST_ASSERT_EQUAL(0, *mail);
valeyev 0:e056ac8fecf8 455 }
valeyev 0:e056ac8fecf8 456
valeyev 0:e056ac8fecf8 457 /** Test mail empty
valeyev 0:e056ac8fecf8 458
valeyev 0:e056ac8fecf8 459 Given a mail of uint32_t data
valeyev 0:e056ac8fecf8 460 before data is inserted the mail should be empty
valeyev 0:e056ac8fecf8 461 after data is inserted the mail shouldn't be empty
valeyev 0:e056ac8fecf8 462 */
valeyev 0:e056ac8fecf8 463 void test_mail_empty()
valeyev 0:e056ac8fecf8 464 {
valeyev 0:e056ac8fecf8 465 Mail<mail_t, 1> m;
valeyev 0:e056ac8fecf8 466
valeyev 0:e056ac8fecf8 467 mail_t *mail = m.alloc();
valeyev 0:e056ac8fecf8 468
valeyev 0:e056ac8fecf8 469 TEST_ASSERT_EQUAL(true, m.empty());
valeyev 0:e056ac8fecf8 470
valeyev 0:e056ac8fecf8 471 m.put(mail);
valeyev 0:e056ac8fecf8 472
valeyev 0:e056ac8fecf8 473 TEST_ASSERT_EQUAL(false, m.empty());
valeyev 0:e056ac8fecf8 474 }
valeyev 0:e056ac8fecf8 475
valeyev 0:e056ac8fecf8 476 /** Test mail empty
valeyev 0:e056ac8fecf8 477
valeyev 0:e056ac8fecf8 478 Given a mail of uint32_t data with size of 1
valeyev 0:e056ac8fecf8 479 before data is inserted the mail shouldn't be full
valeyev 0:e056ac8fecf8 480 after data is inserted the mail should be full
valeyev 0:e056ac8fecf8 481 */
valeyev 0:e056ac8fecf8 482 void test_mail_full()
valeyev 0:e056ac8fecf8 483 {
valeyev 0:e056ac8fecf8 484 Mail<mail_t, 1> m;
valeyev 0:e056ac8fecf8 485
valeyev 0:e056ac8fecf8 486 mail_t *mail = m.alloc();
valeyev 0:e056ac8fecf8 487
valeyev 0:e056ac8fecf8 488 TEST_ASSERT_EQUAL(false, m.full());
valeyev 0:e056ac8fecf8 489
valeyev 0:e056ac8fecf8 490 m.put(mail);
valeyev 0:e056ac8fecf8 491
valeyev 0:e056ac8fecf8 492 TEST_ASSERT_EQUAL(true, m.full());
valeyev 0:e056ac8fecf8 493 }
valeyev 0:e056ac8fecf8 494
valeyev 0:e056ac8fecf8 495 utest::v1::status_t test_setup(const size_t number_of_cases)
valeyev 0:e056ac8fecf8 496 {
valeyev 0:e056ac8fecf8 497 GREENTEA_SETUP(10, "default_auto");
valeyev 0:e056ac8fecf8 498 return verbose_test_setup_handler(number_of_cases);
valeyev 0:e056ac8fecf8 499 }
valeyev 0:e056ac8fecf8 500
valeyev 0:e056ac8fecf8 501 Case cases[] = {
valeyev 0:e056ac8fecf8 502 Case("Test calloc", test_calloc),
valeyev 0:e056ac8fecf8 503 Case("Test message type uint8", test_data_type<uint8_t>),
valeyev 0:e056ac8fecf8 504 Case("Test message type uint16", test_data_type<uint16_t>),
valeyev 0:e056ac8fecf8 505 Case("Test message type uint32", test_data_type<uint32_t>),
valeyev 0:e056ac8fecf8 506 Case("Test mailbox max size", test_max_size),
valeyev 0:e056ac8fecf8 507 Case("Test message send order", test_order),
valeyev 0:e056ac8fecf8 508 Case("Test get with timeout on empty mailbox", test_get_empty_timeout),
valeyev 0:e056ac8fecf8 509 Case("Test get without timeout on empty mailbox", test_get_empty_no_timeout),
valeyev 0:e056ac8fecf8 510 Case("Test message free twice", test_free_twice),
valeyev 0:e056ac8fecf8 511 Case("Test null message free", test_free_null),
valeyev 0:e056ac8fecf8 512 Case("Test invalid message free", test_free_wrong),
valeyev 0:e056ac8fecf8 513 Case("Test message send/receive single thread and order", test_single_thread_order),
valeyev 0:e056ac8fecf8 514 Case("Test message send/receive multi-thread and per thread order", test_multi_thread_order),
valeyev 0:e056ac8fecf8 515 Case("Test message send/receive multi-thread, multi-Mail and per thread order", test_multi_thread_multi_mail_order),
valeyev 0:e056ac8fecf8 516 Case("Test mail empty", test_mail_empty),
valeyev 0:e056ac8fecf8 517 Case("Test mail full", test_mail_full)
valeyev 0:e056ac8fecf8 518 };
valeyev 0:e056ac8fecf8 519
valeyev 0:e056ac8fecf8 520 Specification specification(test_setup, cases);
valeyev 0:e056ac8fecf8 521
valeyev 0:e056ac8fecf8 522 int main()
valeyev 0:e056ac8fecf8 523 {
valeyev 0:e056ac8fecf8 524 return !Harness::run(specification);
valeyev 0:e056ac8fecf8 525 }