From 19e8bfd8c7bddc9dbfe00f7023c95fc73f56d1f8 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Wed, 14 Apr 2021 17:23:19 +0200 Subject: [PATCH] Clean up/refactor/improve waitset tests Signed-off-by: Erik Boasson --- src/core/ddsc/tests/waitset.c | 1411 ++++++++++++--------------------- 1 file changed, 504 insertions(+), 907 deletions(-) diff --git a/src/core/ddsc/tests/waitset.c b/src/core/ddsc/tests/waitset.c index 0f69025be7..2d1e51ec3e 100644 --- a/src/core/ddsc/tests/waitset.c +++ b/src/core/ddsc/tests/waitset.c @@ -22,1167 +22,764 @@ #include "test_common.h" -/************************************************************************************************** - * - * Some thread related convenience stuff. - * - *************************************************************************************************/ +#define MAX_ENTITIES_CNT (10) typedef enum thread_state_t { - STARTING, - WAITING, - STOPPED + STARTING, + WAITING, + STOPPED } thread_state_t; typedef struct thread_arg_t { ddsrt_thread_t tid; ddsrt_atomic_uint32_t state; - dds_entity_t expected; + dds_entity_t expected; } thread_arg_t; -static void waiting_thread_start(struct thread_arg_t *arg, dds_entity_t expected); +static void waiting_thread_start(struct thread_arg_t *arg, dds_entity_t expected); static dds_return_t waiting_thread_expect_exit(struct thread_arg_t *arg); +static dds_entity_t participant, topic, writer, reader, waitset, publisher, subscriber, readcond; - - -/************************************************************************************************** - * - * Test fixtures - * - *************************************************************************************************/ - -static dds_entity_t participant = 0; -static dds_entity_t topic = 0; -static dds_entity_t writer = 0; -static dds_entity_t reader = 0; -static dds_entity_t waitset = 0; -static dds_entity_t publisher = 0; -static dds_entity_t subscriber = 0; -static dds_entity_t readcond = 0; - - -static void -ddsc_waitset_basic_init(void) +static void ddsc_waitset_basic_init (void) { - participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL); - CU_ASSERT_FATAL(participant > 0); - - waitset = dds_create_waitset(participant); - CU_ASSERT_FATAL(waitset > 0); + ddsrt_init (); + participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL); + CU_ASSERT_FATAL (participant > 0); + waitset = dds_create_waitset (participant); + CU_ASSERT_FATAL (waitset > 0); } -static void -ddsc_waitset_basic_fini(void) +static void ddsc_waitset_basic_fini (void) { - /* It shouldn't matter if any of these entities were deleted previously. - * dds_delete will just return an error, which we don't check. */ - dds_delete(waitset); - dds_delete(participant); + (void) dds_delete (waitset); + (void) dds_delete (participant); + ddsrt_fini (); } -static void -ddsc_waitset_init(void) +static void ddsc_waitset_init (void) { - uint32_t mask = DDS_ANY_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE; - char name[100]; - - ddsrt_init(); - - ddsc_waitset_basic_init(); - - publisher = dds_create_publisher(participant, NULL, NULL); - CU_ASSERT_FATAL(publisher > 0); - - subscriber = dds_create_subscriber(participant, NULL, NULL); - CU_ASSERT_FATAL(subscriber > 0); - - topic = dds_create_topic(participant, &RoundTripModule_DataType_desc, create_unique_topic_name("ddsc_waitset_test", name, sizeof name), NULL, NULL); - CU_ASSERT_FATAL(topic > 0); - - reader = dds_create_reader(subscriber, topic, NULL, NULL); - CU_ASSERT_FATAL(reader > 0); - - writer = dds_create_writer(publisher, topic, NULL, NULL); - CU_ASSERT_FATAL(writer > 0); - - readcond = dds_create_readcondition(reader, mask); - CU_ASSERT_FATAL(readcond > 0); + uint32_t mask = DDS_ANY_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE; + char name[100]; + ddsc_waitset_basic_init (); + publisher = dds_create_publisher (participant, NULL, NULL); + CU_ASSERT_FATAL (publisher > 0); + subscriber = dds_create_subscriber (participant, NULL, NULL); + CU_ASSERT_FATAL (subscriber > 0); + topic = dds_create_topic (participant, &RoundTripModule_DataType_desc, create_unique_topic_name ("ddsc_waitset_test", name, sizeof name), NULL, NULL); + CU_ASSERT_FATAL (topic > 0); + reader = dds_create_reader (subscriber, topic, NULL, NULL); + CU_ASSERT_FATAL (reader > 0); + writer = dds_create_writer (publisher, topic, NULL, NULL); + CU_ASSERT_FATAL (writer > 0); + readcond = dds_create_readcondition (reader, mask); + CU_ASSERT_FATAL (readcond > 0); } -static void -ddsc_waitset_fini(void) +static void ddsc_waitset_fini (void) { - /* It shouldn't matter if any of these entities were deleted previously. - * dds_delete will just return an error, which we don't check. */ - dds_delete(readcond); - dds_delete(writer); - dds_delete(reader); - dds_delete(topic); - dds_delete(publisher); - dds_delete(subscriber); - ddsc_waitset_basic_fini(); - ddsrt_fini(); + ddsc_waitset_basic_fini (); } -static void -ddsc_waitset_attached_init(void) +static void ddsc_waitset_attached_init (void) { - dds_return_t ret; - - ddsc_waitset_init(); - - /* Start with interest in nothing. */ - ret = dds_set_status_mask(participant, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = dds_set_status_mask(writer, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = dds_set_status_mask(reader, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = dds_set_status_mask(topic, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = dds_set_status_mask(publisher, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = dds_set_status_mask(subscriber, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - /* Attach all entities to the waitset. */ - ret = dds_waitset_attach(waitset, participant, participant); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = dds_waitset_attach(waitset, waitset, waitset); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = dds_waitset_attach(waitset, writer, writer); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = dds_waitset_attach(waitset, reader, reader); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = dds_waitset_attach(waitset, topic, topic); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = dds_waitset_attach(waitset, publisher, publisher); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = dds_waitset_attach(waitset, subscriber, subscriber); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - + dds_return_t ret; + ddsc_waitset_init (); + dds_entity_t es[] = { participant, topic, writer, reader, waitset, publisher, subscriber, 0 }; + for (int i = 0; es[i]; i++) + { + // waitset doesn't have a status mask, perhaps that ought to be changed + if (es[i] != waitset) + { + ret = dds_set_status_mask (es[i], 0); + CU_ASSERT_FATAL (ret == 0); + } + } + for (int i = 0; es[i]; i++) + { + ret = dds_waitset_attach (waitset, es[i], es[i]); + CU_ASSERT_FATAL (ret == 0); + } } -static void -ddsc_waitset_attached_fini(void) +static void ddsc_waitset_attached_fini (void) { - /* Detach all entities to the waitset. */ - dds_waitset_detach(waitset, participant); - dds_waitset_detach(waitset, topic); - dds_waitset_detach(waitset, publisher); - dds_waitset_detach(waitset, subscriber); - dds_waitset_detach(waitset, waitset); - dds_waitset_detach(waitset, writer); - dds_waitset_detach(waitset, reader); - - ddsc_waitset_fini(); + ddsc_waitset_fini (); } -#if 0 -#else -/************************************************************************************************** - * - * These will check the waitset creation in various ways. - * - *************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_create, second, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_entity_t ws; - dds_return_t ret; - - /* Basically, ddsc_waitset_basic_init() already tested the creation of a waitset. But - * just see if we can create a second one. */ - ws = dds_create_waitset(participant); - CU_ASSERT_FATAL(ws > 0); - - /* Also, we should be able to delete this second one. */ - ret = dds_delete(ws); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - /* And, of course, be able to delete the first one (return code isn't checked in the test fixtures). */ - ret = dds_delete(waitset); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); + dds_entity_t ws; + dds_return_t ret; + /* Basically, ddsc_waitset_basic_init() already tested the creation of a waitset. But + * just see if we can create a second one and delete the waitsets. */ + ws = dds_create_waitset (participant); + CU_ASSERT_FATAL (ws > 0); + ret = dds_delete (ws); + CU_ASSERT_FATAL (ret == 0); + ret = dds_delete (waitset); + CU_ASSERT_FATAL (ret == 0); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_create, deleted_participant, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_entity_t ws; - dds_entity_t deleted; - deleted = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL); - dds_delete(deleted); - ws = dds_create_waitset(deleted); - CU_ASSERT_EQUAL_FATAL(ws, DDS_RETCODE_BAD_PARAMETER); + dds_entity_t ws; + dds_entity_t deleted; + deleted = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL); + (void) dds_delete (deleted); + ws = dds_create_waitset (deleted); + CU_ASSERT_FATAL(ws == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_create, invalid_params) = { - CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), + CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), }; CU_Theory((dds_entity_t par), ddsc_waitset_create, invalid_params, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_entity_t ws; - - ws = dds_create_waitset(par); - CU_ASSERT_EQUAL_FATAL(ws, DDS_RETCODE_BAD_PARAMETER); + dds_entity_t ws = dds_create_waitset (par); + CU_ASSERT_FATAL (ws == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_create, non_participants) = { - CU_DataPoints(dds_entity_t*, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), }; CU_Theory((dds_entity_t *par), ddsc_waitset_create, non_participants, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { - dds_entity_t ws; - ws = dds_create_waitset(*par); - CU_ASSERT_EQUAL_FATAL(ws, DDS_RETCODE_ILLEGAL_OPERATION); + dds_entity_t ws = dds_create_waitset (*par); + CU_ASSERT_FATAL (ws == DDS_RETCODE_ILLEGAL_OPERATION); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_Test (ddsc_waitset_create, domain) { - dds_entity_t par, dom, ws; - dds_return_t rc; - par = dds_create_participant (0, NULL, NULL); - CU_ASSERT_FATAL (par > 0); - dom = dds_get_parent (par); - CU_ASSERT_FATAL (dom > 0); - ws = dds_create_waitset (dom); - CU_ASSERT_FATAL (ws > 0); - rc = dds_delete (dom); - CU_ASSERT_FATAL (rc == 0); + dds_entity_t par, dom, ws; + dds_return_t rc; + par = dds_create_participant (0, NULL, NULL); + CU_ASSERT_FATAL (par > 0); + dom = dds_get_parent (par); + CU_ASSERT_FATAL (dom > 0); + ws = dds_create_waitset (dom); + CU_ASSERT_FATAL (ws > 0); + rc = dds_delete (dom); + CU_ASSERT_FATAL (rc == 0); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_Test (ddsc_waitset_create, cyclonedds) { - dds_entity_t ws; - dds_return_t rc; - /* Expect an uninitialised library */ - rc = dds_get_parent (DDS_CYCLONEDDS_HANDLE); - CU_ASSERT_FATAL (rc == DDS_RETCODE_PRECONDITION_NOT_MET); - ws = dds_create_waitset (DDS_CYCLONEDDS_HANDLE); - CU_ASSERT_FATAL (ws > 0); - rc = dds_delete (DDS_CYCLONEDDS_HANDLE); - CU_ASSERT_FATAL (rc == 0); - /* And the same afterward */ - rc = dds_get_parent (DDS_CYCLONEDDS_HANDLE); - CU_ASSERT_FATAL (rc == DDS_RETCODE_PRECONDITION_NOT_MET); + dds_entity_t ws; + dds_return_t rc; + /* Expect an uninitialised library */ + rc = dds_get_parent (DDS_CYCLONEDDS_HANDLE); + CU_ASSERT_FATAL (rc == DDS_RETCODE_PRECONDITION_NOT_MET); + ws = dds_create_waitset (DDS_CYCLONEDDS_HANDLE); + CU_ASSERT_FATAL (ws > 0); + rc = dds_delete (DDS_CYCLONEDDS_HANDLE); + CU_ASSERT_FATAL (rc == 0); + /* And the same afterward */ + rc = dds_get_parent (DDS_CYCLONEDDS_HANDLE); + CU_ASSERT_FATAL (rc == DDS_RETCODE_PRECONDITION_NOT_MET); } -/*************************************************************************************************/ - -/************************************************************************************************** - * - * These will check the waitset attach in various invalid ways. - * - Valid waitset but try to attach all kinds of invalid entities. - * - Try to attach a valid participant to all kinds of invalid entities. - * - Try attaching valid entities to valid (non-waitset) entities - * - Try attaching a valid entity a second time. - * - *************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_attach, invalid_params) = { - CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), - CU_DataPoints(dds_attach_t, (dds_attach_t)NULL, (dds_attach_t)&reader, (dds_attach_t)3, (dds_attach_t)0, (dds_attach_t)0, (dds_attach_t)0, (dds_attach_t)0), + CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), + CU_DataPoints(dds_attach_t, (dds_attach_t)NULL, (dds_attach_t)&reader, (dds_attach_t)3, (dds_attach_t)0, (dds_attach_t)0, (dds_attach_t)0, (dds_attach_t)0), }; CU_Theory((dds_entity_t e, dds_attach_t a), ddsc_waitset_attach, invalid_params, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_return_t ret; - ret = dds_waitset_attach(waitset, e, a); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_return_t ret = dds_waitset_attach (waitset, e, a); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_attach, invalid_waitsets) = { CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), CU_DataPoints(dds_attach_t, (dds_attach_t)NULL, (dds_attach_t)&reader, (dds_attach_t)3, (dds_attach_t)0, (dds_attach_t)0, (dds_attach_t)0, (dds_attach_t)0), }; CU_Theory((dds_entity_t ws, dds_attach_t a), ddsc_waitset_attach, invalid_waitsets, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_return_t ret; - - ret = dds_waitset_attach(ws, participant, a); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_return_t ret = dds_waitset_attach (ws, participant, a); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_attach, non_waitsets) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), - CU_DataPoints(dds_attach_t, (dds_attach_t)NULL, (dds_attach_t)&reader, (dds_attach_t)3, (dds_attach_t)0, (dds_attach_t)0, (dds_attach_t)0, (dds_attach_t)0), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_attach_t, (dds_attach_t)NULL, (dds_attach_t)&reader, (dds_attach_t)3, (dds_attach_t)0, (dds_attach_t)0, (dds_attach_t)0, (dds_attach_t)0), }; CU_Theory((dds_entity_t *ws, dds_entity_t *e, dds_attach_t a), ddsc_waitset_attach, non_waitsets, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { - dds_return_t ret; - ret = dds_waitset_attach(*ws, *e, a); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_ILLEGAL_OPERATION); + dds_return_t ret = dds_waitset_attach (*ws, *e, a); + CU_ASSERT_FATAL (ret == DDS_RETCODE_ILLEGAL_OPERATION); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_attach, deleted_waitset, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_return_t ret; - dds_delete(waitset); - ret = dds_waitset_attach(waitset, participant, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_delete(waitset); + dds_return_t ret = dds_waitset_attach(waitset, participant, 0); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_attach, scoping) = { - CU_DataPoints (int, -9, -1, -2, 0, 0, 2), /* owner: -9: lib, -1: dom0, -2: dom1 */ - CU_DataPoints (int, 0, 0, 2, 0, 0, 2), /* ok1: participant one can attach */ - CU_DataPoints (int, 3, 1, 3, -1, -1, -1), /* ok2: other participant one can attach, or -1 */ - CU_DataPoints (int, -1, 2, 0, 1, 2, 0), /* fail: participant that one cannot attach, or -1 */ + CU_DataPoints (int, -9, -1, -2, 0, 0, 2), /* owner: -9: lib, -1: dom0, -2: dom1 */ + CU_DataPoints (int, 0, 0, 2, 0, 0, 2), /* ok1: participant one can attach */ + CU_DataPoints (int, 3, 1, 3, -1, -1, -1), /* ok2: other participant one can attach, or -1 */ + CU_DataPoints (int, -1, 2, 0, 1, 2, 0), /* fail: participant that one cannot attach, or -1 */ }; CU_Theory ((int owner, int ok1, int ok2, int fail), ddsc_waitset_attach, scoping) { - dds_entity_t par[4], dom[2], ws, ownh; - dds_return_t rc; - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) { - par[2*i+j] = dds_create_participant ((dds_domainid_t) i, NULL, NULL); - CU_ASSERT_FATAL (par[2*i+j] > 0); - } - dom[i] = dds_get_parent (par[2*i]); - CU_ASSERT_FATAL (dom[i] > 0); + dds_entity_t par[4], dom[2], ws, ownh; + dds_return_t rc; + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + par[2*i+j] = dds_create_participant ((dds_domainid_t) i, NULL, NULL); + CU_ASSERT_FATAL (par[2*i+j] > 0); } - if (owner == -9) { - ownh = DDS_CYCLONEDDS_HANDLE; - } else if (owner < 0) { - ownh = dom[-owner - 1]; - } else { - ownh = par[owner]; - } - printf ("%d %d %d %d | %"PRId32"\n", owner, ok1, ok2, fail, ownh); - ws = dds_create_waitset (ownh); - CU_ASSERT_FATAL (ws > 0); - rc = dds_waitset_attach (ws, par[ok1], 0); + dom[i] = dds_get_parent (par[2*i]); + CU_ASSERT_FATAL (dom[i] > 0); + } + if (owner == -9) { + ownh = DDS_CYCLONEDDS_HANDLE; + } else if (owner < 0) { + ownh = dom[-owner - 1]; + } else { + ownh = par[owner]; + } + printf ("%d %d %d %d | %"PRId32"\n", owner, ok1, ok2, fail, ownh); + ws = dds_create_waitset (ownh); + CU_ASSERT_FATAL (ws > 0); + rc = dds_waitset_attach (ws, par[ok1], 0); + CU_ASSERT_FATAL (rc == 0); + if (ok2 >= 0) { + rc = dds_waitset_attach (ws, par[ok2], 1); CU_ASSERT_FATAL (rc == 0); - if (ok2 >= 0) { - rc = dds_waitset_attach (ws, par[ok2], 1); - CU_ASSERT_FATAL (rc == 0); - } - if (fail >= 0) { - rc = dds_waitset_attach (ws, par[fail], 2); - CU_ASSERT_FATAL (rc == DDS_RETCODE_BAD_PARAMETER); - } - rc = dds_delete (DDS_CYCLONEDDS_HANDLE); - CU_ASSERT_FATAL (rc == 0); - rc = dds_get_parent (DDS_CYCLONEDDS_HANDLE); - CU_ASSERT_FATAL (rc == DDS_RETCODE_PRECONDITION_NOT_MET); + } + if (fail >= 0) { + rc = dds_waitset_attach (ws, par[fail], 2); + CU_ASSERT_FATAL (rc == DDS_RETCODE_BAD_PARAMETER); + } + rc = dds_delete (DDS_CYCLONEDDS_HANDLE); + CU_ASSERT_FATAL (rc == 0); + rc = dds_get_parent (DDS_CYCLONEDDS_HANDLE); + CU_ASSERT_FATAL (rc == DDS_RETCODE_PRECONDITION_NOT_MET); } -/*************************************************************************************************/ - - -/************************************************************************************************** - * - * These will check the waitset attach and detach with valid entities (which should always work). - * - *************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_attach_detach, valid_entities) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), - CU_DataPoints(dds_attach_t, (dds_attach_t)NULL, (dds_attach_t)&reader, (dds_attach_t)3, (dds_attach_t)3, (dds_attach_t)3, (dds_attach_t)3, (dds_attach_t)3, (dds_attach_t)3), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_attach_t, (dds_attach_t)NULL, (dds_attach_t)&reader, (dds_attach_t)3, (dds_attach_t)3, (dds_attach_t)3, (dds_attach_t)3, (dds_attach_t)3, (dds_attach_t)3), }; CU_Theory((dds_entity_t *ws, dds_entity_t *e, dds_attach_t a), ddsc_waitset_attach_detach, valid_entities, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { - dds_return_t exp; - dds_return_t ret; - - if (*ws == waitset) { - /* Attaching to the waitset should work. */ - exp = DDS_RETCODE_OK; - } else { - /* Attaching to every other entity should fail. */ - exp = DDS_RETCODE_ILLEGAL_OPERATION; - } + dds_return_t exp; + dds_return_t ret; - /* Try to attach. */ - ret = dds_waitset_attach(*ws, *e, a); - CU_ASSERT_EQUAL_FATAL(ret, exp); + if (*ws == waitset) { + /* Attaching to the waitset should work. */ + exp = DDS_RETCODE_OK; + } else { + /* Attaching to every other entity should fail. */ + exp = DDS_RETCODE_ILLEGAL_OPERATION; + } - /* Detach when needed. */ - if (ret == DDS_RETCODE_OK) { - ret = dds_waitset_detach(*ws, *e); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - } + ret = dds_waitset_attach (*ws, *e, a); + CU_ASSERT_FATAL (ret == exp); + if (ret == 0) { + ret = dds_waitset_detach (*ws, *e); + CU_ASSERT_FATAL (ret == 0); + } } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_attach_detach, second, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_return_t ret; - - ret = dds_waitset_attach(waitset, waitset, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - ret = dds_waitset_attach(waitset, waitset, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_PRECONDITION_NOT_MET); - - ret = dds_waitset_detach(waitset, waitset); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - ret = dds_waitset_detach(waitset, waitset); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_PRECONDITION_NOT_MET); + dds_return_t ret; + ret = dds_waitset_attach (waitset, waitset, 0); + CU_ASSERT_FATAL(ret == 0); + ret = dds_waitset_attach (waitset, waitset, 0); + CU_ASSERT_FATAL(ret == DDS_RETCODE_PRECONDITION_NOT_MET); + ret = dds_waitset_detach (waitset, waitset); + CU_ASSERT_FATAL(ret == DDS_RETCODE_OK); + ret = dds_waitset_detach (waitset, waitset); + CU_ASSERT_FATAL(ret == DDS_RETCODE_PRECONDITION_NOT_MET); } -/*************************************************************************************************/ - - -/************************************************************************************************** - * - * These will check the waitset detach in various ways. - * - Valid waitset but try to detach all kinds of invalid entities. - * - Try to detach a valid participant from all kinds of invalid entities. - * - Try detach valid entities from valid entities - * -- detach to entities that are not waitsets. - * -- detach to a waitset. - * - * Note: everything is expected to fail for varous reasons. The 'happy day' detach is tested on - * the fly in ddsc_waitset_attach_detach::valid_entities - * - *************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_detach, invalid_params) = { - CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), + CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), }; CU_Theory((dds_entity_t e), ddsc_waitset_detach, invalid_params, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_return_t ret; - ret = dds_waitset_detach(waitset, e); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_return_t ret = dds_waitset_detach(waitset, e); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_detach, invalid_waitsets) = { - CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), + CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), }; CU_Theory((dds_entity_t ws), ddsc_waitset_detach, invalid_waitsets, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_return_t ret; - - ret = dds_waitset_detach(ws, participant); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_return_t ret = dds_waitset_detach (ws, participant); + CU_ASSERT_FATAL(ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_detach, valid_entities) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), }; CU_Theory((dds_entity_t *ws, dds_entity_t *e), ddsc_waitset_detach, valid_entities, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { - dds_return_t exp; - dds_return_t ret; - - if (*ws == waitset) { - /* Detaching from an empty waitset should yield 'precondition not met'. */ - exp = DDS_RETCODE_PRECONDITION_NOT_MET; - } else { - /* Attaching to every other entity should yield 'illegal operation'. */ - exp = DDS_RETCODE_ILLEGAL_OPERATION; + dds_return_t exp; + dds_return_t ret; + if (*ws == waitset) { + /* Detaching from an empty waitset should yield 'precondition not met'. */ + exp = DDS_RETCODE_PRECONDITION_NOT_MET; + } else { + /* Attaching to every other entity should yield 'illegal operation'. */ + exp = DDS_RETCODE_ILLEGAL_OPERATION; + } + ret = dds_waitset_detach (*ws, *e); + CU_ASSERT_FATAL (ret == exp); +} + +CU_Test(ddsc_waitset_attach_detach, various, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) +{ + const dds_entity_t es[] = { readcond, writer, reader, topic, publisher, subscriber, waitset, participant }; + dds_return_t ret; + for (size_t i = 0; i < sizeof (es) / sizeof (es[0]); i++) + { + ret = dds_waitset_attach (waitset, es[i], 0); + CU_ASSERT_FATAL (ret == 0); + // doing it a second time gives a precondition not met + ret = dds_waitset_attach (waitset, es[i], 0); + CU_ASSERT_FATAL (ret == DDS_RETCODE_PRECONDITION_NOT_MET); + ret = dds_waitset_detach (waitset, es[i]); + CU_ASSERT_FATAL (ret == 0); + } +} + +CU_Test(ddsc_waitset_attach_detach, combinations, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) +{ + const dds_entity_t entities[] = { readcond, writer, reader, topic, publisher, subscriber, waitset, participant }; + const uint32_t count = (uint32_t) (sizeof (entities) / sizeof (entities[0])); + dds_return_t ret; + dds_entity_t es[MAX_ENTITIES_CNT]; + ret = dds_waitset_get_entities (waitset, es, sizeof (es) / sizeof (es[0])); + CU_ASSERT_FATAL (ret == 0); + + uint32_t prevset = 0; + for (uint32_t round = 1; round < (2u << count) - 2; round++) + { + const uint32_t i = (round < (1u << count)) ? round : ((2u << count) - round - 2); + const uint32_t set = i ^ (i >> 1); + const uint32_t flipped = set ^ prevset; + DDSRT_WARNING_MSVC_OFF(4146); + assert (flipped && (flipped & -flipped) == flipped); + DDSRT_WARNING_MSVC_ON(4146); + uint32_t flipidx = 0; + while (!(flipped & (1u << flipidx))) + flipidx++; + assert (flipidx < count); + + //printf ("%zu %zu %02zx -> %02zx : %02zx %"PRIu32" %s\n", round, i, prevset, set, flipped, flipidx, (prevset & flipped) ? "detach" : "attach"); + if (prevset & flipped) + { + ret = dds_waitset_detach (waitset, entities[flipidx]); + CU_ASSERT_FATAL (ret == 0); + } + else + { + ret = dds_waitset_attach (waitset, entities[flipidx], 0); + CU_ASSERT_FATAL (ret == 0); } - ret = dds_waitset_detach(*ws, *e); - CU_ASSERT_EQUAL_FATAL(ret, exp); -} -/*************************************************************************************************/ - - - - -/************************************************************************************************** - * - * These will check the waitset attach/detach in various ways. We will use NULL as attach argument - * because it will be properly used in 'waitset behaviour' tests anyway. - * - *************************************************************************************************/ -/*************************************************************************************************/ -CU_Test(ddsc_waitset_attach_detach, itself, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) -{ - dds_return_t ret; - - ret = dds_waitset_attach(waitset, waitset, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - ret = dds_waitset_detach(waitset, waitset); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); -} -/*************************************************************************************************/ - -/*************************************************************************************************/ -CU_Test(ddsc_waitset_attach_detach, participant, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) -{ - dds_return_t ret; - - ret = dds_waitset_attach(waitset, participant, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - ret = dds_waitset_detach(waitset, participant); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); -} -/*************************************************************************************************/ - -/*************************************************************************************************/ -CU_Test(ddsc_waitset_attach_detach, reader, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) -{ - dds_return_t ret; - - ret = dds_waitset_attach(waitset, reader, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - ret = dds_waitset_detach(waitset, reader); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); -} -/*************************************************************************************************/ - -/*************************************************************************************************/ -CU_Test(ddsc_waitset_attach_detach, readcondition, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) -{ - dds_return_t ret; + // attaching any entity in set must give "precond. not met" + for (uint32_t j = 0; j < count; j++) + { + if (!(set & (1u << j))) + continue; + ret = dds_waitset_attach (waitset, entities[j], 0); + CU_ASSERT_FATAL (ret == DDS_RETCODE_PRECONDITION_NOT_MET); + } - ret = dds_waitset_attach(waitset, readcond, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); + // set must match expectations + ret = dds_waitset_get_entities (waitset, es, sizeof (es) / sizeof (es[0])); + CU_ASSERT_FATAL (ret > 0 && ret <= (dds_return_t) count); + uint32_t actset = 0; + for (dds_return_t j = 0; j < ret; j++) + { + uint32_t k; + for (k = 0; k < count; k++) + if (es[j] == entities[k]) + break; + // it must be one of the known entities + CU_ASSERT_FATAL (k < count); + // must not be seen yet, must be expected to be seen + CU_ASSERT_FATAL (!(actset & (1u << k))); + CU_ASSERT_FATAL ((set & (1u << k)) != 0); + actset |= 1u << k; + } - ret = dds_waitset_detach(waitset, readcond); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); + prevset = set; + } } -/*************************************************************************************************/ - - - -/************************************************************************************************** - * - * These will check entities can be deleted while attached to the waitset. We will use NULL as - * attach argument because it will be properly used in 'waitset behaviour' tests anyway. - * 1) Test if the waitset can be deleted when attached to itself. - * 2) Test if the waitset parent can be deleted when attached. - * 3) Test if an 'ordinary' entity can be deleted when attached. - * 4) Test if an condition can be deleted when attached. - * - *************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_delete_attached, self, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_return_t ret; - - ret = dds_waitset_attach(waitset, waitset, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - ret = dds_delete(waitset); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); + dds_return_t ret; + ret = dds_waitset_attach (waitset, waitset, 0); + CU_ASSERT_FATAL (ret == 0); + ret = dds_delete (waitset); + CU_ASSERT_FATAL (ret == 0); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_delete_attached, participant, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_return_t ret; - - ret = dds_waitset_attach(waitset, participant, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - ret = dds_delete(participant); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); + dds_return_t ret; + // init is supposed to create the waitset in the participant, deleting the participant should therefore + // also delete tear down everything and de-initialize the library + assert (dds_get_parent (waitset) == participant); + ret = dds_waitset_attach (waitset, participant, 0); + CU_ASSERT_FATAL (ret == 0); + ret = dds_delete (participant); + CU_ASSERT_FATAL (ret == 0); + ret = dds_get_parent (waitset); + CU_ASSERT_FATAL (ret == DDS_RETCODE_PRECONDITION_NOT_MET); + ret = dds_get_parent (participant); + CU_ASSERT_FATAL (ret == DDS_RETCODE_PRECONDITION_NOT_MET); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_delete_attached, reader, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { - dds_return_t ret; - - ret = dds_waitset_attach(waitset, reader, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - ret = dds_delete(reader); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); -} -/*************************************************************************************************/ - -/*************************************************************************************************/ -CU_Test(ddsc_waitset_delete_attached, readcondition, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) -{ - dds_return_t ret; - - ret = dds_waitset_attach(waitset, readcond, 0); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - ret = dds_delete(readcond); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); + dds_entity_t es[MAX_ENTITIES_CNT]; + dds_return_t ret; + ret = dds_waitset_attach (waitset, readcond, 0); + CU_ASSERT_FATAL (ret == 0); + ret = dds_waitset_attach (waitset, reader, 1); + CU_ASSERT_FATAL (ret == 0); + ret = dds_delete (reader); + CU_ASSERT_FATAL (ret == 0); + // deleting the reader also deletes readcond, and so no entities should still be attached to waitset + ret = dds_waitset_get_entities (waitset, es, sizeof (es) / sizeof (es[0])); + CU_ASSERT_FATAL (ret == 0); +} + +CU_Test(ddsc_waitset_delete_attached, various, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) +{ + // order matters: deleting the reader will also delete readcond; deleting pub/sub will delete wr/rd + // this order should be ok, but the number of alive entities will dwindle + const dds_entity_t es[] = { readcond, writer, reader, topic, publisher, subscriber }; + dds_return_t ret; + for (size_t i = 0; i < sizeof (es) / sizeof (es[0]); i++) + { + ret = dds_waitset_attach (waitset, es[i], 0); + CU_ASSERT_FATAL(ret == 0); + ret = dds_delete (es[i]); + CU_ASSERT_FATAL(ret == 0); + } } -/*************************************************************************************************/ - - -/************************************************************************************************** - * - * These will check the waitset triggering in various invalid ways. - * The happy days scenario is tested by ddsc_waitset_triggering::on_self. - * - *************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_set_trigger, deleted_waitset, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_return_t ret; - dds_delete(waitset); - ret = dds_waitset_set_trigger(waitset, true); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_delete (waitset); + dds_return_t ret = dds_waitset_set_trigger (waitset, true); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_set_trigger, invalid_params) = { - CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), + CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), }; CU_Theory((dds_entity_t ws), ddsc_waitset_set_trigger, invalid_params, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_return_t ret; - - ret = dds_waitset_set_trigger(ws, true); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_return_t ret = dds_waitset_set_trigger (ws, true); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_set_trigger, non_waitsets) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), }; CU_Theory((dds_entity_t *ws), ddsc_waitset_set_trigger, non_waitsets, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { - dds_return_t ret; - ret = dds_waitset_set_trigger(*ws, true); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_ILLEGAL_OPERATION); + dds_return_t ret = dds_waitset_set_trigger (*ws, true); + CU_ASSERT_FATAL (ret == DDS_RETCODE_ILLEGAL_OPERATION); } -/*************************************************************************************************/ - - -/************************************************************************************************** - * - * These will check the waitset wait in various invalid ways. - * The happy days scenario is tested by ddsc_waitset_triggering::*. - * - *************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_wait, deleted_waitset, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) { - dds_attach_t triggered; - dds_return_t ret; - dds_delete(waitset); - ret = dds_waitset_wait(waitset, &triggered, 1, DDS_SECS(1)); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_delete (waitset); + dds_attach_t triggered; + dds_return_t ret = dds_waitset_wait (waitset, &triggered, 1, DDS_SECS (1)); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_wait, invalid_waitsets) = { - CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), + CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), }; CU_Theory((dds_entity_t ws), ddsc_waitset_wait, invalid_waitsets, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_attach_t triggered; - dds_return_t ret; - - ret = dds_waitset_wait(ws, &triggered, 1, DDS_SECS(1)); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_attach_t triggered; + dds_return_t ret = dds_waitset_wait (ws, &triggered, 1, DDS_SECS (1)); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_wait, non_waitsets) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), }; CU_Theory((dds_entity_t *ws), ddsc_waitset_wait, non_waitsets, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { - dds_attach_t triggered; - dds_return_t ret; - ret = dds_waitset_wait(*ws, &triggered, 1, DDS_SECS(1)); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_ILLEGAL_OPERATION); + dds_attach_t triggered; + dds_return_t ret = dds_waitset_wait (*ws, &triggered, 1, DDS_SECS (1)); + CU_ASSERT_FATAL (ret == DDS_RETCODE_ILLEGAL_OPERATION); } -/*************************************************************************************************/ -/*************************************************************************************************/ -static dds_attach_t attachment; CU_TheoryDataPoints(ddsc_waitset_wait, invalid_params) = { - CU_DataPoints(dds_attach_t *, &attachment, NULL), - CU_DataPoints(size_t, 0, 1, 100), - CU_DataPoints(int, -1, 0, 1), + CU_DataPoints(dds_attach_t *, (dds_attach_t[]){0}, NULL), + CU_DataPoints(size_t, 0, 1, 100), + CU_DataPoints(int, -1, 0, 1), }; CU_Theory((dds_attach_t *a, size_t size, int msec), ddsc_waitset_wait, invalid_params, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_return_t ret; - - /* Only test when the combination of parameters is actually invalid. */ - CU_ASSERT_FATAL(((a == NULL) && (size != 0)) || ((a != NULL) && (size == 0)) || (msec < 0)); - - ret = dds_waitset_wait(waitset, a, size, DDS_MSECS(msec)); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_return_t ret; + assert ((a == NULL && size != 0) || (a != NULL && size == 0) || msec < 0); + ret = dds_waitset_wait (waitset, a, size, DDS_MSECS (msec)); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_wait_until, deleted_waitset, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) { - dds_attach_t triggered; - dds_return_t ret; - dds_delete(waitset); - ret = dds_waitset_wait_until(waitset, &triggered, 1, dds_time()); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + (void) dds_delete (waitset); + dds_attach_t triggered; + dds_return_t ret = dds_waitset_wait_until (waitset, &triggered, 1, dds_time ()); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_wait_until, invalid_waitsets) = { - CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), + CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), }; CU_Theory((dds_entity_t ws), ddsc_waitset_wait_until, invalid_waitsets, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_attach_t triggered; - dds_return_t ret; - - ret = dds_waitset_wait_until(ws, &triggered, 1, dds_time()); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_attach_t triggered; + dds_return_t ret = dds_waitset_wait_until (ws, &triggered, 1, dds_time ()); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_wait_until, non_waitsets) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), }; CU_Theory((dds_entity_t *ws), ddsc_waitset_wait_until, non_waitsets, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { - dds_attach_t triggered; - dds_return_t ret; - ret = dds_waitset_wait_until(*ws, &triggered, 1, dds_time()); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_ILLEGAL_OPERATION); + dds_attach_t triggered; + dds_return_t ret = dds_waitset_wait_until (*ws, &triggered, 1, dds_time ()); + CU_ASSERT_FATAL (ret == DDS_RETCODE_ILLEGAL_OPERATION); } -/*************************************************************************************************/ -/*************************************************************************************************/ -static dds_attach_t attachment; CU_TheoryDataPoints(ddsc_waitset_wait_until, invalid_params) = { - CU_DataPoints(dds_attach_t *, &attachment, NULL), - CU_DataPoints(size_t, 0, 1, 100) + CU_DataPoints(dds_attach_t *, (dds_attach_t[]){0}, NULL), + CU_DataPoints(size_t, 0, 1, 100) }; CU_Theory((dds_attach_t *a, size_t size), ddsc_waitset_wait_until, invalid_params, .init=ddsc_waitset_basic_init, .fini=ddsc_waitset_basic_fini) { - dds_return_t ret; - - /* Only test when the combination of parameters is actually invalid. */ - CU_ASSERT_FATAL(((a == NULL) && (size != 0)) || ((a != NULL) && (size == 0))); - - ret = dds_waitset_wait_until(waitset, a, size, dds_time()); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_return_t ret; + assert ((a == NULL && size != 0) || (a != NULL && size == 0)); + ret = dds_waitset_wait_until (waitset, a, size, dds_time ()); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_wait_until, past, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) { - dds_attach_t triggered; - dds_return_t ret; - - ret = dds_waitset_wait_until(waitset, &triggered, 1, dds_time() - 100000); - CU_ASSERT_EQUAL_FATAL(ret, 0); -} -/*************************************************************************************************/ - - - -/************************************************************************************************** - * - * These will check the waitset getting the attached entities. - * - *************************************************************************************************/ -#define MAX_ENTITIES_CNT (10) -#define FOUND_PARTICIPANT (0x0001) -#define FOUND_PUBLISHER (0x0002) -#define FOUND_SUBSCRIBER (0x0004) -#define FOUND_WAITSET (0x0008) -#define FOUND_TOPIC (0x0010) -#define FOUND_READER (0x0020) -#define FOUND_WRITER (0x0040) -#define FOUND_ALL (0x007F) - -static uint32_t NumberOfSetBits(uint32_t i) -{ - /* https://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer */ - // Java: use >>> instead of >> - // C or C++: use uint32_t - i = i - ((i >> 1) & 0x55555555); - i = (i & 0x33333333) + ((i >> 2) & 0x33333333); - return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; + dds_attach_t triggered; + dds_return_t ret = dds_waitset_wait_until (waitset, &triggered, 1, dds_time () - 100000); + CU_ASSERT_FATAL(ret == 0); } -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_get_entities, array_sizes) = { - CU_DataPoints(size_t, 0, 1, 7, MAX_ENTITIES_CNT), + CU_DataPoints(size_t, 0, 1, 7, MAX_ENTITIES_CNT), }; CU_Theory((size_t size), ddsc_waitset_get_entities, array_sizes, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) { - uint32_t found = 0; - dds_return_t i; - dds_return_t ret; - dds_entity_t entities[MAX_ENTITIES_CNT]; - - /* Make sure at least one entity is in the waitsets' internal triggered list. */ - ret = dds_waitset_set_trigger(waitset, true); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - /* Get the actual attached entities. */ - ret = dds_waitset_get_entities(waitset, entities, size); - - /* ddsc_waitset_attached_init() attached 7 entities. */ - CU_ASSERT_EQUAL_FATAL(ret, 7); - - /* Found entities should be only present once. */ - ret = ((dds_return_t)size < ret) ? (dds_return_t)size : ret; - for (i = 0; i < ret; i++) { - if (entities[i] == participant) { - CU_ASSERT_FATAL(!(found & FOUND_PARTICIPANT)); - found |= FOUND_PARTICIPANT; - } else if (entities[i] == publisher) { - CU_ASSERT_FATAL(!(found & FOUND_PUBLISHER)); - found |= FOUND_PUBLISHER; - } else if (entities[i] == subscriber) { - CU_ASSERT_FATAL(!(found & FOUND_SUBSCRIBER)); - found |= FOUND_SUBSCRIBER; - } else if (entities[i] == waitset) { - CU_ASSERT_FATAL(!(found & FOUND_WAITSET)); - found |= FOUND_WAITSET; - } else if (entities[i] == topic) { - CU_ASSERT_FATAL(!(found & FOUND_TOPIC)); - found |= FOUND_TOPIC; - } else if (entities[i] == reader) { - CU_ASSERT_FATAL(!(found & FOUND_READER)); - found |= FOUND_READER; - } else if (entities[i] == writer) { - CU_ASSERT_FATAL(!(found & FOUND_WRITER)); - found |= FOUND_WRITER; - } + const dds_entity_t expected[] = { participant, topic, writer, reader, waitset, publisher, subscriber }; + uint32_t found = 0; + dds_return_t ret; + dds_entity_t es[MAX_ENTITIES_CNT]; + + /* Make sure at least one entity is in the waitsets' internal triggered list. */ + ret = dds_waitset_set_trigger (waitset, true); + CU_ASSERT_FATAL (ret == 0); + + /* Get the actual attached entities, return value is the number of attached entities + and may be larger than size. */ + ret = dds_waitset_get_entities (waitset, es, size); + CU_ASSERT_FATAL (ret == (dds_return_t) (sizeof (expected) / sizeof (expected[0]))); + + /* If size is too small, a subset of expected must be present, otherwise it must be identical */ + dds_return_t nvalid = ((dds_return_t) size < ret) ? (dds_return_t) size : ret; + dds_return_t count = 0; + for (dds_return_t i = 0; i < nvalid; i++) { + uint32_t flag = 0; + for (size_t j = 0; j < sizeof (expected) / sizeof (expected[0]); j++) { + if (expected[j] == es[i]) { + flag = 1u << j; + break; + } } - - /* Every found entity should be a known one. */ - CU_ASSERT_EQUAL_FATAL((dds_return_t)NumberOfSetBits(found), ret); + CU_ASSERT_FATAL (flag != 0); + CU_ASSERT_FATAL (!(found & flag)); + found |= flag; + count++; + } + CU_ASSERT_FATAL (count == nvalid); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_get_entities, no_array, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) { - dds_return_t ret; - DDSRT_WARNING_MSVC_OFF(6387); /* Disable SAL warning on intentional misuse of the API */ - ret = dds_waitset_get_entities(waitset, NULL, 1); - DDSRT_WARNING_MSVC_ON(6387); - /* ddsc_waitset_attached_init attached 7 entities. */ - CU_ASSERT_EQUAL_FATAL(ret, 7); + dds_return_t ret; + DDSRT_WARNING_MSVC_OFF(6387); /* Disable SAL warning on intentional misuse of the API */ + ret = dds_waitset_get_entities (waitset, NULL, 1); + DDSRT_WARNING_MSVC_ON(6387); + /* ddsc_waitset_attached_init attached 7 entities. */ + CU_ASSERT_FATAL (ret == 7); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_get_entities, deleted_waitset, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) { - dds_return_t ret; - dds_entity_t entities[MAX_ENTITIES_CNT]; - dds_delete(waitset); - ret = dds_waitset_get_entities(waitset, entities, MAX_ENTITIES_CNT); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_entity_t entities[MAX_ENTITIES_CNT]; + dds_delete (waitset); + dds_return_t ret = dds_waitset_get_entities (waitset, entities, MAX_ENTITIES_CNT); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_get_entities, invalid_params) = { - CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), + CU_DataPoints(dds_entity_t, -2, -1, 0, INT_MAX, INT_MIN), }; CU_Theory((dds_entity_t ws), ddsc_waitset_get_entities, invalid_params, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) { - dds_entity_t entities[MAX_ENTITIES_CNT]; - dds_return_t ret; - - ret = dds_waitset_get_entities(ws, entities, MAX_ENTITIES_CNT); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER); + dds_entity_t entities[MAX_ENTITIES_CNT]; + dds_return_t ret = dds_waitset_get_entities (ws, entities, MAX_ENTITIES_CNT); + CU_ASSERT_FATAL (ret == DDS_RETCODE_BAD_PARAMETER); } -/*************************************************************************************************/ -/*************************************************************************************************/ CU_TheoryDataPoints(ddsc_waitset_get_entities, non_waitsets) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), }; CU_Theory((dds_entity_t *ws), ddsc_waitset_get_entities, non_waitsets, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) { - dds_entity_t entities[MAX_ENTITIES_CNT]; - dds_return_t ret; - ret = dds_waitset_get_entities(*ws, entities, MAX_ENTITIES_CNT); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_ILLEGAL_OPERATION); + dds_entity_t entities[MAX_ENTITIES_CNT]; + dds_return_t ret = dds_waitset_get_entities (*ws, entities, MAX_ENTITIES_CNT); + CU_ASSERT_FATAL (ret == DDS_RETCODE_ILLEGAL_OPERATION); } -/*************************************************************************************************/ +static void cw_trig_write (void) +{ + dds_return_t ret = dds_write (writer, &(RoundTripModule_DataType){0}); + CU_ASSERT_FATAL (ret == 0); +} +static void cw_trig_waitset (void) +{ + dds_return_t ret = dds_waitset_set_trigger (waitset, true); + CU_ASSERT_FATAL (ret == 0); +} +static void check_waitset_trigger (dds_entity_t e, void (*trig) (void)) +{ + thread_arg_t arg; + dds_return_t ret; + /* verify the initial state of the entity we're playing with is not-triggered */ + ret = dds_triggered (e); + CU_ASSERT_FATAL (ret == 0); -/************************************************************************************************** - * - * This will check if waitset will wake up when it is attached to itself and triggered. - * - * In short: - * 1) Attach the waitset to itself - * 2) A different thread will call dds_waitset_wait. This should block because the waitset - * hasn't been triggered yet. We also want it to block to know for sure that it'll wake up. - * 3) Trigger the waitset. This should unblock the other thread that was waiting on the waitset. - * 4) A new dds_waitset_wait should return immediately because the trigger value hasn't been - * reset (dds_waitset_set_trigger(waitset, false)) after the waitset woke up. - * - *************************************************************************************************/ -/*************************************************************************************************/ -CU_Test(ddsc_waitset_triggering, on_self, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) -{ - dds_attach_t triggered; - thread_arg_t arg; - dds_return_t ret; - - /* The waitset should not have been triggered. */ - ret = dds_triggered(waitset); - CU_ASSERT_EQUAL_FATAL(ret, 0); - - /* Start a thread that'll wait because no entity attached to the waitset - * has been triggered (for instance by a status change). */ - waiting_thread_start(&arg, waitset); - - /* Triggering of the waitset should unblock the thread. */ - ret = dds_waitset_set_trigger(waitset, true); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = waiting_thread_expect_exit(&arg); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - /* Now the trigger state should be true. */ - ret = dds_triggered(waitset); - CU_ASSERT_FATAL(ret > 0); - - /* Waitset shouldn't wait, but immediately return our waitset. */ - ret = dds_waitset_wait(waitset, &triggered, 1, DDS_SECS(1)); - CU_ASSERT_EQUAL_FATAL(ret, 1); - CU_ASSERT_EQUAL_FATAL(waitset, (dds_entity_t)(intptr_t)triggered); - - /* Reset waitset trigger. */ - ret = dds_waitset_set_trigger(waitset, false); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = dds_triggered(waitset); - CU_ASSERT_EQUAL_FATAL(ret, 0); -} -/*************************************************************************************************/ + /* start a thread to wait for a trigger */ + waiting_thread_start (&arg, e); + /* calling trig() should unblock the thread and cause it to exit */ + trig (); + ret = waiting_thread_expect_exit (&arg); + CU_ASSERT_FATAL (ret == 0); + /* The thread doesn't do anything with the entity, so the state should remain triggered */ + ret = dds_triggered (e); + CU_ASSERT (ret > 0); + /* and consequently a wait with timeout=0 should return the entity */ + dds_attach_t triggered; + ret = dds_waitset_wait (waitset, &triggered, 1, 0); + CU_ASSERT_FATAL (ret == 1); + CU_ASSERT_FATAL (triggered == (dds_attach_t) e); +} +CU_Test (ddsc_waitset_triggering, on_self, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) +{ + dds_return_t ret; + check_waitset_trigger (waitset, cw_trig_waitset); + ret = dds_waitset_set_trigger (waitset, false); + CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK); + ret = dds_triggered (waitset); + CU_ASSERT_EQUAL_FATAL (ret, 0); +} -/************************************************************************************************** - * - * This will check if waitset will wake up when data is written related to an attached reader. - * - * In short: - * 1) Attach the reader to the waitset - * 2) A different thread will call dds_waitset_wait. This should block because the reader - * hasn't got data yet. We also want it to block to know for sure that it'll wake up. - * 3) Write data. This should unblock the other thread that was waiting on the waitset. - * 4) A new dds_waitset_wait should return immediately because the status of the reader hasn't - * changed after the first trigger (it didn't read the data). - * - *************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_triggering, on_reader, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) { - RoundTripModule_DataType sample; - dds_attach_t triggered; - thread_arg_t arg; - dds_return_t ret; - - memset(&sample, 0, sizeof(RoundTripModule_DataType)); - - /* Only interested in data_available for this test. */ - ret = dds_set_status_mask(reader, DDS_DATA_AVAILABLE_STATUS); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - /* The reader should not have been triggered. */ - ret = dds_triggered(reader); - CU_ASSERT_EQUAL_FATAL(ret, 0); - - /* Start a thread that'll wait because no entity attached to the waitset - * has been triggered (for instance by a status change). */ - waiting_thread_start(&arg, reader); - - /* Writing data should unblock the thread. */ - ret = dds_write(writer, &sample); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = waiting_thread_expect_exit(&arg); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - /* Now the trigger state should be true. */ - ret = dds_triggered(reader); - CU_ASSERT_FATAL(ret > 0); - - /* Waitset shouldn't wait, but immediately return our reader. */ - ret = dds_waitset_wait(waitset, &triggered, 1, DDS_SECS(1)); - CU_ASSERT_EQUAL_FATAL(ret, 1); - CU_ASSERT_EQUAL_FATAL(reader, (dds_entity_t)(intptr_t)triggered); + dds_return_t ret = dds_set_status_mask (reader, DDS_DATA_AVAILABLE_STATUS); + CU_ASSERT_FATAL (ret == 0); + check_waitset_trigger (reader, cw_trig_write); } -/*************************************************************************************************/ - - - -/************************************************************************************************** - * - * This will check if waitset will wake up when data is written related to an attached condition. - * - * In short: - * 1) Attach the readcondition to the waitset - * 2) A different thread will call dds_waitset_wait. This should block because the related reader - * hasn't got data yet. We also want it to block to know for sure that it'll wake up. - * 3) Write data. This should unblock the other thread that was waiting on the readcondition. - * 4) A new dds_waitset_wait should return immediately because the status of the related reader - * (and thus the readcondition) hasn't changed after the first trigger (it didn't read the data). - * - *************************************************************************************************/ -/*************************************************************************************************/ CU_Test(ddsc_waitset_triggering, on_readcondition, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) { - RoundTripModule_DataType sample; - dds_attach_t triggered; - thread_arg_t arg; - dds_return_t ret; - - memset(&sample, 0, sizeof(RoundTripModule_DataType)); - - /* Make sure that we start un-triggered. */ - ret = dds_triggered(readcond); - CU_ASSERT_EQUAL_FATAL(ret, 0); - - /* Attach condition to the waitset. */ - ret = dds_waitset_attach(waitset, readcond, readcond); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - /* Start a thread that'll wait because no entity attached to the waitset - * has been triggered (for instance by a status change). */ - waiting_thread_start(&arg, readcond); - - /* Writing data should unblock the thread. */ - ret = dds_write(writer, &sample); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - ret = waiting_thread_expect_exit(&arg); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); - - /* Now the trigger state should be true. */ - ret = dds_triggered(readcond); - CU_ASSERT(ret > 0); - - /* Waitset shouldn't wait, but immediately return our reader. */ - ret = dds_waitset_wait(waitset, &triggered, 1, DDS_SECS(1)); - CU_ASSERT_EQUAL_FATAL(ret, 1); - CU_ASSERT_EQUAL_FATAL(readcond, (dds_entity_t)(intptr_t)triggered); - - /* Detach condition. */ - ret = dds_waitset_detach(waitset, readcond); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); + dds_return_t ret; + ret = dds_waitset_attach (waitset, readcond, readcond); + CU_ASSERT_FATAL (ret == 0); + check_waitset_trigger (readcond, cw_trig_write); + ret = dds_waitset_detach (waitset, readcond); + CU_ASSERT_FATAL (ret == 0); } -/*************************************************************************************************/ - - - - -#endif - -/************************************************************************************************** - * - * Convenience support functions. - * - *************************************************************************************************/ - -static uint32_t -waiting_thread(void *a) +static uint32_t waiting_thread (void *a) { - thread_arg_t *arg = (thread_arg_t*)a; - dds_attach_t triggered; - dds_return_t ret; - - ddsrt_atomic_st32 (&arg->state, WAITING); - /* This should block until the main test released all claims. */ - ret = dds_waitset_wait(waitset, &triggered, 1, DDS_SECS(1000)); - CU_ASSERT_EQUAL_FATAL(ret, 1); - CU_ASSERT_EQUAL_FATAL(arg->expected, (dds_entity_t)(intptr_t)triggered); - ddsrt_atomic_st32 (&arg->state, STOPPED); - - return 0; + thread_arg_t *arg = (thread_arg_t *) a; + dds_attach_t triggered; + dds_return_t ret; + ddsrt_atomic_st32 (&arg->state, WAITING); + /* This should block until the main test released all claims. */ + ret = dds_waitset_wait (waitset, &triggered, 1, DDS_SECS (1000)); + CU_ASSERT_FATAL (ret == 1); + CU_ASSERT_FATAL (arg->expected == (dds_entity_t) (intptr_t) triggered); + ddsrt_atomic_st32 (&arg->state, STOPPED); + return 0; } -static dds_return_t -thread_reached_state(ddsrt_atomic_uint32_t *actual, thread_state_t expected, int32_t msec) +static dds_return_t thread_reached_state (ddsrt_atomic_uint32_t *actual, thread_state_t expected, int32_t msec) { - /* Convenience function. */ - dds_time_t msec10 = DDS_MSECS(10); - while ((msec > 0) && ((thread_state_t) ddsrt_atomic_ld32 (actual) != expected)) { - dds_sleepfor(msec10); - msec -= 10; - } - return ((thread_state_t) ddsrt_atomic_ld32 (actual) == expected) ? DDS_RETCODE_OK : DDS_RETCODE_TIMEOUT; + while (msec > 0 && (thread_state_t) ddsrt_atomic_ld32 (actual) != expected) { + dds_sleepfor (DDS_MSECS (10)); + msec -= 10; + } + return ((thread_state_t) ddsrt_atomic_ld32 (actual) == expected) ? 0 : DDS_RETCODE_TIMEOUT; } -static void -waiting_thread_start(struct thread_arg_t *arg, dds_entity_t expected) +static void waiting_thread_start (struct thread_arg_t *arg, dds_entity_t expected) { - ddsrt_thread_t thread_id; - ddsrt_threadattr_t thread_attr; - dds_return_t rc; - - assert(arg); - - /* Create an other thread that will blocking wait on the waitset. */ - arg->expected = expected; - ddsrt_atomic_st32 (&arg->state, STARTING); - ddsrt_threadattr_init(&thread_attr); - rc = ddsrt_thread_create(&thread_id, "waiting_thread", &thread_attr, waiting_thread, arg); - CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK); + ddsrt_thread_t thread_id; + ddsrt_threadattr_t thread_attr; + dds_return_t rc; - /* The thread should reach 'waiting' state. */ - rc = thread_reached_state(&(arg->state), WAITING, 1000); - CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK); + assert (arg); - /* But thread should block and thus NOT reach 'stopped' state. */ - rc = thread_reached_state(&(arg->state), STOPPED, 100); - CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_TIMEOUT); + /* Create an other thread that will blocking wait on the waitset. */ + arg->expected = expected; + ddsrt_atomic_st32 (&arg->state, STARTING); + ddsrt_threadattr_init (&thread_attr); + rc = ddsrt_thread_create (&thread_id, "waiting_thread", &thread_attr, waiting_thread, arg); + CU_ASSERT_FATAL (rc == 0); - arg->tid = thread_id; + /* The thread should reach 'waiting' state. */ + rc = thread_reached_state (&arg->state, WAITING, 1000); + CU_ASSERT_FATAL (rc == 0); + /* But thread should block and thus NOT reach 'stopped' state. */ + rc = thread_reached_state (&arg->state, STOPPED, 100); + CU_ASSERT_FATAL (rc == DDS_RETCODE_TIMEOUT); + arg->tid = thread_id; } -static dds_return_t -waiting_thread_expect_exit(struct thread_arg_t *arg) +static dds_return_t waiting_thread_expect_exit (struct thread_arg_t *arg) { - dds_return_t rc; - assert(arg); - rc = thread_reached_state(&(arg->state), STOPPED, 5000); - if (rc == DDS_RETCODE_OK) { - ddsrt_thread_join(arg->tid, NULL); - return DDS_RETCODE_OK; - } - return DDS_RETCODE_TIMEOUT; + dds_return_t ret = thread_reached_state (&arg->state, STOPPED, 5000); + if (ret == 0) + (void) ddsrt_thread_join (arg->tid, NULL); + return ret; } -