1 #include <stdbool.h>
2 #include <string.h>
3
4 #include "esp_event.h"
5 #include "sdkconfig.h"
6
7 #include "freertos/FreeRTOS.h"
8 #include "freertos/task.h"
9 #include "esp_log.h"
10 #include "driver/periph_ctrl.h"
11 #include "driver/timer.h"
12
13 #include "esp_event.h"
14 #include "esp_event_private.h"
15 #include "esp_event_internal.h"
16
17 #include "esp_heap_caps.h"
18 #include "esp_timer.h"
19
20 #include "sdkconfig.h"
21 #include "unity.h"
22
23 #include "test_utils.h"
24
25 static const char* TAG = "test_event";
26
27 #define TEST_CONFIG_ITEMS_TO_REGISTER 5
28 #define TEST_CONFIG_TASKS_TO_SPAWN 2
29
30 #define TEST_CONFIG_WAIT_MULTIPLIER 5
31
32 // The initial logging "initializing test" is to ensure mutex allocation is not counted against memory not being freed
33 // during teardown.
34 #define TEST_SETUP() \
35 ESP_LOGI(TAG, "initializing test"); \
36 size_t free_mem_before = heap_caps_get_free_size(MALLOC_CAP_DEFAULT); \
37 test_setup(); \
38 s_test_core_id = xPortGetCoreID(); \
39 s_test_priority = uxTaskPriorityGet(NULL);
40
41 #define TEST_TEARDOWN() \
42 test_teardown(); \
43 vTaskDelay(pdMS_TO_TICKS(CONFIG_ESP_INT_WDT_TIMEOUT_MS * TEST_CONFIG_WAIT_MULTIPLIER)); \
44 TEST_ASSERT_EQUAL(free_mem_before, heap_caps_get_free_size(MALLOC_CAP_DEFAULT));
45
46 typedef struct {
47 void* data;
48 SemaphoreHandle_t start;
49 SemaphoreHandle_t done;
50 } task_arg_t;
51
52 typedef struct {
53 esp_event_base_t base;
54 int32_t id;
55 esp_event_handler_t* handles;
56 int32_t num;
57 esp_event_loop_handle_t loop;
58 bool is_registration;
59 } handler_registration_data_t;
60
61 typedef struct {
62 esp_event_base_t base;
63 int32_t id;
64 esp_event_loop_handle_t loop;
65 int32_t num;
66 } post_event_data_t;
67
68 typedef struct {
69 int performed;
70 int expected;
71 SemaphoreHandle_t done;
72 } performance_data_t;
73
74 typedef struct {
75 void* data;
76 SemaphoreHandle_t mutex;
77 } simple_arg_t;
78
79 typedef struct {
80 esp_event_handler_instance_t *context;
81 void* data;
82 } instance_unregister_data_t;
83
84 typedef struct {
85 int *arr;
86 int index;
87 } ordered_data_t;
88
89 static BaseType_t s_test_core_id;
90 static UBaseType_t s_test_priority;
91
92 ESP_EVENT_DECLARE_BASE(s_test_base1);
93 ESP_EVENT_DECLARE_BASE(s_test_base2);
94
95 ESP_EVENT_DEFINE_BASE(s_test_base1);
96 ESP_EVENT_DEFINE_BASE(s_test_base2);
97
98 enum {
99 TEST_EVENT_BASE1_EV1,
100 TEST_EVENT_BASE1_EV2,
101 TEST_EVENT_BASE1_MAX
102 };
103
104 enum {
105 TEST_EVENT_BASE2_EV1,
106 TEST_EVENT_BASE2_EV2,
107 TEST_EVENT_BASE2_MAX
108 };
109
test_event_get_core(void)110 static BaseType_t test_event_get_core(void)
111 {
112 static int calls = 0;
113
114 if (portNUM_PROCESSORS > 1) {
115 return (s_test_core_id + calls++) % portNUM_PROCESSORS;
116 } else {
117 return s_test_core_id;
118 }
119 }
120
test_event_get_default_loop_args(void)121 static esp_event_loop_args_t test_event_get_default_loop_args(void)
122 {
123 esp_event_loop_args_t loop_config = {
124 .queue_size = CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE,
125 .task_name = "loop",
126 .task_priority = s_test_priority,
127 .task_stack_size = 2048,
128 .task_core_id = test_event_get_core()
129 };
130
131 return loop_config;
132 }
133
test_event_simple_handler(void * event_handler_arg,esp_event_base_t event_base,int32_t event_id,void * event_data)134 static void test_event_simple_handler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
135 {
136 if (!event_handler_arg) {
137 return;
138 }
139 simple_arg_t* arg = (simple_arg_t*) event_handler_arg;
140 xSemaphoreTake(arg->mutex, portMAX_DELAY);
141
142 int* count = (int*) arg->data;
143
144 if (event_data == NULL) {
145 (*count)++;
146 } else {
147 (*count) += *((int*) event_data);
148 }
149
150 xSemaphoreGive(arg->mutex);
151 }
152
test_event_ordered_dispatch(void * event_handler_arg,esp_event_base_t event_base,int32_t event_id,void * event_data)153 static void test_event_ordered_dispatch(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
154 {
155 int *arg = (int*) event_handler_arg;
156 ordered_data_t *data = *((ordered_data_t**) (event_data));
157
158 data->arr[data->index++] = *arg;
159 }
160
test_event_performance_handler(void * event_handler_arg,esp_event_base_t event_base,int32_t event_id,void * event_data)161 static void test_event_performance_handler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
162 {
163 performance_data_t* data = (performance_data_t*) event_handler_arg;
164
165 data->performed++;
166
167 if (data->performed >= data->expected) {
168 xSemaphoreGive(data->done);
169 }
170 }
171
test_event_post_task(void * args)172 static void test_event_post_task(void* args)
173 {
174 task_arg_t* arg = (task_arg_t*) args;
175 post_event_data_t* data = arg->data;
176
177 xSemaphoreTake(arg->start, portMAX_DELAY);
178
179 for (int i = 0; i < data->num; i++) {
180 TEST_ESP_OK(esp_event_post_to(data->loop, data->base, data->id, NULL, 0, portMAX_DELAY));
181 vTaskDelay(1);
182 }
183
184 xSemaphoreGive(arg->done);
185
186 vTaskDelete(NULL);
187 }
188
test_event_simple_handler_registration_task(void * args)189 static void test_event_simple_handler_registration_task(void* args)
190 {
191 task_arg_t* arg = (task_arg_t*) args;
192 handler_registration_data_t* data = (handler_registration_data_t*) arg->data;
193
194 xSemaphoreTake(arg->start, portMAX_DELAY);
195
196 for(int i = 0; i < data->num; i++) {
197 if (data->is_registration) {
198 TEST_ESP_OK(esp_event_handler_register_with(data->loop, data->base, data->id, data->handles[i], NULL));
199 } else {
200 TEST_ESP_OK(esp_event_handler_unregister_with(data->loop, data->base, data->id, data->handles[i]));
201 }
202 vTaskDelay(1);
203 }
204
205 xSemaphoreGive(arg->done);
206
207 vTaskDelete(NULL);
208 }
209
test_handler_post_w_task(void * event_handler_arg,esp_event_base_t event_base,int32_t event_id,void * event_data)210 static void test_handler_post_w_task(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
211 {
212 simple_arg_t* arg = (simple_arg_t*) event_handler_arg;
213
214 esp_event_loop_handle_t* loop = (esp_event_loop_handle_t*) event_data;
215 int* count = (int*) arg->data;
216
217 (*count)++;
218
219 if (*count <= 2) {
220 if (event_base == s_test_base1 && event_id == TEST_EVENT_BASE1_EV1) {
221 TEST_ESP_OK(esp_event_post_to(*loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
222 } else{
223 xSemaphoreGive((SemaphoreHandle_t) arg->mutex);
224 }
225 } else {
226 // Test that once the queue is full and the handler attempts to post to the same loop,
227 // posting does not block indefinitely.
228 if (event_base == s_test_base1 && event_id == TEST_EVENT_BASE1_EV1) {
229 xSemaphoreTake((SemaphoreHandle_t) arg->mutex, portMAX_DELAY);
230 TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, esp_event_post_to(*loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
231 }
232 }
233 }
234
test_handler_post_wo_task(void * event_handler_arg,esp_event_base_t event_base,int32_t event_id,void * event_data)235 static void test_handler_post_wo_task(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
236 {
237 simple_arg_t* arg = (simple_arg_t*) event_handler_arg;
238
239 esp_event_loop_handle_t* loop = (esp_event_loop_handle_t*) event_data;
240 int* count = (int*) arg->data;
241
242 (*count)++;
243
244 if (*count <= 2) {
245 if (event_base == s_test_base1 && event_id == TEST_EVENT_BASE1_EV1) {
246 TEST_ESP_OK(esp_event_post_to(*loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
247 } else{
248 xSemaphoreGive((SemaphoreHandle_t) arg->mutex);
249 }
250 } else {
251 // Test that once the queue is full and the handler attempts to post to the same loop,
252 // posting does not block indefinitely.
253 if (event_base == s_test_base1 && event_id == TEST_EVENT_BASE1_EV1) {
254 xSemaphoreTake((SemaphoreHandle_t) arg->mutex, portMAX_DELAY);
255 TEST_ESP_OK(esp_event_post_to(*loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
256 TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, esp_event_post_to(*loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
257 }
258 }
259 }
260
test_handler_unregister_itself(void * event_handler_arg,esp_event_base_t event_base,int32_t event_id,void * event_data)261 static void test_handler_unregister_itself(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
262 {
263 esp_event_loop_handle_t* loop = (esp_event_loop_handle_t*) event_data;
264 int* unregistered = (int*) event_handler_arg;
265
266 (*unregistered) += (event_base == s_test_base1 ? 0 : 10) + event_id + 1;
267
268 // Unregister this handler for this event
269 TEST_ESP_OK(esp_event_handler_unregister_with(*loop, event_base, event_id, test_handler_unregister_itself));
270 }
271
test_handler_instance_unregister_itself(void * event_handler_arg,esp_event_base_t event_base,int32_t event_id,void * event_data)272 static void test_handler_instance_unregister_itself(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
273 {
274 esp_event_loop_handle_t* loop = (esp_event_loop_handle_t*) event_data;
275 instance_unregister_data_t *unregister_data = (instance_unregister_data_t*) event_handler_arg;
276 esp_event_handler_instance_t *context = (esp_event_handler_instance_t*) unregister_data->context;
277 int *count = (int*) unregister_data->data;
278
279 (*count)++;
280
281 // Unregister this handler for this event
282 TEST_ESP_OK(esp_event_handler_instance_unregister_with(*loop, event_base, event_id, *context));
283 }
284
test_post_from_handler_loop_task(void * args)285 static void test_post_from_handler_loop_task(void* args)
286 {
287 esp_event_loop_handle_t event_loop = (esp_event_loop_handle_t) args;
288
289 while(1) {
290 TEST_ESP_OK(esp_event_loop_run(event_loop, portMAX_DELAY));
291 }
292 }
293
test_setup(void)294 static void test_setup(void)
295 {
296 TEST_ASSERT_TRUE(TEST_CONFIG_TASKS_TO_SPAWN >= 2);
297 TEST_ESP_OK(esp_event_loop_create_default());
298 }
299
test_teardown(void)300 static void test_teardown(void)
301 {
302 TEST_ESP_OK(esp_event_loop_delete_default());
303 }
304
305 #define TIMER_DIVIDER 16 // Hardware timer clock divider
306 #define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds
307 #define TIMER_INTERVAL0_SEC (2.0) // sample test interval for the first timer
308
309 TEST_CASE("can create and delete event loops", "[event]")
310 {
311 /* this test aims to verify that:
312 * - creating loops with and without a task succeeds
313 * - event queue can accomodate the set queue size, and drops the post when exceeded
314 * - deleting loops with unconsumed posts and unregistered handlers (when unregistration is enabled) does not leak memory */
315
316 TEST_SETUP();
317
318 esp_event_loop_handle_t loop1; // with dedicated task
319 esp_event_loop_handle_t loop2; // without dedicated task
320 esp_event_loop_handle_t loop3; // with leftover post and handlers
321
322 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
323
324 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop1));
325
326 loop_args.task_name = NULL;
327 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop2));
328 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop3));
329
330 TEST_ESP_OK(esp_event_handler_register_with(loop3, s_test_base1, TEST_EVENT_BASE1_EV1, (void*) 0x00000001, NULL));
331 TEST_ESP_OK(esp_event_handler_register_with(loop3, s_test_base1, TEST_EVENT_BASE1_EV2, (void*) 0x00000002, NULL));
332 TEST_ESP_OK(esp_event_handler_register_with(loop3, s_test_base2, TEST_EVENT_BASE1_EV1, (void*) 0x00000003, NULL));
333
334 for (int i = 0; i < loop_args.queue_size; i++) {
335 int mod = i % 4;
336
337 switch(mod) {
338 case 0:
339 TEST_ESP_OK(esp_event_post_to(loop3, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
340 break;
341 case 1:
342 TEST_ESP_OK(esp_event_post_to(loop3, s_test_base2, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
343 break;
344 case 2:
345 TEST_ESP_OK(esp_event_post_to(loop3, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
346 break;
347 case 3:
348 TEST_ESP_OK(esp_event_post_to(loop3, s_test_base2, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
349 break;
350 default:
351 break;
352 }
353 }
354
355 TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, esp_event_post_to(loop3, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, pdMS_TO_TICKS(10)));
356
357 TEST_ESP_OK(esp_event_loop_delete(loop1));
358 TEST_ESP_OK(esp_event_loop_delete(loop2));
359 TEST_ESP_OK(esp_event_loop_delete(loop3));
360
361 TEST_TEARDOWN();
362 }
363
364 TEST_CASE("registering event handler instance without instance context works", "[event]") {
365 TEST_SETUP();
366
367 esp_event_loop_handle_t loop;
368
369 int count_1 = 0;
370
371 simple_arg_t arg_1 = {
372 .data = &count_1,
373 .mutex = xSemaphoreCreateMutex()
374 };
375
376 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
377
378 loop_args.task_name = NULL;
379 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
380
381 TEST_ESP_OK(esp_event_handler_instance_register_with(loop, ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, test_event_simple_handler, &arg_1, NULL));
382
383 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
384
385 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
386
387 TEST_ASSERT_EQUAL(1, count_1);
388
389 TEST_ESP_OK(esp_event_loop_delete(loop));
390
391 vSemaphoreDelete(arg_1.mutex);
392
393 TEST_TEARDOWN();
394 }
395
396 TEST_CASE("registering event twice with same handler yields updated handler arg", "[event]") {
397 TEST_SETUP();
398
399 esp_event_loop_handle_t loop;
400
401 int count = 0;
402
403 simple_arg_t arg = {
404 .data = &count,
405 .mutex = xSemaphoreCreateMutex()
406 };
407
408 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
409
410 loop_args.task_name = NULL;
411 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
412
413 /* Register the handler twice to the same base and id but with a different argument (expects to return ESP_OK and log a warning)
414 * This aims to verify: 1) Handler's argument to be updated
415 * 2) Registration not to leak memory
416 */
417 TEST_ESP_OK(esp_event_handler_register_with(loop, ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, test_event_simple_handler, NULL));
418 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
419 // exec loop, no handler data: count stays 0
420 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
421 TEST_ASSERT_EQUAL(0, count);
422
423 // overriding the former registration of the same event
424 TEST_ESP_OK(esp_event_handler_register_with(loop, ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, test_event_simple_handler, &arg));
425 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
426 // exec loop, registered handler data exists: count increases
427 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
428 TEST_ASSERT_EQUAL(1, count);
429
430 TEST_ESP_OK(esp_event_loop_delete(loop));
431
432 vSemaphoreDelete(arg.mutex);
433
434 TEST_TEARDOWN();
435 }
436
437 TEST_CASE("registering event handler instance twice works", "[event]") {
438 TEST_SETUP();
439
440 esp_event_loop_handle_t loop;
441
442 int count_1 = 0;
443 int count_2 = 0;
444
445 simple_arg_t arg_1 = {
446 .data = &count_1,
447 .mutex = xSemaphoreCreateMutex()
448 };
449
450 simple_arg_t arg_2 = {
451 .data = &count_2,
452 .mutex = xSemaphoreCreateMutex()
453 };
454
455 esp_event_handler_instance_t ctx_1;
456 esp_event_handler_instance_t ctx_2;
457
458 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
459
460 loop_args.task_name = NULL;
461 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
462
463 TEST_ESP_OK(esp_event_handler_instance_register_with(loop, ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, test_event_simple_handler, &arg_1, &ctx_1));
464 TEST_ESP_OK(esp_event_handler_instance_register_with(loop, ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, test_event_simple_handler, &arg_2, &ctx_2));
465
466 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
467
468 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
469
470 TEST_ASSERT_EQUAL(1, count_1);
471 TEST_ASSERT_EQUAL(1, count_2);
472
473 TEST_ESP_OK(esp_event_loop_delete(loop));
474
475 vSemaphoreDelete(arg_1.mutex);
476 vSemaphoreDelete(arg_2.mutex);
477
478 TEST_TEARDOWN();
479 }
480
481 TEST_CASE("registering with ANY_BASE but specific ID fails", "[event]") {
482 TEST_SETUP();
483
484 esp_event_loop_handle_t loop;
485
486 int count = 0;
487
488 simple_arg_t arg = {
489 .data = &count,
490 .mutex = xSemaphoreCreateMutex()
491 };
492
493 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
494
495 loop_args.task_name = NULL;
496 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
497
498 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_handler_register_with(loop, ESP_EVENT_ANY_BASE, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg));
499 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
500
501 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
502
503 TEST_ASSERT_EQUAL(0, count);
504
505 TEST_ESP_OK(esp_event_loop_delete(loop));
506
507 vSemaphoreDelete(arg.mutex);
508
509 TEST_TEARDOWN();
510 }
511
512 TEST_CASE("registering instance with ANY_BASE but specific ID fails", "[event]") {
513 TEST_SETUP();
514
515 esp_event_loop_handle_t loop;
516
517 int count = 0;
518 esp_event_handler_instance_t ctx;
519
520 simple_arg_t arg = {
521 .data = &count,
522 .mutex = xSemaphoreCreateMutex()
523 };
524
525 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
526
527 loop_args.task_name = NULL;
528 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
529
530 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_handler_instance_register_with(loop, ESP_EVENT_ANY_BASE, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg, &ctx));
531 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
532
533 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
534
535 TEST_ASSERT_EQUAL(0, count);
536
537 TEST_ESP_OK(esp_event_loop_delete(loop));
538
539 vSemaphoreDelete(arg.mutex);
540
541 TEST_TEARDOWN();
542 }
543
544 TEST_CASE("Check registering ANY_ID", "[event]") {
545 TEST_SETUP();
546
547 esp_event_loop_handle_t loop;
548
549 int count = 0;
550
551 simple_arg_t arg = {
552 .data = &count,
553 .mutex = xSemaphoreCreateMutex()
554 };
555
556 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
557
558 loop_args.task_name = NULL;
559 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
560
561 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, ESP_EVENT_ANY_ID, test_event_simple_handler, &arg));
562
563 // handler shouldn't be triggered with different base
564 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
565 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
566 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
567 TEST_ASSERT_EQUAL(0, count);
568
569 // for all events with correct base, it should be triggered
570 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
571 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
572 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
573 TEST_ASSERT_EQUAL(2, count);
574
575 TEST_ESP_OK(esp_event_loop_delete(loop));
576
577 vSemaphoreDelete(arg.mutex);
578
579 TEST_TEARDOWN();
580 }
581
582 TEST_CASE("Check registering instance with ANY_ID", "[event]") {
583 TEST_SETUP();
584
585 esp_event_loop_handle_t loop;
586
587 int count = 0;
588
589 simple_arg_t arg = {
590 .data = &count,
591 .mutex = xSemaphoreCreateMutex()
592 };
593
594 esp_event_handler_instance_t ctx;
595
596 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
597
598 loop_args.task_name = NULL;
599 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
600
601 TEST_ESP_OK(esp_event_handler_instance_register_with(loop, s_test_base1, ESP_EVENT_ANY_ID, test_event_simple_handler, &arg, &ctx));
602
603 // handler shouldn't be triggered with different base
604 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
605 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
606 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
607 TEST_ASSERT_EQUAL(0, count);
608
609 // for all events with correct base, it should be triggered
610 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
611 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
612 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
613 TEST_ASSERT_EQUAL(2, count);
614
615 TEST_ESP_OK(esp_event_loop_delete(loop));
616
617 vSemaphoreDelete(arg.mutex);
618
619 TEST_TEARDOWN();
620 }
621
622 TEST_CASE("Check registering specific event", "[event]") {
623 TEST_SETUP();
624
625 esp_event_loop_handle_t loop;
626
627 int count = 0;
628
629 simple_arg_t arg = {
630 .data = &count,
631 .mutex = xSemaphoreCreateMutex()
632 };
633
634 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
635
636 loop_args.task_name = NULL;
637 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
638
639 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg));
640
641 // handler should not be triggered with different base
642 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
643 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
644 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
645 TEST_ASSERT_EQUAL(0, count);
646
647 // for incorrect id, it should not be triggered
648 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
649 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
650 TEST_ASSERT_EQUAL(0, count);
651
652 // for correct event and base, it should be triggered
653 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
654 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
655 TEST_ASSERT_EQUAL(1, count);
656
657 TEST_ESP_OK(esp_event_loop_delete(loop));
658
659 vSemaphoreDelete(arg.mutex);
660
661 TEST_TEARDOWN();
662 }
663
664 TEST_CASE("Check registering instance with specific event", "[event]") {
665 TEST_SETUP();
666
667 esp_event_loop_handle_t loop;
668
669 int count = 0;
670
671 simple_arg_t arg = {
672 .data = &count,
673 .mutex = xSemaphoreCreateMutex()
674 };
675
676 esp_event_handler_instance_t ctx;
677
678 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
679
680 loop_args.task_name = NULL;
681 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
682
683 TEST_ESP_OK(esp_event_handler_instance_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg, &ctx));
684
685 // handler should not be triggered with different base
686 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
687 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
688 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
689 TEST_ASSERT_EQUAL(0, count);
690
691 // for incorrect id, it should not be triggered
692 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
693 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
694 TEST_ASSERT_EQUAL(0, count);
695
696 // for correct event and base, it should be triggered
697 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
698 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
699 TEST_ASSERT_EQUAL(1, count);
700
701 TEST_ESP_OK(esp_event_loop_delete(loop));
702
703 vSemaphoreDelete(arg.mutex);
704
705 TEST_TEARDOWN();
706 }
707
708 TEST_CASE("Specific event is not called when no correct events are posted", "[event]") {
709 TEST_SETUP();
710
711 esp_event_loop_handle_t loop;
712
713 int count = 0;
714
715 simple_arg_t arg = {
716 .data = &count,
717 .mutex = xSemaphoreCreateMutex()
718 };
719
720 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
721
722 loop_args.task_name = NULL;
723 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
724
725 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg));
726
727 // handler should not be triggered by any of these postings
728 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
729 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
730 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
731 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
732 TEST_ASSERT_EQUAL(0, count);
733
734 // Post unknown events.
735 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_MAX, NULL, 0, portMAX_DELAY));
736 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE2_MAX, NULL, 0, portMAX_DELAY));
737 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
738 TEST_ASSERT_EQUAL(0, count);
739
740 TEST_ESP_OK(esp_event_loop_delete(loop));
741
742 vSemaphoreDelete(arg.mutex);
743
744 TEST_TEARDOWN();
745 }
746
747 TEST_CASE("Specific event instance is not called when no correct events are posted", "[event]") {
748 TEST_SETUP();
749
750 esp_event_loop_handle_t loop;
751
752 int count = 0;
753
754 simple_arg_t arg = {
755 .data = &count,
756 .mutex = xSemaphoreCreateMutex()
757 };
758
759 esp_event_handler_instance_t ctx;
760
761 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
762
763 loop_args.task_name = NULL;
764 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
765
766 TEST_ESP_OK(esp_event_handler_instance_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg, &ctx));
767
768 // handler should not be triggered by any of these postings
769 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
770 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
771 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
772 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
773 TEST_ASSERT_EQUAL(0, count);
774
775 // Post unknown events.
776 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_MAX, NULL, 0, portMAX_DELAY));
777 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE2_MAX, NULL, 0, portMAX_DELAY));
778 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
779 TEST_ASSERT_EQUAL(0, count);
780
781 TEST_ESP_OK(esp_event_loop_delete(loop));
782
783 vSemaphoreDelete(arg.mutex);
784
785 TEST_TEARDOWN();
786 }
787
788 TEST_CASE("can register/unregister handlers for all events/all events for a specific base", "[event]")
789 {
790 /* this test aims to verify that handlers can be registered to be called on all events
791 * or for all events with specific bases */
792
793 TEST_SETUP();
794
795 esp_event_loop_handle_t loop;
796
797 int count = 0;
798
799 simple_arg_t arg = {
800 .data = &count,
801 .mutex = xSemaphoreCreateMutex()
802 };
803
804 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
805
806 loop_args.task_name = NULL;
807 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
808
809 /* Register the handler twice to the same base and id but with a different argument (expects to return ESP_OK and log a warning)
810 * This aims to verify: 1) Handler's argument to be updated
811 * 2) Registration not to leak memory
812 */
813 TEST_ESP_OK(esp_event_handler_register_with(loop, ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, test_event_simple_handler, NULL));
814 TEST_ESP_OK(esp_event_handler_register_with(loop, ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, test_event_simple_handler, &arg));
815
816 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, ESP_EVENT_ANY_ID, test_event_simple_handler, &arg));
817 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_handler_register_with(loop, ESP_EVENT_ANY_BASE, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg));
818 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg));
819 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV2, test_event_simple_handler, &arg));
820 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base2, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg));
821
822 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_post_to(loop, ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, NULL, 0, portMAX_DELAY));
823 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_post_to(loop, s_test_base1, ESP_EVENT_ANY_ID, NULL, 0, portMAX_DELAY));
824 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_post_to(loop, ESP_EVENT_ANY_BASE, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
825 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY)); // exec loop, base and id level (+3)
826 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY)); // exec loop, base and id level (+3)
827
828 // Post unknown events. Respective loop level and base level handlers should still execute.
829 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_MAX, NULL, 0, portMAX_DELAY)); // exec loop and base level (+2)
830 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE2_MAX, NULL, 0, portMAX_DELAY)); // exec loop level (+1)
831
832 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
833
834 TEST_ASSERT_EQUAL(9, count); // 3 + 3 + 2 + 1
835
836 TEST_ESP_OK(esp_event_loop_delete(loop));
837
838 vSemaphoreDelete(arg.mutex);
839
840 TEST_TEARDOWN();
841 }
842
843 TEST_CASE("can unregister handler", "[event]")
844 {
845 /* this test aims to verify that unregistered handlers no longer execute when events are raised */
846
847 TEST_SETUP();
848
849 esp_event_loop_handle_t loop;
850 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
851
852 loop_args.task_name = NULL;
853 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
854
855 int count = 0;
856
857 simple_arg_t arg = {
858 .data = &count,
859 .mutex = xSemaphoreCreateMutex()
860 };
861
862 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg));
863 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base2, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg));
864
865 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
866 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
867
868 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
869
870 TEST_ASSERT_EQUAL(2, count);
871
872 TEST_ESP_OK(esp_event_handler_unregister_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_event_simple_handler));
873
874 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
875 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
876
877 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
878
879 TEST_ASSERT_EQUAL(3, count);
880
881 TEST_ESP_OK(esp_event_loop_delete(loop));
882
883 vSemaphoreDelete(arg.mutex);
884
885 TEST_TEARDOWN();
886 }
887
888 TEST_CASE("can unregister handler instance", "[event]")
889 {
890 /* this test aims to verify that unregistered handlers no longer execute when events are raised */
891
892 TEST_SETUP();
893
894 esp_event_loop_handle_t loop;
895 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
896
897 loop_args.task_name = NULL;
898 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
899
900 int count = 0;
901
902 simple_arg_t arg = {
903 .data = &count,
904 .mutex = xSemaphoreCreateMutex()
905 };
906
907 esp_event_handler_instance_t ctx;
908
909 TEST_ESP_OK(esp_event_handler_instance_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg, &ctx));
910
911 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
912
913 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
914
915 TEST_ASSERT_EQUAL(1, count);
916
917 TEST_ESP_OK(esp_event_handler_instance_unregister_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, ctx));
918
919 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
920
921 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
922
923 TEST_ASSERT_EQUAL(1, count);
924
925 TEST_ESP_OK(esp_event_loop_delete(loop));
926
927 vSemaphoreDelete(arg.mutex);
928
929 TEST_TEARDOWN();
930 }
931
932 TEST_CASE("handler can unregister itself", "[event]")
933 {
934 /* this test aims to verify that handlers can unregister themselves */
935
936 TEST_SETUP();
937
938 esp_event_loop_handle_t loop;
939 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
940
941 loop_args.task_name = NULL;
942 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
943
944 int unregistered = 0;
945
946 /*
947 * s_test_base1, ev1 = 1
948 * s_test_base1, ev2 = 2
949 * s_test_base2, ev1 = 11
950 * s_test_base2, ev2 = 12
951 */
952 int expected_unregistered = 0;
953
954 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_handler_unregister_itself, &unregistered));
955 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV2, test_handler_unregister_itself, &unregistered));
956 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base2, TEST_EVENT_BASE2_EV1, test_handler_unregister_itself, &unregistered));
957 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base2, TEST_EVENT_BASE2_EV2, test_handler_unregister_itself, &unregistered));
958
959 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV2, &loop, sizeof(loop), portMAX_DELAY));
960 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
961 expected_unregistered = 2; // base1, ev2
962 TEST_ASSERT_EQUAL(expected_unregistered, unregistered);
963
964 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, &loop, sizeof(loop), portMAX_DELAY));
965 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE2_EV1, &loop, sizeof(loop), portMAX_DELAY));
966 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
967 expected_unregistered += 1 + 11; // base1, ev1 + base2, ev1
968 TEST_ASSERT_EQUAL(expected_unregistered, unregistered);
969
970 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE2_EV2, &loop, sizeof(loop), portMAX_DELAY));
971 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
972 expected_unregistered += 12; // base2, ev2
973 TEST_ASSERT_EQUAL(expected_unregistered, unregistered);
974
975 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, &loop, sizeof(loop), portMAX_DELAY));
976 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV2, &loop, sizeof(loop), portMAX_DELAY));
977 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE2_EV1, &loop, sizeof(loop), portMAX_DELAY));
978 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE2_EV2, &loop, sizeof(loop), portMAX_DELAY));
979 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
980 TEST_ASSERT_EQUAL(expected_unregistered, unregistered); // all handlers unregistered
981
982 TEST_ESP_OK(esp_event_loop_delete(loop));
983
984 TEST_TEARDOWN();
985 }
986
987 TEST_CASE("handler instance can unregister itself", "[event]")
988 {
989 /* this test aims to verify that handlers can unregister themselves */
990
991 TEST_SETUP();
992
993 esp_event_loop_handle_t loop;
994 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
995
996 loop_args.task_name = NULL;
997 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
998
999 esp_event_handler_instance_t ctx;
1000
1001 int count = 0;
1002
1003 instance_unregister_data_t instance_data = {
1004 .context = &ctx,
1005 .data = &count
1006 };
1007
1008 TEST_ESP_OK(esp_event_handler_instance_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_handler_instance_unregister_itself, &instance_data, &ctx));
1009
1010 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, &loop, sizeof(loop), portMAX_DELAY));
1011 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1012 TEST_ASSERT_EQUAL(1, count);
1013
1014 vTaskDelay(1000);
1015
1016 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, &loop, sizeof(loop), portMAX_DELAY));
1017 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1018 TEST_ASSERT_EQUAL(1, count);
1019
1020 TEST_ESP_OK(esp_event_loop_delete(loop));
1021
1022 TEST_TEARDOWN();
1023 }
1024
1025 TEST_CASE("can exit running loop at approximately the set amount of time", "[event]")
1026 {
1027 /* this test aims to verify that running loop does not block indefinitely in cases where
1028 * events are posted frequently */
1029
1030 TEST_SETUP();
1031
1032 esp_event_loop_handle_t loop;
1033 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1034
1035 loop_args.task_name = NULL;
1036 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
1037
1038 performance_data_t handler_data = {
1039 .performed = 0,
1040 .expected = INT32_MAX,
1041 .done = xSemaphoreCreateBinary()
1042 };
1043
1044 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_event_performance_handler, &handler_data));
1045
1046 post_event_data_t post_event_data = {
1047 .base = s_test_base1,
1048 .id = TEST_EVENT_BASE1_EV1,
1049 .loop = loop,
1050 .num = INT32_MAX
1051 };
1052
1053 task_arg_t post_event_arg = {
1054 .data = &post_event_data,
1055 .done = xSemaphoreCreateBinary(),
1056 .start = xSemaphoreCreateBinary()
1057 };
1058
1059 TaskHandle_t post_task;
1060
1061 xTaskCreatePinnedToCore(test_event_post_task, "post", 2048, &post_event_arg, s_test_priority, &post_task, test_event_get_core());
1062
1063 int runtime_ms = 10;
1064 int runtime_us = runtime_ms * 1000;
1065
1066 int64_t start, diff;
1067 start = esp_timer_get_time();
1068
1069 xSemaphoreGive(post_event_arg.start);
1070
1071 // Run the loop for the runtime_ms set amount of time, regardless of whether events
1072 // are still being posted to the loop.
1073 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(runtime_ms)));
1074
1075 diff = (esp_timer_get_time() - start);
1076
1077 // Threshold is 25 percent.
1078 TEST_ASSERT(diff < runtime_us * 1.25f);
1079
1080 // Verify that the post task still continues
1081 TEST_ASSERT_NOT_EQUAL(pdTRUE, xSemaphoreTake(post_event_arg.done, pdMS_TO_TICKS(10)));
1082
1083 vSemaphoreDelete(post_event_arg.done);
1084 vSemaphoreDelete(post_event_arg.start);
1085 vSemaphoreDelete(handler_data.done);
1086 vTaskDelete(post_task);
1087
1088 TEST_ESP_OK(esp_event_loop_delete(loop));
1089
1090 TEST_TEARDOWN();
1091 }
1092
1093 TEST_CASE("can register/unregister handlers simultaneously", "[event]")
1094 {
1095 /* this test aims to verify that the event handlers list remains consistent despite
1096 * simultaneous access by differenct tasks */
1097
1098 TEST_SETUP();
1099
1100 const char* base = "base";
1101 int32_t id = 0;
1102
1103 esp_event_loop_handle_t loop;
1104 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1105
1106 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
1107
1108 ESP_LOGI(TAG, "registering handlers");
1109
1110 handler_registration_data_t* registration_data = calloc(TEST_CONFIG_TASKS_TO_SPAWN, sizeof(*registration_data));
1111 task_arg_t* registration_arg = calloc(TEST_CONFIG_TASKS_TO_SPAWN, sizeof(*registration_arg));
1112
1113 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1114 registration_data[i].base = base;
1115 registration_data[i].id = id;
1116 registration_data[i].loop = loop;
1117 registration_data[i].handles = calloc(TEST_CONFIG_ITEMS_TO_REGISTER, sizeof(esp_event_handler_t));
1118 registration_data[i].num = TEST_CONFIG_ITEMS_TO_REGISTER;
1119 registration_data[i].is_registration = true;
1120
1121 for (int j = 0; j < TEST_CONFIG_ITEMS_TO_REGISTER; j++) {
1122 registration_data[i].handles[j] = (void*) (i * TEST_CONFIG_ITEMS_TO_REGISTER) + (j + TEST_CONFIG_ITEMS_TO_REGISTER);
1123 }
1124
1125 registration_arg[i].start = xSemaphoreCreateBinary();
1126 registration_arg[i].done = xSemaphoreCreateBinary();
1127 registration_arg[i].data = ®istration_data[i];
1128
1129 xTaskCreatePinnedToCore(test_event_simple_handler_registration_task, "register", 2048, ®istration_arg[i], s_test_priority, NULL, test_event_get_core());
1130 }
1131
1132 // Give the semaphores to the spawned registration task
1133 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1134 xSemaphoreGive(registration_arg[i].start);
1135 }
1136
1137 // Take the same semaphores in order to proceed
1138 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1139 xSemaphoreTake(registration_arg[i].done, portMAX_DELAY);
1140 }
1141
1142 ESP_LOGI(TAG, "checking consistency of handlers list");
1143
1144 // Check consistency of events list
1145 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1146 for (int j = 0; j < TEST_CONFIG_ITEMS_TO_REGISTER; j++) {
1147 TEST_ASSERT_TRUE(esp_event_is_handler_registered(loop, base, id, registration_data[i].handles[j]));
1148 }
1149 }
1150
1151 ESP_LOGI(TAG, "unregistering handlers");
1152
1153 /* Test if tasks can unregister simultaneously */
1154
1155 // Unregister registered events
1156 handler_registration_data_t* unregistration_data = calloc(TEST_CONFIG_TASKS_TO_SPAWN, sizeof(*unregistration_data));
1157 task_arg_t* unregistration_arg = calloc(TEST_CONFIG_TASKS_TO_SPAWN, sizeof(*unregistration_arg));
1158
1159 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1160 unregistration_data[i].base = base;
1161 unregistration_data[i].id = id;
1162 unregistration_data[i].loop = loop;
1163 unregistration_data[i].handles = calloc(TEST_CONFIG_ITEMS_TO_REGISTER, sizeof(esp_event_handler_t));
1164 unregistration_data[i].num = TEST_CONFIG_ITEMS_TO_REGISTER;
1165 unregistration_data[i].is_registration = false;
1166
1167 memcpy(unregistration_data[i].handles, registration_data[i].handles, TEST_CONFIG_ITEMS_TO_REGISTER * sizeof(esp_event_handler_t));
1168
1169 unregistration_arg[i].data = &unregistration_data[i];
1170 unregistration_arg[i].start = xSemaphoreCreateBinary();
1171 unregistration_arg[i].done = xSemaphoreCreateBinary();
1172
1173 xTaskCreatePinnedToCore(test_event_simple_handler_registration_task, "unregister", 2048, &unregistration_arg[i], s_test_priority, NULL, test_event_get_core());
1174 }
1175
1176 // Give the semaphores to the spawned unregistration task
1177 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1178 xSemaphoreGive(unregistration_arg[i].start);
1179 }
1180
1181 // Take the same semaphores in order to proceed
1182 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1183 xSemaphoreTake(unregistration_arg[i].done, portMAX_DELAY);
1184 }
1185
1186 ESP_LOGI(TAG, "checking consistency of handlers list");
1187
1188 // Check consistency of events list
1189 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1190 for (int j = 0; j < TEST_CONFIG_ITEMS_TO_REGISTER; j++) {
1191 TEST_ASSERT_FALSE(esp_event_is_handler_registered(loop, base, id, registration_data[i].handles[j]));
1192 }
1193 }
1194
1195 // Do cleanup
1196 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1197 free(registration_data[i].handles);
1198 vSemaphoreDelete(registration_arg[i].start);
1199 vSemaphoreDelete(registration_arg[i].done);
1200
1201 free(unregistration_data[i].handles);
1202 vSemaphoreDelete(unregistration_arg[i].start);
1203 vSemaphoreDelete(unregistration_arg[i].done);
1204 }
1205
1206 free(registration_data);
1207 free(unregistration_data);
1208 free(registration_arg);
1209 free(unregistration_arg);
1210
1211 TEST_ESP_OK(esp_event_loop_delete(loop));
1212
1213 TEST_TEARDOWN();
1214 }
1215
1216 TEST_CASE("posting ANY_EVENT or ANY_ID fails", "[event]") {
1217 TEST_SETUP();
1218
1219 esp_event_loop_handle_t loop;
1220
1221 int count = 0;
1222
1223 simple_arg_t arg = {
1224 .data = &count,
1225 .mutex = xSemaphoreCreateMutex()
1226 };
1227
1228 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1229
1230 loop_args.task_name = NULL;
1231 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
1232
1233 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_post_to(loop, ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, NULL, 0, portMAX_DELAY));
1234 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_post_to(loop, s_test_base1, ESP_EVENT_ANY_ID, NULL, 0, portMAX_DELAY));
1235 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_post_to(loop, ESP_EVENT_ANY_BASE, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
1236
1237 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1238
1239 TEST_ASSERT_EQUAL(0, count);
1240
1241 TEST_ESP_OK(esp_event_loop_delete(loop));
1242
1243 vSemaphoreDelete(arg.mutex);
1244
1245 TEST_TEARDOWN();
1246 }
1247
1248 TEST_CASE("can post and run events", "[event]")
1249 {
1250 /* this test aims to verify that:
1251 * - multiple tasks can post to the queue simultaneously
1252 * - handlers recieve the appropriate handler arg and associated event data */
1253
1254 TEST_SETUP();
1255
1256 esp_event_loop_handle_t loop;
1257
1258 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1259
1260 loop_args.task_name = NULL;
1261 loop_args.queue_size = TEST_CONFIG_TASKS_TO_SPAWN * TEST_CONFIG_ITEMS_TO_REGISTER;
1262 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
1263
1264 int count = 0;
1265
1266 simple_arg_t arg = {
1267 .data = &count,
1268 .mutex = xSemaphoreCreateMutex()
1269 };
1270
1271 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg));
1272
1273 post_event_data_t* post_event_data = calloc(TEST_CONFIG_TASKS_TO_SPAWN, sizeof(*post_event_data));
1274 task_arg_t* post_event_arg = calloc(TEST_CONFIG_TASKS_TO_SPAWN, sizeof(*post_event_arg));
1275
1276 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++)
1277 {
1278 post_event_data[i].base = s_test_base1;
1279 post_event_data[i].id = TEST_EVENT_BASE1_EV1;
1280 post_event_data[i].loop = loop;
1281 post_event_data[i].num = TEST_CONFIG_ITEMS_TO_REGISTER;
1282
1283 post_event_arg[i].data = &post_event_data[i];
1284 post_event_arg[i].start = xSemaphoreCreateBinary();
1285 post_event_arg[i].done = xSemaphoreCreateBinary();
1286
1287 xTaskCreatePinnedToCore(test_event_post_task, "post", 2048, &post_event_arg[i], s_test_priority, NULL, test_event_get_core());
1288 }
1289
1290 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1291 xSemaphoreGive(post_event_arg[i].start);
1292 }
1293
1294 // Execute some events as they are posted
1295 for (int i = 0; i < (TEST_CONFIG_TASKS_TO_SPAWN * TEST_CONFIG_ITEMS_TO_REGISTER) / 2; i++) {
1296 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1297 }
1298
1299 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1300 xSemaphoreTake(post_event_arg[i].done, portMAX_DELAY);
1301 }
1302
1303 // Execute the rest
1304 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1305
1306 TEST_ASSERT_EQUAL(TEST_CONFIG_TASKS_TO_SPAWN * TEST_CONFIG_ITEMS_TO_REGISTER, count);
1307
1308 // Cleanup
1309 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1310 vSemaphoreDelete(post_event_arg[i].start);
1311 vSemaphoreDelete(post_event_arg[i].done);
1312 }
1313
1314 free(post_event_data);
1315 free(post_event_arg);
1316
1317 TEST_ESP_OK(esp_event_loop_delete(loop));
1318
1319 vSemaphoreDelete(arg.mutex);
1320
1321 TEST_TEARDOWN();
1322 }
1323
1324 TEST_CASE("can post and run events with instances", "[event]")
1325 {
1326 /* this test aims to verify that:
1327 * - multiple tasks can post to the queue simultaneously
1328 * - handlers recieve the appropriate handler arg and associated event data */
1329
1330 TEST_SETUP();
1331
1332 esp_event_loop_handle_t loop;
1333
1334 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1335
1336 loop_args.task_name = NULL;
1337 loop_args.queue_size = TEST_CONFIG_TASKS_TO_SPAWN * TEST_CONFIG_ITEMS_TO_REGISTER;
1338 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
1339
1340 int count = 0;
1341
1342 simple_arg_t arg = {
1343 .data = &count,
1344 .mutex = xSemaphoreCreateMutex()
1345 };
1346
1347 esp_event_handler_instance_t ctx;
1348
1349 TEST_ESP_OK(esp_event_handler_instance_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_event_simple_handler, &arg, &ctx));
1350
1351 post_event_data_t* post_event_data = calloc(TEST_CONFIG_TASKS_TO_SPAWN, sizeof(*post_event_data));
1352 task_arg_t* post_event_arg = calloc(TEST_CONFIG_TASKS_TO_SPAWN, sizeof(*post_event_arg));
1353
1354 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++)
1355 {
1356 post_event_data[i].base = s_test_base1;
1357 post_event_data[i].id = TEST_EVENT_BASE1_EV1;
1358 post_event_data[i].loop = loop;
1359 post_event_data[i].num = TEST_CONFIG_ITEMS_TO_REGISTER;
1360
1361 post_event_arg[i].data = &post_event_data[i];
1362 post_event_arg[i].start = xSemaphoreCreateBinary();
1363 post_event_arg[i].done = xSemaphoreCreateBinary();
1364
1365 xTaskCreatePinnedToCore(test_event_post_task, "post", 2048, &post_event_arg[i], s_test_priority, NULL, test_event_get_core());
1366 }
1367
1368 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1369 xSemaphoreGive(post_event_arg[i].start);
1370 }
1371
1372 // Execute some events as they are posted
1373 for (int i = 0; i < (TEST_CONFIG_TASKS_TO_SPAWN * TEST_CONFIG_ITEMS_TO_REGISTER) / 2; i++) {
1374 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1375 }
1376
1377 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1378 xSemaphoreTake(post_event_arg[i].done, portMAX_DELAY);
1379 }
1380
1381 // Execute the rest
1382 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1383
1384 TEST_ASSERT_EQUAL(TEST_CONFIG_TASKS_TO_SPAWN * TEST_CONFIG_ITEMS_TO_REGISTER, count);
1385
1386 // Cleanup
1387 for (int i = 0; i < TEST_CONFIG_TASKS_TO_SPAWN; i++) {
1388 vSemaphoreDelete(post_event_arg[i].start);
1389 vSemaphoreDelete(post_event_arg[i].done);
1390 }
1391
1392 free(post_event_data);
1393 free(post_event_arg);
1394
1395 TEST_ESP_OK(esp_event_loop_delete(loop));
1396
1397 vSemaphoreDelete(arg.mutex);
1398
1399 TEST_TEARDOWN();
1400 }
1401
loop_run_task(void * args)1402 static void loop_run_task(void* args)
1403 {
1404 esp_event_loop_handle_t event_loop = (esp_event_loop_handle_t) args;
1405
1406 while(1) {
1407 esp_event_loop_run(event_loop, portMAX_DELAY);
1408 }
1409 }
1410
performance_test(bool dedicated_task)1411 static void performance_test(bool dedicated_task)
1412 {
1413 // rand() seems to do a one-time allocation. Call it here so that the memory it allocates
1414 // is not counted as a leak.
1415 unsigned int _rand __attribute__((unused)) = rand();
1416
1417 TEST_SETUP();
1418
1419 const char test_base[] = "qwertyuiopasdfghjklzxvbnmmnbvcxz";
1420
1421 #define TEST_CONFIG_BASES (sizeof(test_base) - 1)
1422 #define TEST_CONFIG_IDS (TEST_CONFIG_BASES / 2)
1423
1424 // Create loop
1425 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1426 esp_event_loop_handle_t loop;
1427
1428 if (!dedicated_task) {
1429 loop_args.task_name = NULL;
1430 }
1431
1432 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
1433
1434 performance_data_t data;
1435
1436 // Register the handlers
1437 for (int base = 0; base < TEST_CONFIG_BASES; base++) {
1438 for (int id = 0; id < TEST_CONFIG_IDS; id++) {
1439 TEST_ESP_OK(esp_event_handler_register_with(loop, test_base + base, id, test_event_performance_handler, &data));
1440 }
1441 }
1442
1443 TaskHandle_t mtask = NULL;
1444
1445 if (!dedicated_task) {
1446 xTaskCreate(loop_run_task, "loop_run", loop_args.task_stack_size, (void*) loop, loop_args.task_priority, &mtask);
1447 }
1448
1449 // Perform performance test
1450 float running_sum = 0;
1451 float running_count = 0;
1452
1453 for (int bases = 1; bases <= TEST_CONFIG_BASES; bases *= 2) {
1454 for (int ids = 1; ids <= TEST_CONFIG_IDS; ids *= 2) {
1455
1456 data.performed = 0;
1457 data.expected = bases * ids;
1458 data.done = xSemaphoreCreateBinary();
1459
1460 // Generate randomized list of posts
1461 int post_bases[TEST_CONFIG_BASES];
1462 int post_ids[TEST_CONFIG_IDS];
1463
1464 for (int i = 0; i < bases; i++) {
1465 post_bases[i] = i;
1466 }
1467
1468 for (int i = 0; i < ids; i++) {
1469 post_ids[i] = i;
1470 }
1471
1472 for (int i = 0; i < bases; i++) {
1473 int rand_a = rand() % bases;
1474 int rand_b = rand() % bases;
1475
1476 int temp = post_bases[rand_a];
1477 post_bases[rand_a]= post_bases[rand_b];
1478 post_bases[rand_b] = temp;
1479 }
1480
1481 for (int i = 0; i < ids; i++) {
1482 int rand_a = rand() % ids;
1483 int rand_b = rand() % ids;
1484
1485 int temp = post_ids[rand_a];
1486 post_ids[rand_a]= post_ids[rand_b];
1487 post_ids[rand_b] = temp;
1488 }
1489
1490 // Post the events
1491 int64_t start = esp_timer_get_time();
1492 for (int base = 0; base < bases; base++) {
1493 for (int id = 0; id < ids; id++) {
1494 TEST_ESP_OK(esp_event_post_to(loop, test_base + post_bases[base], post_ids[id], NULL, 0, portMAX_DELAY));
1495 }
1496 }
1497
1498 xSemaphoreTake(data.done, portMAX_DELAY);
1499 int64_t elapsed = esp_timer_get_time() - start;
1500
1501 // Record data
1502 TEST_ASSERT_EQUAL(data.expected, data.performed);
1503
1504 running_count++;
1505 running_sum += data.performed / (elapsed / (1000000.0));
1506
1507 vSemaphoreDelete(data.done);
1508 }
1509 }
1510
1511 int average = (int) (running_sum / (running_count));
1512
1513 if (!dedicated_task) {
1514 ((esp_event_loop_instance_t*) loop)->task = mtask;
1515 }
1516
1517 TEST_ESP_OK(esp_event_loop_delete(loop));
1518
1519 TEST_TEARDOWN();
1520
1521 #ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
1522 ESP_LOGI(TAG, "events dispatched/second with profiling enabled: %d", average);
1523 // Enabling profiling will slow down event dispatch, so the set threshold
1524 // is not valid when it is enabled.
1525 #else
1526 #ifndef CONFIG_SPIRAM
1527 TEST_PERFORMANCE_GREATER_THAN(EVENT_DISPATCH, "%d", average);
1528 #else
1529 TEST_PERFORMANCE_GREATER_THAN(EVENT_DISPATCH_PSRAM, "%d", average);
1530 #endif // CONFIG_SPIRAM
1531 #endif // CONFIG_ESP_EVENT_LOOP_PROFILING
1532 }
1533
1534 TEST_CASE("performance test - dedicated task", "[event]")
1535 {
1536 performance_test(true);
1537 }
1538
1539 TEST_CASE("performance test - no dedicated task", "[event]")
1540 {
1541 performance_test(false);
1542 }
1543
1544 TEST_CASE("can post to loop from handler - dedicated task", "[event]")
1545 {
1546 TEST_SETUP();
1547
1548 esp_event_loop_handle_t loop_w_task;
1549
1550 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1551
1552 int count;
1553
1554 simple_arg_t arg = {
1555 .data = &count,
1556 .mutex = xSemaphoreCreateBinary()
1557 };
1558
1559 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop_w_task));
1560
1561 count = 0;
1562
1563 // Test that a handler can post to a different loop while there is still slots on the queue
1564 TEST_ESP_OK(esp_event_handler_register_with(loop_w_task, s_test_base1, TEST_EVENT_BASE1_EV1, test_handler_post_w_task, &arg));
1565 TEST_ESP_OK(esp_event_handler_register_with(loop_w_task, s_test_base1, TEST_EVENT_BASE1_EV2, test_handler_post_w_task, &arg));
1566
1567 TEST_ESP_OK(esp_event_post_to(loop_w_task, s_test_base1, TEST_EVENT_BASE1_EV1, &loop_w_task, sizeof(&loop_w_task), portMAX_DELAY));
1568
1569 xSemaphoreTake(arg.mutex, portMAX_DELAY);
1570
1571 TEST_ASSERT_EQUAL(2, count);
1572
1573 // Test that other tasks can still post while there is still slots in the queue, while handler is executing
1574 count = 100;
1575
1576 TEST_ESP_OK(esp_event_post_to(loop_w_task, s_test_base1, TEST_EVENT_BASE1_EV1, &loop_w_task, sizeof(&loop_w_task), portMAX_DELAY));
1577
1578 for (int i = 0; i < loop_args.queue_size; i++) {
1579 TEST_ESP_OK(esp_event_post_to(loop_w_task, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
1580 }
1581
1582 TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, esp_event_post_to(loop_w_task, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0,
1583 pdMS_TO_TICKS(CONFIG_ESP_INT_WDT_TIMEOUT_MS * TEST_CONFIG_WAIT_MULTIPLIER)));
1584
1585 xSemaphoreGive(arg.mutex);
1586
1587 vTaskDelay(pdMS_TO_TICKS(CONFIG_ESP_INT_WDT_TIMEOUT_MS * TEST_CONFIG_WAIT_MULTIPLIER));
1588
1589 TEST_ESP_OK(esp_event_loop_delete(loop_w_task));
1590
1591 vSemaphoreDelete(arg.mutex);
1592
1593 TEST_TEARDOWN();
1594 }
1595
1596 TEST_CASE("can post to loop from handler instance - dedicated task", "[event]")
1597 {
1598 TEST_SETUP();
1599
1600 esp_event_loop_handle_t loop_w_task;
1601
1602 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1603
1604 int count;
1605
1606 simple_arg_t arg = {
1607 .data = &count,
1608 .mutex = xSemaphoreCreateBinary()
1609 };
1610
1611 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop_w_task));
1612
1613 count = 0;
1614
1615 esp_event_handler_instance_t ctx_1;
1616 esp_event_handler_instance_t ctx_2;
1617
1618 // Test that a handler can post to a different loop while there is still slots on the queue
1619 TEST_ESP_OK(esp_event_handler_instance_register_with(loop_w_task, s_test_base1, TEST_EVENT_BASE1_EV1, test_handler_post_w_task, &arg, &ctx_1));
1620 TEST_ESP_OK(esp_event_handler_instance_register_with(loop_w_task, s_test_base1, TEST_EVENT_BASE1_EV2, test_handler_post_w_task, &arg, &ctx_2));
1621
1622 TEST_ESP_OK(esp_event_post_to(loop_w_task, s_test_base1, TEST_EVENT_BASE1_EV1, &loop_w_task, sizeof(&loop_w_task), portMAX_DELAY));
1623
1624 xSemaphoreTake(arg.mutex, portMAX_DELAY);
1625
1626 TEST_ASSERT_EQUAL(2, count);
1627
1628 // Test that other tasks can still post while there is still slots in the queue, while handler is executing
1629 count = 100;
1630
1631 TEST_ESP_OK(esp_event_post_to(loop_w_task, s_test_base1, TEST_EVENT_BASE1_EV1, &loop_w_task, sizeof(&loop_w_task), portMAX_DELAY));
1632
1633 for (int i = 0; i < loop_args.queue_size; i++) {
1634 TEST_ESP_OK(esp_event_post_to(loop_w_task, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
1635 }
1636
1637 TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, esp_event_post_to(loop_w_task, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0,
1638 pdMS_TO_TICKS(CONFIG_ESP_INT_WDT_TIMEOUT_MS * TEST_CONFIG_WAIT_MULTIPLIER)));
1639
1640 xSemaphoreGive(arg.mutex);
1641
1642 vTaskDelay(pdMS_TO_TICKS(CONFIG_ESP_INT_WDT_TIMEOUT_MS * TEST_CONFIG_WAIT_MULTIPLIER));
1643
1644 TEST_ESP_OK(esp_event_loop_delete(loop_w_task));
1645
1646 vSemaphoreDelete(arg.mutex);
1647
1648 TEST_TEARDOWN();
1649 }
1650
1651 TEST_CASE("can post to loop from handler - no dedicated task", "[event]")
1652 {
1653 TEST_SETUP();
1654
1655 esp_event_loop_handle_t loop_wo_task;
1656
1657 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1658
1659 int count;
1660
1661 simple_arg_t arg = {
1662 .data = &count,
1663 .mutex = xSemaphoreCreateBinary()
1664 };
1665
1666 count = 0;
1667
1668 loop_args.queue_size = 1;
1669 loop_args.task_name = NULL;
1670 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop_wo_task));
1671
1672 TaskHandle_t mtask;
1673
1674 xTaskCreate(test_post_from_handler_loop_task, "task", 2584, (void*) loop_wo_task, s_test_priority, &mtask);
1675
1676 // Test that a handler can post to a different loop while there is still slots on the queue
1677 TEST_ESP_OK(esp_event_handler_register_with(loop_wo_task, s_test_base1, TEST_EVENT_BASE1_EV1, test_handler_post_wo_task, &arg));
1678 TEST_ESP_OK(esp_event_handler_register_with(loop_wo_task, s_test_base1, TEST_EVENT_BASE1_EV2, test_handler_post_wo_task, &arg));
1679
1680 TEST_ESP_OK(esp_event_post_to(loop_wo_task, s_test_base1, TEST_EVENT_BASE1_EV1, &loop_wo_task, sizeof(&loop_wo_task), portMAX_DELAY));
1681
1682 xSemaphoreTake(arg.mutex, portMAX_DELAY);
1683
1684 TEST_ASSERT_EQUAL(2, count);
1685
1686 count = 100;
1687
1688 TEST_ESP_OK(esp_event_post_to(loop_wo_task, s_test_base1, TEST_EVENT_BASE1_EV1, &loop_wo_task, sizeof(&loop_wo_task), portMAX_DELAY));
1689
1690 vTaskDelay(pdMS_TO_TICKS(CONFIG_ESP_INT_WDT_TIMEOUT_MS * TEST_CONFIG_WAIT_MULTIPLIER));
1691
1692 // For loop without tasks, posting is more restrictive. Posting should wait until execution of handler finishes
1693 TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, esp_event_post_to(loop_wo_task, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0,
1694 pdMS_TO_TICKS(CONFIG_ESP_INT_WDT_TIMEOUT_MS * TEST_CONFIG_WAIT_MULTIPLIER)));
1695
1696 xSemaphoreGive(arg.mutex);
1697
1698 vTaskDelay(pdMS_TO_TICKS(CONFIG_ESP_INT_WDT_TIMEOUT_MS * TEST_CONFIG_WAIT_MULTIPLIER));
1699
1700 vTaskDelete(mtask);
1701
1702 TEST_ESP_OK(esp_event_loop_delete(loop_wo_task));
1703
1704 vSemaphoreDelete(arg.mutex);
1705
1706 TEST_TEARDOWN();
1707 }
1708
1709 TEST_CASE("can post to loop from handler instance - no dedicated task", "[event]")
1710 {
1711 TEST_SETUP();
1712
1713 esp_event_loop_handle_t loop_wo_task;
1714
1715 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1716
1717 int count;
1718
1719 simple_arg_t arg = {
1720 .data = &count,
1721 .mutex = xSemaphoreCreateBinary()
1722 };
1723
1724 count = 0;
1725
1726 esp_event_handler_instance_t ctx_1;
1727 esp_event_handler_instance_t ctx_2;
1728
1729 loop_args.queue_size = 1;
1730 loop_args.task_name = NULL;
1731 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop_wo_task));
1732
1733 TaskHandle_t mtask;
1734
1735 xTaskCreate(test_post_from_handler_loop_task, "task", 2584, (void*) loop_wo_task, s_test_priority, &mtask);
1736
1737 // Test that a handler can post to a different loop while there is still slots on the queue
1738 TEST_ESP_OK(esp_event_handler_instance_register_with(loop_wo_task, s_test_base1, TEST_EVENT_BASE1_EV1, test_handler_post_wo_task, &arg, &ctx_1));
1739 TEST_ESP_OK(esp_event_handler_instance_register_with(loop_wo_task, s_test_base1, TEST_EVENT_BASE1_EV2, test_handler_post_wo_task, &arg, &ctx_2));
1740
1741 TEST_ESP_OK(esp_event_post_to(loop_wo_task, s_test_base1, TEST_EVENT_BASE1_EV1, &loop_wo_task, sizeof(&loop_wo_task), portMAX_DELAY));
1742
1743 xSemaphoreTake(arg.mutex, portMAX_DELAY);
1744
1745 TEST_ASSERT_EQUAL(2, count);
1746
1747 count = 100;
1748
1749 TEST_ESP_OK(esp_event_post_to(loop_wo_task, s_test_base1, TEST_EVENT_BASE1_EV1, &loop_wo_task, sizeof(&loop_wo_task), portMAX_DELAY));
1750
1751 vTaskDelay(pdMS_TO_TICKS(CONFIG_ESP_INT_WDT_TIMEOUT_MS * TEST_CONFIG_WAIT_MULTIPLIER));
1752
1753 // For loop without tasks, posting is more restrictive. Posting should wait until execution of handler finishes
1754 TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, esp_event_post_to(loop_wo_task, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0,
1755 pdMS_TO_TICKS(CONFIG_ESP_INT_WDT_TIMEOUT_MS * TEST_CONFIG_WAIT_MULTIPLIER)));
1756
1757 xSemaphoreGive(arg.mutex);
1758
1759 vTaskDelay(pdMS_TO_TICKS(CONFIG_ESP_INT_WDT_TIMEOUT_MS * TEST_CONFIG_WAIT_MULTIPLIER));
1760
1761 vTaskDelete(mtask);
1762
1763 TEST_ESP_OK(esp_event_loop_delete(loop_wo_task));
1764
1765 vSemaphoreDelete(arg.mutex);
1766
1767 TEST_TEARDOWN();
1768 }
1769
test_event_simple_handler_template(void * handler_arg,esp_event_base_t base,int32_t id,void * event_arg)1770 static void test_event_simple_handler_template(void* handler_arg, esp_event_base_t base, int32_t id, void* event_arg)
1771 {
1772 int* count = (int*) handler_arg;
1773 (*count)++;
1774 }
1775
test_event_simple_handler_1(void * handler_arg,esp_event_base_t base,int32_t id,void * event_arg)1776 static void test_event_simple_handler_1(void* handler_arg, esp_event_base_t base, int32_t id, void* event_arg)
1777 {
1778 test_event_simple_handler_template(handler_arg, base, id, event_arg);
1779 }
1780
test_event_simple_handler_3(void * handler_arg,esp_event_base_t base,int32_t id,void * event_arg)1781 static void test_event_simple_handler_3(void* handler_arg, esp_event_base_t base, int32_t id, void* event_arg)
1782 {
1783 test_event_simple_handler_template(handler_arg, base, id, event_arg);
1784 }
1785
test_event_simple_handler_2(void * handler_arg,esp_event_base_t base,int32_t id,void * event_arg)1786 static void test_event_simple_handler_2(void* handler_arg, esp_event_base_t base, int32_t id, void* event_arg)
1787 {
1788 test_event_simple_handler_template(handler_arg, base, id, event_arg);
1789 }
1790
test_registration_from_handler_hdlr(void * handler_arg,esp_event_base_t base,int32_t id,void * event_arg)1791 static void test_registration_from_handler_hdlr(void* handler_arg, esp_event_base_t base, int32_t id, void* event_arg)
1792 {
1793 esp_event_loop_handle_t* loop = (esp_event_loop_handle_t*) event_arg;
1794 TEST_ESP_OK(esp_event_handler_register_with(*loop, s_test_base1, TEST_EVENT_BASE1_EV2, test_event_simple_handler_1, handler_arg));
1795 TEST_ESP_OK(esp_event_handler_register_with(*loop, s_test_base1, TEST_EVENT_BASE1_EV2, test_event_simple_handler_2, handler_arg));
1796 TEST_ESP_OK(esp_event_handler_register_with(*loop, s_test_base1, TEST_EVENT_BASE1_EV2, test_event_simple_handler_3, handler_arg));
1797 }
1798
test_unregistration_from_handler_hdlr(void * handler_arg,esp_event_base_t base,int32_t id,void * event_arg)1799 static void test_unregistration_from_handler_hdlr(void* handler_arg, esp_event_base_t base, int32_t id, void* event_arg)
1800 {
1801 esp_event_loop_handle_t* loop = (esp_event_loop_handle_t*) event_arg;
1802 TEST_ESP_OK(esp_event_handler_unregister_with(*loop, s_test_base1, TEST_EVENT_BASE1_EV2, test_event_simple_handler_1));
1803 TEST_ESP_OK(esp_event_handler_unregister_with(*loop, s_test_base1, TEST_EVENT_BASE1_EV2, test_event_simple_handler_2));
1804 TEST_ESP_OK(esp_event_handler_unregister_with(*loop, s_test_base1, TEST_EVENT_BASE1_EV2, test_event_simple_handler_3));
1805 }
1806
1807 TEST_CASE("can register from handler", "[event]")
1808 {
1809 TEST_SETUP();
1810
1811 esp_event_loop_handle_t loop;
1812
1813 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1814
1815 loop_args.task_name = NULL;
1816 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
1817
1818 int count = 0;
1819
1820 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_registration_from_handler_hdlr, &count));
1821 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base2, TEST_EVENT_BASE2_EV1, test_unregistration_from_handler_hdlr, &count));
1822
1823 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, &loop, sizeof(&loop), portMAX_DELAY));
1824 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1825
1826 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
1827 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1828
1829 TEST_ASSERT_EQUAL(3, count);
1830
1831 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE2_EV1, &loop, sizeof(&loop), portMAX_DELAY));
1832 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1833
1834 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
1835 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1836
1837 TEST_ASSERT_EQUAL(3, count);
1838
1839 TEST_ESP_OK(esp_event_loop_delete(loop));
1840
1841 TEST_TEARDOWN();
1842 }
1843
test_create_loop_handler(void * handler_args,esp_event_base_t base,int32_t id,void * event_data)1844 static void test_create_loop_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data)
1845 {
1846 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1847
1848 if (id == TEST_EVENT_BASE1_EV1) {
1849 TEST_ESP_OK(esp_event_loop_create(&loop_args, (esp_event_loop_handle_t*) handler_args));
1850 } else {
1851 TEST_ESP_OK(esp_event_loop_delete(*((esp_event_loop_handle_t*) handler_args)));
1852 }
1853 }
1854
1855 TEST_CASE("can create and delete loop from handler", "[event]")
1856 {
1857 TEST_SETUP();
1858
1859 esp_event_loop_handle_t loop;
1860 esp_event_loop_handle_t test_loop;
1861
1862 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1863
1864 loop_args.task_name = NULL;
1865 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
1866
1867 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_create_loop_handler, &test_loop));
1868 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV2, test_create_loop_handler, &test_loop));
1869
1870 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
1871 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1872
1873 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY));
1874 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1875
1876 TEST_ESP_OK(esp_event_loop_delete(loop));
1877
1878 TEST_TEARDOWN();
1879 }
1880
1881 TEST_CASE("events are dispatched in the order they are registered", "[event]")
1882 {
1883 TEST_SETUP();
1884
1885 esp_event_loop_handle_t loop;
1886 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1887
1888 loop_args.task_name = NULL;
1889 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
1890
1891 int id_arr[7];
1892
1893 for (int i = 0; i < 7; i++) {
1894 id_arr[i] = i;
1895 }
1896
1897 int data_arr[12] = {0};
1898
1899 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base2, TEST_EVENT_BASE2_EV1, test_event_ordered_dispatch, id_arr + 0));
1900 TEST_ESP_OK(esp_event_handler_register_with(loop, ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, test_event_ordered_dispatch, id_arr + 1));
1901 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, ESP_EVENT_ANY_ID, test_event_ordered_dispatch, id_arr + 2));
1902 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base2, TEST_EVENT_BASE2_EV2, test_event_ordered_dispatch, id_arr + 3));
1903 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV1, test_event_ordered_dispatch, id_arr + 4));
1904 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base2, ESP_EVENT_ANY_ID, test_event_ordered_dispatch, id_arr + 5));
1905 TEST_ESP_OK(esp_event_handler_register_with(loop, s_test_base1, TEST_EVENT_BASE1_EV2, test_event_ordered_dispatch, id_arr + 6));
1906
1907 esp_event_dump(stdout);
1908
1909 ordered_data_t data = {
1910 .arr = data_arr,
1911 .index = 0
1912 };
1913
1914 ordered_data_t* dptr = &data;
1915
1916 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV2, &dptr, sizeof(dptr), portMAX_DELAY));
1917 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, &dptr, sizeof(dptr), portMAX_DELAY));
1918 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV2, &dptr, sizeof(dptr), portMAX_DELAY));
1919 TEST_ESP_OK(esp_event_post_to(loop, s_test_base2, TEST_EVENT_BASE1_EV1, &dptr, sizeof(dptr), portMAX_DELAY));
1920
1921 TEST_ESP_OK(esp_event_loop_run(loop, pdMS_TO_TICKS(10)));
1922
1923 // Expected data executing the posts above
1924 int ref_arr[12] = {1, 3, 5, 1, 2, 4, 1, 2, 6, 0, 1, 5};
1925
1926 for (int i = 0; i < 12; i++) {
1927 TEST_ASSERT_EQUAL(ref_arr[i], data_arr[i]);
1928 }
1929
1930 TEST_ESP_OK(esp_event_loop_delete(loop));
1931
1932 TEST_TEARDOWN();
1933 }
1934
1935 #if CONFIG_ESP_EVENT_POST_FROM_ISR
1936 TEST_CASE("can properly prepare event data posted to loop", "[event]")
1937 {
1938 TEST_SETUP();
1939
1940 esp_event_loop_handle_t loop;
1941 esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
1942
1943 loop_args.task_name = NULL;
1944 TEST_ESP_OK(esp_event_loop_create(&loop_args, &loop));
1945
1946 esp_event_post_instance_t post;
1947 esp_event_loop_instance_t* loop_def = (esp_event_loop_instance_t*) loop;
1948
1949 TEST_ESP_OK(esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
1950 TEST_ASSERT_EQUAL(pdTRUE, xQueueReceive(loop_def->queue, &post, portMAX_DELAY));
1951 TEST_ASSERT_EQUAL(false, post.data_set);
1952 TEST_ASSERT_EQUAL(false, post.data_allocated);
1953 TEST_ASSERT_EQUAL(NULL, post.data.ptr);
1954
1955 int sample = 0;
1956 TEST_ESP_OK(esp_event_isr_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, &sample, sizeof(sample), NULL));
1957 TEST_ASSERT_EQUAL(pdTRUE, xQueueReceive(loop_def->queue, &post, portMAX_DELAY));
1958 TEST_ASSERT_EQUAL(true, post.data_set);
1959 TEST_ASSERT_EQUAL(false, post.data_allocated);
1960 TEST_ASSERT_EQUAL(false, post.data.val);
1961
1962 TEST_ESP_OK(esp_event_loop_delete(loop));
1963
1964 TEST_TEARDOWN();
1965 }
1966
test_handler_post_from_isr(void * event_handler_arg,esp_event_base_t event_base,int32_t event_id,void * event_data)1967 static void test_handler_post_from_isr(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
1968 {
1969 SemaphoreHandle_t *sem = (SemaphoreHandle_t*) event_handler_arg;
1970 // Event data is just the address value (maybe have been truncated due to casting).
1971 int *data = (int*) event_data;
1972 TEST_ASSERT_EQUAL(*data, (int) (*sem));
1973 xSemaphoreGive(*sem);
1974 }
1975
test_event_on_timer_alarm(void * para)1976 void IRAM_ATTR test_event_on_timer_alarm(void* para)
1977 {
1978 /* Retrieve the interrupt status and the counter value
1979 from the timer that reported the interrupt */
1980 uint64_t timer_counter_value =
1981 timer_group_get_counter_value_in_isr(TIMER_GROUP_0, TIMER_0);
1982 timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0);
1983 timer_counter_value += (uint64_t) (TIMER_INTERVAL0_SEC * TIMER_SCALE);
1984 timer_group_set_alarm_value_in_isr(TIMER_GROUP_0, TIMER_0, timer_counter_value);
1985
1986 int data = (int) para;
1987 // Posting events with data more than 4 bytes should fail.
1988 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_isr_post(s_test_base1, TEST_EVENT_BASE1_EV1, &data, 5, NULL));
1989 // This should succeedd, as data is int-sized. The handler for the event checks that the passed event data
1990 // is correct.
1991 BaseType_t task_unblocked;
1992 TEST_ESP_OK(esp_event_isr_post(s_test_base1, TEST_EVENT_BASE1_EV1, &data, sizeof(data), &task_unblocked));
1993 if (task_unblocked == pdTRUE) {
1994 portYIELD_FROM_ISR();
1995 }
1996 }
1997
1998 TEST_CASE("can post events from interrupt handler", "[event]")
1999 {
2000 SemaphoreHandle_t sem = xSemaphoreCreateBinary();
2001
2002 /* Select and initialize basic parameters of the timer */
2003 timer_config_t config;
2004 config.divider = TIMER_DIVIDER;
2005 config.counter_dir = TIMER_COUNT_UP;
2006 config.counter_en = TIMER_PAUSE;
2007 config.alarm_en = TIMER_ALARM_EN;
2008 config.intr_type = TIMER_INTR_LEVEL;
2009 config.auto_reload = false;
2010 timer_init(TIMER_GROUP_0, TIMER_0, &config);
2011
2012 /* Timer's counter will initially start from value below.
2013 Also, if auto_reload is set, this value will be automatically reload on alarm */
2014 timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0x00000000ULL);
2015
2016 /* Configure the alarm value and the interrupt on alarm. */
2017 timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, TIMER_INTERVAL0_SEC * TIMER_SCALE);
2018 timer_enable_intr(TIMER_GROUP_0, TIMER_0);
2019 timer_isr_register(TIMER_GROUP_0, TIMER_0, test_event_on_timer_alarm,
2020 (void *) sem, ESP_INTR_FLAG_IRAM, NULL);
2021
2022 timer_start(TIMER_GROUP_0, TIMER_0);
2023
2024 TEST_SETUP();
2025
2026 TEST_ESP_OK(esp_event_handler_register(s_test_base1, TEST_EVENT_BASE1_EV1,
2027 test_handler_post_from_isr, &sem));
2028
2029 xSemaphoreTake(sem, portMAX_DELAY);
2030
2031 TEST_TEARDOWN();
2032 }
2033
2034 #endif // CONFIG_ESP_EVENT_POST_FROM_ISR
2035