Skip to content

Commit 4d25bcc

Browse files
authored
Merge pull request #5081 from maciejbocianski/events_flags_tests
Extends test set for EventFlags class
2 parents e9e0595 + 0e014c9 commit 4d25bcc

File tree

1 file changed

+341
-27
lines changed
  • TESTS/mbedmicro-rtos-mbed/event_flags

1 file changed

+341
-27
lines changed

TESTS/mbedmicro-rtos-mbed/event_flags/main.cpp

Lines changed: 341 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,47 +17,361 @@
1717

1818
#include "mbed.h"
1919
#include "greentea-client/test_env.h"
20-
#include "rtos.h"
20+
#include "unity/unity.h"
21+
#include "utest/utest.h"
22+
23+
using utest::v1::Case;
2124

2225
#if defined(MBED_RTOS_SINGLE_THREAD)
2326
#error [NOT_SUPPORTED] test not supported
2427
#endif
2528

26-
#define TEST_STACK_SIZE 512
29+
#define THREAD_STACK_SIZE 320 /* 512B stack on GCC_ARM compiler cause out of memory on some 16kB RAM boards e.g. NUCLEO_F070RB */
30+
31+
#define MAX_FLAG_POS 30
32+
#define PROHIBITED_FLAG_POS 31
2733

28-
#define EVENT_SET_VALUE 0x01
29-
const int EVENT_TO_EMIT = 100;
30-
const int EVENT_HANDLE_DELAY = 25;
34+
/* flags */
35+
#define FLAG01 0x1FFF /* 00000000000000000001111111111111 */
36+
#define FLAG02 0x3FFE000 /* 00000011111111111110000000000000 */
37+
#define FLAG03 0x7C000000 /* 01111100000000000000000000000000 */
38+
#define PROHIBITED_FLAG 0x80000000 /* 10000000000000000000000000000000 */
39+
#define NO_FLAGS 0x0
3140

32-
DigitalOut led(LED1);
33-
EventFlags event_flags;
41+
Semaphore sync_sem(0, 1);
3442

35-
int events_counter = 0;
43+
/* In order to successfully run this test suite when compiled with --profile=debug
44+
* error() has to be redefined as noop.
45+
*
46+
* EventFlags calls RTX API which uses Event Recorder functionality. When compiled
47+
* with MBED_TRAP_ERRORS_ENABLED=1 (set in debug profile) EvrRtxEventFlagsError() calls error()
48+
* which aborts test program.
49+
*/
50+
#if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED
51+
void error(const char* format, ...) {
52+
(void) format;
53+
}
54+
#endif
3655

