cyclonedds/src/util/tests/handleserver.c
Jeroen Koekkoek 74a48c5731 Replace Criterion by CUnit
Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
2018-12-06 14:48:30 +01:00

306 lines
8.5 KiB
C

/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include "os/os.h"
#include "util/ut_handleserver.h"
#include "CUnit/Test.h"
/*****************************************************************************************/
CU_Test(util_handleserver, basic)
{
const os_time zero = { 0, 0 };
int32_t kind = 0x10000000;
ut_handle_retcode_t ret;
ut_handle_t hdl;
int arg = 1;
void *argx;
ret = ut_handleserver_init();
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
hdl = ut_handle_create(kind, (void*)&arg);
CU_ASSERT_FATAL(hdl > 0);
ret = ut_handle_claim(hdl, NULL, kind, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
CU_ASSERT_EQUAL_FATAL(argx, &arg);
ut_handle_release(hdl, NULL);
ret = ut_handle_delete(hdl, NULL, zero);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
ret = ut_handle_claim(hdl, NULL, kind, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_DELETED);
ut_handleserver_fini();
}
/*****************************************************************************************/
CU_Test(util_handleserver, close)
{
const os_time zero = { 0, 0 };
int32_t kind = 0x10000000;
ut_handle_retcode_t ret;
ut_handle_t hdl;
int arg = 1;
void *argx;
bool closed;
ret = ut_handleserver_init();
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
hdl = ut_handle_create(kind, (void*)&arg);
CU_ASSERT_FATAL(hdl > 0);
closed = ut_handle_is_closed(hdl, NULL);
CU_ASSERT_EQUAL_FATAL(closed, false);
ut_handle_close(hdl, NULL);
closed = ut_handle_is_closed(hdl, NULL);
CU_ASSERT_EQUAL_FATAL(closed, true);
ret = ut_handle_claim(hdl, NULL, kind, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_CLOSED);
ret = ut_handle_delete(hdl, NULL, zero);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
ret = ut_handle_claim(hdl, NULL, kind, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_DELETED);
ut_handleserver_fini();
}
/*****************************************************************************************/
CU_Test(util_handleserver, link)
{
const os_time zero = { 0, 0 };
int32_t kind = 0x10000000;
ut_handle_retcode_t ret;
struct ut_handlelink *link;
ut_handle_t hdl;
int arg = 1;
void *argx;
ret = ut_handleserver_init();
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
hdl = ut_handle_create(kind, (void*)&arg);
CU_ASSERT_FATAL(hdl > 0);
link = ut_handle_get_link(hdl);
CU_ASSERT_NOT_EQUAL_FATAL(link, NULL);
ret = ut_handle_claim(hdl, link, kind, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
CU_ASSERT_EQUAL_FATAL(argx, &arg);
ut_handle_release(hdl, link);
ret = ut_handle_delete(hdl, link, zero);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
link = ut_handle_get_link(hdl);
CU_ASSERT_EQUAL_FATAL(link, NULL);
ut_handleserver_fini();
}
/*****************************************************************************************/
CU_Test(util_handleserver, types)
{
const os_time zero = { 0, 0 };
int32_t kind1 = 0x10000000;
int32_t kind2 = 0x20000000;
ut_handle_retcode_t ret;
ut_handle_t hdl1a;
ut_handle_t hdl1b;
ut_handle_t hdl2;
int arg1a = (int)'a';
int arg1b = (int)'b';
int arg2 = (int)'2';
void *argx;
ret = ut_handleserver_init();
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
hdl1a = ut_handle_create(kind1, (void*)&arg1a);
CU_ASSERT_FATAL(hdl1a > 0);
hdl1b = ut_handle_create(kind1, (void*)&arg1b);
CU_ASSERT_FATAL(hdl1b > 0);
hdl2 = ut_handle_create(kind2, (void*)&arg2);
CU_ASSERT_FATAL(hdl2 > 0);
ret = ut_handle_claim(hdl1a, NULL, kind1, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
CU_ASSERT_EQUAL_FATAL(argx, &arg1a);
ret = ut_handle_claim(hdl1b, NULL, kind1, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
CU_ASSERT_EQUAL_FATAL(argx, &arg1b);
ret = ut_handle_claim(hdl2, NULL, kind2, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
CU_ASSERT_EQUAL_FATAL(argx, &arg2);
ret = ut_handle_claim(hdl1a, NULL, kind2, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_UNEQUAL_KIND);
ret = ut_handle_claim(hdl1a, NULL, kind2, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_UNEQUAL_KIND);
ret = ut_handle_claim(hdl2, NULL, kind1, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_UNEQUAL_KIND);
ut_handle_release(hdl1a, NULL);
ut_handle_release(hdl1b, NULL);
ut_handle_release(hdl2, NULL);
ret = ut_handle_delete(hdl1a, NULL, zero);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
ret = ut_handle_delete(hdl1b, NULL, zero);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
ret = ut_handle_delete(hdl2, NULL, zero);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
ut_handleserver_fini();
}
/*****************************************************************************************/
CU_Test(util_handleserver, timeout)
{
const os_time zero = { 0, 0 };
int32_t kind = 0x10000000;
ut_handle_retcode_t ret;
ut_handle_t hdl;
int arg = 1;
void *argx;
ret = ut_handleserver_init();
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
hdl = ut_handle_create(kind, (void*)&arg);
CU_ASSERT_FATAL(hdl > 0);
ret = ut_handle_claim(hdl, NULL, kind, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
CU_ASSERT_EQUAL_FATAL(argx, &arg);
ret = ut_handle_delete(hdl, NULL, zero);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_TIMEOUT);
ut_handle_release(hdl, NULL);
ret = ut_handle_delete(hdl, NULL, zero);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
ut_handleserver_fini();
}
/*****************************************************************************************/
typedef enum thread_state_t {
STARTING,
DELETING,
STOPPED
} thread_state_t;
typedef struct thread_arg_t {
thread_state_t state;
ut_handle_t hdl;
} thread_arg_t;
static uint32_t
deleting_thread(void *a)
{
thread_arg_t *arg = (thread_arg_t*)a;
const os_time ten = { 10, 0 };
ut_handle_t ret;
arg->state = DELETING;
/* This should block until the main test released all claims. */
ret = ut_handle_delete(arg->hdl, NULL, ten);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
arg->state = STOPPED;
return 0;
}
os_result
thread_reached_state(thread_state_t *actual, thread_state_t expected, int32_t msec)
{
/* Convenience function. */
os_time msec10 = { 0, 10000000 };
while ((msec > 0) && (*actual != expected)) {
os_nanoSleep(msec10);
msec -= 10;
}
return (*actual == expected) ? os_resultSuccess : os_resultTimeout;
}
CU_Test(util_handleserver, wakeup)
{
int32_t kind = 0x10000000;
ut_handle_retcode_t ret;
ut_handle_t hdl;
int arg = 1;
void *argx;
os_threadId thread_id;
thread_arg_t thread_arg;
os_threadAttr thread_attr;
os_result osr;
ret = ut_handleserver_init();
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
hdl = ut_handle_create(kind, (void*)&arg);
CU_ASSERT_FATAL(hdl > 0);
ret = ut_handle_claim(hdl, NULL, kind, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
ret = ut_handle_claim(hdl, NULL, kind, &argx);
CU_ASSERT_EQUAL_FATAL(ret, UT_HANDLE_OK);
/* Try deleting in other thread, which should block. */
thread_arg.hdl = hdl;
thread_arg.state = STARTING;
os_threadAttrInit(&thread_attr);
osr = os_threadCreate(&thread_id, "deleting_thread", &thread_attr, deleting_thread, (void*)&thread_arg);
CU_ASSERT_EQUAL_FATAL(osr, os_resultSuccess);
osr = thread_reached_state(&thread_arg.state, DELETING, 1000);
CU_ASSERT_EQUAL_FATAL(osr, os_resultSuccess);
osr = thread_reached_state(&thread_arg.state, STOPPED, 500);
CU_ASSERT_EQUAL_FATAL(osr, os_resultTimeout);
/* First release of the hdl should not unblock the thread. */
ut_handle_release(hdl, NULL);
osr = thread_reached_state(&thread_arg.state, STOPPED, 500);
CU_ASSERT_EQUAL_FATAL(osr, os_resultTimeout);
/* Second release of the hdl should unblock the thread. */
ut_handle_release(hdl, NULL);
osr = thread_reached_state(&thread_arg.state, STOPPED, 500);
CU_ASSERT_EQUAL_FATAL(osr, os_resultSuccess);
os_threadWaitExit(thread_id, NULL);
/* The handle is deleted within the thread. */
ut_handleserver_fini();
}