Files
bacnet_stack/test/ports/linux/bsc_event/src/main.c
T
Steve Karg cf77abac9b Feature/bacnet secure connect hub (#818)
* Added BACnet Secure Connect datalink.

* Added BACnet/SC hub application
---------

Co-authored-by: Kirill Neznamov <kirill.neznamov@dsr-corporation.com>
Co-authored-by: Mikhail Antropov <michail.antropov@dsr-corporation.com>
Co-authored-by: Ondřej Hruška <ondra@ondrovo.com>
Co-authored-by: Patrick Grimm <patrick@lunatiki.de>
2024-11-04 07:05:26 -06:00

197 lines
4.6 KiB
C

/*
* Copyright (c) 2022 Legrand North America, LLC.
*
* SPDX-License-Identifier: MIT
*/
/* @file
* @brief test of bsc-event interface
*/
#define _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <zephyr/ztest.h>
#include <bacnet/datalink/bsc/bsc-event.h>
#include <unistd.h>
typedef enum {
STAGE_NONE,
STAGE_WAIT_1,
STAGE_WAIT_2,
STAGE_TIMEDWAIT_TIMEOUT,
STAGE_TIMEDWAIT_OK,
} TEST_STAGE;
static TEST_STAGE test_stage = STAGE_NONE;
#define TIMEOUT_CHILD 400
#define TIMEOUT_MIN 200
#define TIMEOUT_MAX 600
#define MSEC_PER_SEC 1000
#define USEC_PER_MSEC 1000000
#define TIMEOUT_SLEEP 2
#define WAITTIME_MIN (TIMEOUT_SLEEP * MSEC_PER_SEC - 100)
#define WAITTIME_MAX (TIMEOUT_SLEEP * MSEC_PER_SEC + 100)
#define MULTIPLE_WAIT_THREADS_NUM 50
static void *child_func(void *arg)
{
BSC_EVENT *event = (BSC_EVENT *)arg;
zassert_not_null(event, NULL);
while (test_stage != STAGE_WAIT_1) {
usleep(10);
}
bsc_event_signal(event);
while (test_stage != STAGE_WAIT_2) {
usleep(10);
}
bsc_event_signal(event);
while (test_stage != STAGE_TIMEDWAIT_TIMEOUT) {
usleep(10);
}
usleep(1000 * TIMEOUT_CHILD);
bsc_event_signal(event);
while (test_stage != STAGE_TIMEDWAIT_OK) {
usleep(10);
}
usleep(1000 * TIMEOUT_CHILD);
bsc_event_signal(event);
return NULL;
}
static void test_bsc_event1(void)
{
BSC_EVENT *event;
pthread_t tid_child;
bool b;
struct timespec t1;
struct timespec t2;
int64_t timediff;
test_stage = STAGE_NONE;
event = bsc_event_init();
zassert_not_null(event, NULL);
// run child and wait when child running
zassert_equal(
pthread_create(&tid_child, NULL, &child_func, event), 0, NULL);
test_stage = STAGE_WAIT_1;
bsc_event_wait(event);
test_stage = STAGE_WAIT_2;
bsc_event_wait(event);
test_stage = STAGE_TIMEDWAIT_TIMEOUT;
b = bsc_event_timedwait(event, TIMEOUT_MIN);
zassert_false(b, NULL);
test_stage = STAGE_TIMEDWAIT_OK;
b = bsc_event_timedwait(event, TIMEOUT_MAX);
zassert_true(b, NULL);
clock_gettime(CLOCK_REALTIME, &t1);
bsc_wait(TIMEOUT_SLEEP);
clock_gettime(CLOCK_REALTIME, &t2);
timediff = (t2.tv_sec * MSEC_PER_SEC + t2.tv_nsec / USEC_PER_MSEC) -
(t1.tv_sec * MSEC_PER_SEC + t1.tv_nsec / USEC_PER_MSEC);
zassert_true(timediff >= TIMEOUT_SLEEP * MSEC_PER_SEC, NULL);
pthread_join(tid_child, NULL);
bsc_event_deinit(event);
}
static void *thread_func(void *arg)
{
BSC_EVENT *event = (BSC_EVENT *)arg;
zassert_not_null(event, NULL);
bsc_event_wait(event);
return NULL;
}
static void test_bsc_event2(void)
{
BSC_EVENT *event;
pthread_t tid[MULTIPLE_WAIT_THREADS_NUM];
int i;
event = bsc_event_init();
zassert_not_null(event, NULL);
for (i = 0; i < MULTIPLE_WAIT_THREADS_NUM; i++) {
zassert_equal(
pthread_create(&tid[i], NULL, &thread_func, event), 0, NULL);
}
bsc_wait(1);
bsc_event_signal(event);
for (i = 0; i < MULTIPLE_WAIT_THREADS_NUM; i++) {
pthread_join(tid[i], NULL);
}
bsc_event_deinit(event);
}
typedef struct {
BSC_EVENT *event;
bool result;
} test_param_t;
static void *thread_func2(void *arg)
{
test_param_t *p = (test_param_t *)arg;
zassert_not_null(p->event, NULL);
// use some big timeout value, 24 hours seems to be enough
p->result = bsc_event_timedwait(p->event, 24 * 60 * 60 * 1000);
return NULL;
}
static void test_bsc_event3(void)
{
BSC_EVENT *event;
pthread_t tid[MULTIPLE_WAIT_THREADS_NUM];
test_param_t results[MULTIPLE_WAIT_THREADS_NUM];
int i;
event = bsc_event_init();
zassert_not_null(event, NULL);
for (i = 0; i < MULTIPLE_WAIT_THREADS_NUM; i++) {
results[i].event = event;
results[i].result = false;
zassert_equal(
pthread_create(&tid[i], NULL, &thread_func2, &results[i]), 0, NULL);
}
bsc_wait(1);
bsc_event_signal(event);
for (i = 0; i < MULTIPLE_WAIT_THREADS_NUM; i++) {
pthread_join(tid[i], NULL);
}
for (i = 0; i < MULTIPLE_WAIT_THREADS_NUM; i++) {
zassert_equal(results[i].result == true, true, NULL);
}
bsc_event_deinit(event);
}
void test_main(void)
{
ztest_test_suite(bsc_event_test1, ztest_unit_test(test_bsc_event1));
ztest_test_suite(bsc_event_test2, ztest_unit_test(test_bsc_event2));
ztest_test_suite(bsc_event_test3, ztest_unit_test(test_bsc_event3));
ztest_run_test_suite(bsc_event_test1);
ztest_run_test_suite(bsc_event_test2);
ztest_run_test_suite(bsc_event_test3);
}