37-
void led_thread() {
38-
while (true) {
39-
event_flags.wait_all(EVENT_SET_VALUE);
40-
led = !led;
41-
events_counter++;
56+
template<uint32_t flags, uint32_t wait_ms>
57+
void send_thread(EventFlags *ef)
58+
{
59+
for (uint32_t i = 0; i <= MAX_FLAG_POS; i++) {
60+
const uint32_t flag = flags & (1 << i);
61+
if (flag) {
62+
ef->set(flag);
63+
Thread::wait(wait_ms);
64+
}
4265
}
4366
}
4467

45-
int main (void) {
46-
GREENTEA_SETUP(10, "default_auto");
68+
template<uint32_t flags, uint32_t wait_ms>
69+
void send_thread_sync(EventFlags *ef)
70+
{
71+
for (uint32_t i = 0; i <= MAX_FLAG_POS; i++) {
72+
const uint32_t flag = flags & (1 << i);
73+
if (flag) {
74+
sync_sem.wait();
75+
ef->set(flag);
76+
Thread::wait(wait_ms);
77+
}
78+
}
79+
}
4780

48-
Thread thread(osPriorityNormal, TEST_STACK_SIZE);
49-
thread.start(led_thread);
81+
template<uint32_t flags>
82+
void wait_thread_all(EventFlags *ef)
83+
{
84+
uint32_t ret, flags_after_clear;
85+
ret = ef->wait_all(flags);
86+
flags_after_clear = ef->get();
87+
TEST_ASSERT(flags | ret);
88+
TEST_ASSERT(flags | ~flags_after_clear);
89+
}
5090

51-
bool result = false;
5291

53-
while (true) {
54-
Thread::wait(2 * EVENT_HANDLE_DELAY);
55-
event_flags.set(EVENT_SET_VALUE);
56-
if (events_counter == EVENT_TO_EMIT) {
57-
result = true;
58-
break;
59-
}
92+
/** Test if get on empty EventFlags object return NO_FLAGS
93+
94+
Given a empty EventFlags object
95+
When call @a get
96+
Then @a get return status is NO_FLAGS
97+
*/
98+
void test_empty_get(void)
99+
{
100+
EventFlags ev;
101+
uint32_t flags;
102+
103+
flags = ev.get();
104+
TEST_ASSERT_EQUAL(NO_FLAGS, flags);
105+
}
106+
107+
/** Test if clear on empty EventFlags object return NO_FLAGS
108+
109+
Given a empty EventFlags object
110+
When call @a clear(NO_FLAGS)
111+
Then @a clear return status is NO_FLAGS
112+
*/
113+
void test_empty_clear(void)
114+
{
115+
EventFlags ev;
116+
uint32_t flags;
117+
118+
flags = ev.clear(NO_FLAGS);
119+
TEST_ASSERT_EQUAL(NO_FLAGS, flags);
120+
}
121+
122+
/** Test if set on empty EventFlags object return NO_FLAGS
123+
124+
Given a empty EventFlags object
125+
When call @a set(NO_FLAGS)
126+
Then @a set return status is NO_FLAGS
127+
*/
128+
void test_empty_set(void)
129+
{
130+
EventFlags ev;
131+
uint32_t flags;
132+
133+
flags = ev.set(NO_FLAGS);
134+
TEST_ASSERT_EQUAL(NO_FLAGS, flags);
135+
}
136+
137+
/** Test if call of set/clean with PROHIBITED_FLAG doesn't invalidates object flags
138+
139+
Given a EventFlags object with all flags already set
140+
When call @a clear(PROHIBITED_FLAG) with prohibited flag
141+
Then @a clear return status is osFlagsErrorParameter and object flags stays unchanged
142+
When call @a set(PROHIBITED_FLAG) with prohibited flag
143+
Then @a set return status is osFlagsErrorParameter and object flags stays unchanged
144+
145+
@note Each signal has up to 31 event flags 0x1, 0x2, 0x4, 0x8, ..., 0x40000000
146+
Most significant bit is reserved and thereby flag 0x80000000 is prohibited
147+
*/
148+
void test_prohibited(void)
149+
{
150+
EventFlags ev;
151+
uint32_t flags;
152+
153+
ev.set(FLAG01 | FLAG02 | FLAG03);
154+
155+
flags = ev.clear(PROHIBITED_FLAG);
156+
TEST_ASSERT_EQUAL(osFlagsErrorParameter, flags);
157+
158+
flags = ev.get();
159+
TEST_ASSERT_EQUAL(FLAG01 | FLAG02 | FLAG03, flags);
160+
161+
flags = ev.set(PROHIBITED_FLAG);
162+
TEST_ASSERT_EQUAL(osFlagsErrorParameter, flags);
163+
164+
flags = ev.get();
165+
TEST_ASSERT_EQUAL(FLAG01 | FLAG02 | FLAG03, flags);
166+
}
167+
168+
/** Test set/get/clear for full flag range
169+
170+
Given a EventFlags object
171+
When call @a clear
172+
Then @a clear return status is already set flags
173+
When call @a set with specified flag
174+
Then @a set return status is flags after setting
175+
When call @a get
176+
Then @a get return status is set flags
177+
*/
178+
void test_set_get_clear_full_flag_range(void)
179+
{
180+
EventFlags ev;
181+
uint32_t flag, flags, ret;
182+
183+
flags = NO_FLAGS;
184+
for (int i = 0; i <= MAX_FLAG_POS; i++) {
185+
ret = ev.clear();
186+
TEST_ASSERT_EQUAL(flags, ret);
187+
flags = 1 << i;
188+
ret = ev.set(flags);
189+
TEST_ASSERT_EQUAL(flags, ret);
190+
ret = ev.get();
191+
TEST_ASSERT_EQUAL(flags, ret);
192+
}
193+
194+
ev.clear();
195+
flags = NO_FLAGS;
196+
for (int i = 0; i <= MAX_FLAG_POS; i++) {
197+
ret = ev.clear(NO_FLAGS);
198+
TEST_ASSERT_EQUAL(flags, ret);
199+
flag = 1 << i;
200+
flags |= flag;
201+
ret = ev.set(flag);
202+
TEST_ASSERT_EQUAL(flags, ret);
203+
ret = ev.get();
204+
TEST_ASSERT_EQUAL(flags, ret);
205+
}
206+
}
207+
208+
/** Test if multi-threaded flag set cause wait_all to return
209+
210+
Given a EventFlags object and three threads are started in parallel
211+
When threads set specified flags
212+
Then main thread waits until receive all of them
213+
*/
214+
void test_multi_thread_all(void)
215+
{
216+
EventFlags ef;
217+
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
218+
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
219+
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
220+
thread1.start(callback(send_thread<FLAG01, 1>, &ef));
221+
thread2.start(callback(send_thread<FLAG02, 2>, &ef));
222+
thread3.start(callback(send_thread<FLAG03, 3>, &ef));
223+
224+
uint32_t ret = ef.wait_all(FLAG01 | FLAG02 | FLAG03);
225+
TEST_ASSERT_EQUAL(FLAG01 | FLAG02 | FLAG03, ret);
226+
}
227+
228+
/** Test if multi-threaded flag set cause wait_any to return
229+
230+
Given a EventFlags object and three threads are started in parallel
231+
When threads set specified flags
232+
Then main thread waits until receive all of them
233+
*/
234+
void test_multi_thread_any(void)
235+
{
236+
EventFlags ef;
237+
uint32_t ret;
238+
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
239+
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
240+
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
241+
thread1.start(callback(send_thread<FLAG01, 1>, &ef));
242+
thread2.start(callback(send_thread<FLAG02, 1>, &ef));
243+
thread3.start(callback(send_thread<FLAG03, 1>, &ef));
244+
245+
for (int i = 0; i <= MAX_FLAG_POS; i++) {
246+
uint32_t flag = 1 << i;
247+
ret = ef.wait_any(flag);
248+
TEST_ASSERT(flag | ret);
249+
}
250+
ret = ef.get();
251+
TEST_ASSERT_EQUAL(NO_FLAGS, ret);
252+
}
253+
254+
/** Test if multi-threaded flag set cause wait_any(with timeout) to return
255+
256+
Given a EventFlags object and thread is running
257+
When main thread call @ wait_any with timeout
258+
Then when timeout expires @ wait_any return status is osFlagsErrorTimeout
259+
When main thread call @ wait_any with timeout and thread set specified flags
260+
Then main thread waits until receive all of them and @ wait_any return status is wait flag
261+
*/
262+
void test_multi_thread_any_timeout(void)
263+
{
264+
EventFlags ef;
265+
uint32_t ret;
266+
Thread thread(osPriorityNormal, THREAD_STACK_SIZE);
267+
thread.start(callback(send_thread_sync<FLAG01 | FLAG02 | FLAG03, 1>, &ef));
268+
269+
for (int i = 0; i <= MAX_FLAG_POS; i++) {
270+
uint32_t flag = 1 << i;
271+
272+
ret = ef.wait_any(flag, 10);
273+
TEST_ASSERT_EQUAL(osFlagsErrorTimeout, ret);
274+
275+
sync_sem.release();
276+
ret = ef.wait_any(flag, 10);
277+
TEST_ASSERT_EQUAL(flag, ret);
278+
}
279+
ret = ef.get();
280+
TEST_ASSERT_EQUAL(NO_FLAGS, ret);
281+
}
282+
283+
/** Test if multi-threaded flag set cause wait_any(without clear) to return
284+
285+
Given a EventFlags object and three threads are started in parallel
286+
When threads set specified flags
287+
Then main thread waits until receive all of them
288+
*/
289+
void test_multi_thread_any_no_clear(void)
290+
{
291+
EventFlags ef;
292+
uint32_t ret;
293+
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
294+
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
295+
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
296+
thread1.start(callback(send_thread<FLAG01, 1>, &ef));
297+
thread2.start(callback(send_thread<FLAG02, 1>, &ef));
298+
thread3.start(callback(send_thread<FLAG03, 1>, &ef));
299+
300+
for (int i = 0; i <= MAX_FLAG_POS; i++) {
301+
uint32_t flag = 1 << i;
302+
ret = ef.wait_any(flag, osWaitForever, false);
303+
TEST_ASSERT(flag | ret);
304+
ret = ef.clear(flag);
305+
TEST_ASSERT(ret < osFlagsError);
306+
}
307+
ret = ef.get();
308+
TEST_ASSERT_EQUAL(NO_FLAGS, ret);
309+
}
310+
311+
/** Test multi-threaded wait_any
312+
313+
Given a EventFlags object and three threads are started in parallel
314+
When flags are set in main thread
315+
Then other threads waits until receive all of them
316+
*/
317+
void test_multi_thread_all_many_wait(void)
318+
{
319+
EventFlags ef;
320+
{
321+
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
322+
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
323+
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
324+
thread1.start(callback(wait_thread_all<FLAG01>, &ef));
325+
thread2.start(callback(wait_thread_all<FLAG02>, &ef));
326+
thread3.start(callback(wait_thread_all<FLAG03>, &ef));
327+
328+
ef.set(FLAG01 | FLAG02 | FLAG03);
329+
thread1.join();
330+
thread2.join();
331+
thread3.join();
332+
TEST_ASSERT_EQUAL(NO_FLAGS, ef.get());
60333
}
61-
GREENTEA_TESTSUITE_RESULT(result);
62-
return 0;
334+
335+
{
336+
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
337+
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
338+
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
339+
thread1.start(callback(wait_thread_all<FLAG01>, &ef));
340+
thread2.start(callback(wait_thread_all<FLAG02>, &ef));
341+
thread3.start(callback(wait_thread_all<FLAG03>, &ef));
342+
343+
ef.set(FLAG01);
344+
thread1.join();
345+
ef.set(FLAG02);
346+
thread2.join();
347+
ef.set(FLAG03);
348+
thread3.join();
349+
TEST_ASSERT_EQUAL(NO_FLAGS, ef.get());
350+
}
351+
}
352+
353+
utest::v1::status_t test_setup(const size_t number_of_cases)
354+
{
355+
GREENTEA_SETUP(10, "default_auto");
356+
return utest::v1::verbose_test_setup_handler(number_of_cases);
357+
}
358+
359+
Case cases[] = {
360+
Case("Test empty clear", test_empty_clear),
361+
Case("Test empty get", test_empty_get),
362+
Case("Test empty set", test_empty_set),
363+
Case("Test clear/set with prohibited flag", test_prohibited),
364+
Case("Test set/get/clear for full flag range", test_set_get_clear_full_flag_range),
365+
Case("Test multi-threaded wait_all", test_multi_thread_all),
366+
Case("Test multi-threaded wait_any", test_multi_thread_any),
367+
Case("Test multi-threaded wait_all many wait", test_multi_thread_all_many_wait),
368+
Case("Test multi-threaded wait_any timeout", test_multi_thread_any_timeout),
369+
Case("Test multi-threaded wait_any no clear", test_multi_thread_any_no_clear)
370+
};
371+
372+
utest::v1::Specification specification(test_setup, cases);
373+
374+
int main()
375+
{
376+
return !utest::v1::Harness::run(specification);
63377
}

0 commit comments

Comments
 (0)