diff --git a/src/core/ddsc/tests/psmx.c b/src/core/ddsc/tests/psmx.c
index 050e537115..bb55fb6580 100644
--- a/src/core/ddsc/tests/psmx.c
+++ b/src/core/ddsc/tests/psmx.c
@@ -113,22 +113,13 @@ static bool endpoint_has_psmx_enabled (dds_entity_t rd_or_wr)
bool psmx_enabled = false;
rc = dds_entity_pin (rd_or_wr, &x);
CU_ASSERT_FATAL (rc == DDS_RETCODE_OK);
- switch (dds_entity_kind (x))
- {
- case DDS_KIND_READER: {
- struct dds_reader const * const rd = (struct dds_reader *) x;
- psmx_enabled = (rd->m_endpoint.psmx_endpoints.length > 0);
- break;
- }
- case DDS_KIND_WRITER: {
- struct dds_writer const * const wr = (struct dds_writer *) x;
- psmx_enabled = (wr->m_endpoint.psmx_endpoints.length > 0);
- break;
- }
- default: {
- CU_ASSERT_FATAL (dds_entity_kind (x) == DDS_KIND_READER || dds_entity_kind (x) == DDS_KIND_WRITER);
- break;
- }
+ if ( dds_entity_kind (x) == DDS_KIND_READER ) {
+ struct dds_reader const * const rd = (struct dds_reader *) x;
+ psmx_enabled = (rd->m_endpoint.psmx_endpoints.length > 0);
+ } else {
+ CU_ASSERT_FATAL(dds_entity_kind (x) == DDS_KIND_WRITER);
+ struct dds_writer const * const wr = (struct dds_writer *) x;
+ psmx_enabled = (wr->m_endpoint.psmx_endpoints.length > 0);
}
dds_entity_unpin (x);
return psmx_enabled;
@@ -1208,6 +1199,32 @@ CU_Test(ddsc_psmx, partition_xtalk)
CU_ASSERT_FATAL (rc == 0);
}
+/// @brief Check that shared memory is not supported by endpoints created from a default Cyclone domain.
+/// @methodology
+/// - Create endpoints with a from a default domain.
+/// - Assert that shared memory is not available.
+CU_Test(ddsc_psmx, no_shared_memory)
+{
+ dds_entity_t participant, topic, writer, reader;
+
+ participant = dds_create_participant(0, NULL, NULL);
+ CU_ASSERT_FATAL(participant > 0);
+
+ char topicname[100];
+ create_unique_topic_name("test_psmx_no_shared_memory", topicname, sizeof(topicname));
+ topic = dds_create_topic(participant, &SC_Model_desc, topicname, NULL, NULL);
+ CU_ASSERT_FATAL(topic > 0);
+
+ writer = dds_create_writer(participant, topic, NULL, NULL);
+ CU_ASSERT_FATAL(writer > 0);
+
+ reader = dds_create_reader(participant, topic, NULL, NULL);
+ CU_ASSERT_FATAL(reader > 0);
+
+ CU_ASSERT_FATAL(!dds_is_shared_memory_available(writer));
+ CU_ASSERT_FATAL(!dds_is_shared_memory_available(reader));
+ dds_delete(dds_get_parent(participant));
+}
#define MAX_SAMPLES 8
CU_Test (ddsc_psmx, basic)
diff --git a/src/core/ddsc/tests/psmx_dummy_impl.c b/src/core/ddsc/tests/psmx_dummy_impl.c
index ec58928d71..f11e7a1795 100644
--- a/src/core/ddsc/tests/psmx_dummy_impl.c
+++ b/src/core/ddsc/tests/psmx_dummy_impl.c
@@ -8,34 +8,46 @@
#include "psmx_dummy_public.h"
#include "psmx_dummy_impl.h"
-void dummy_topics_alloc(dummy_mockstats_t* mockstats, uint32_t topics_capacity)
+static dummy_mockstats_t g_mockstats;
+
+dummy_mockstats_t* dummy_mockstats_get_ptr(void)
+{
+ return &g_mockstats;
+}
+
+void dummy_topics_alloc(dummy_mockstats_t* mockstats, size_t topics_capacity)
{
mockstats->topics._maximum = topics_capacity;
mockstats->topics._length = 0;
mockstats->topics._buffer = ddsrt_malloc(topics_capacity * sizeof(dds_psmx_topic_t));
}
-void dummy_endpoints_alloc(dummy_mockstats_t* mockstats, uint32_t endpoints_capacity)
+void dummy_endpoints_alloc(dummy_mockstats_t* mockstats, size_t endpoints_capacity)
{
mockstats->endpoints._maximum = endpoints_capacity;
mockstats->endpoints._length = 0;
mockstats->endpoints._buffer = ddsrt_malloc(endpoints_capacity * sizeof(dds_psmx_endpoint_t));
}
-static dummy_mockstats_t g_mockstats;
-
-static dummy_mockstats_t* dummy_mockstats_get_ptr()
+static void dummy_psmx_loan_free(dds_loaned_sample_t* loan)
{
- return &g_mockstats;
+ (void)loan;
}
static dds_loaned_sample_t* dummy_psmx_ep_request_loan(dds_psmx_endpoint_t* psmx_endpoint, uint32_t size_requested)
{
- (void)psmx_endpoint;
(void)size_requested;
- // Details yet to be implemented
++g_mockstats.cnt_request_loan;
- return NULL;
+ g_mockstats.request_loan_rcv_endpt = psmx_endpoint;
+ memset(&g_mockstats.loan, 0x0, sizeof(dds_loaned_sample_t));
+ memset(&g_mockstats.loan_metadata, 0x0, sizeof(dds_psmx_metadata_t));
+ g_mockstats.loan.ops.free = dummy_psmx_loan_free;
+ g_mockstats.loan.loan_origin.origin_kind = DDS_LOAN_ORIGIN_KIND_PSMX;
+ g_mockstats.loan.loan_origin.psmx_endpoint = psmx_endpoint;
+ g_mockstats.loan.metadata = &g_mockstats.loan_metadata;
+ g_mockstats.loan.sample_ptr = (void*)0x1;
+ ddsrt_atomic_st32(&g_mockstats.loan.refc, 1);
+ return &g_mockstats.loan;
}
static dds_return_t dummy_psmx_ep_write(dds_psmx_endpoint_t* psmx_endpoint, dds_loaned_sample_t* data)
@@ -44,6 +56,8 @@ static dds_return_t dummy_psmx_ep_write(dds_psmx_endpoint_t* psmx_endpoint, dds_
(void)data;
// Details yet to be implemented
++g_mockstats.cnt_write;
+ g_mockstats.write_rcv_endpt = psmx_endpoint;
+ g_mockstats.write_rcv_loan = data;
return DDS_RETCODE_OK;
}
@@ -80,14 +94,17 @@ static dds_psmx_endpoint_t* dummy_psmx_create_endpoint(
endp->psmx_topic = psmx_topic;
endp->endpoint_type = endpoint_type;
dds_add_psmx_endpoint_to_list(endp, &psmx_topic->psmx_endpoints);
+
++g_mockstats.cnt_create_endpoint;
+ g_mockstats.create_endpoint_rcv_topic = psmx_topic;
return endp;
}
static dds_return_t dummy_psmx_delete_endpoint(dds_psmx_endpoint_t* psmx_endpoint)
{
- memcpy(psmx_endpoint, (dds_psmx_endpoint_t*)g_mockstats.endpoints._buffer + (--g_mockstats.endpoints._length), sizeof(dds_psmx_endpoint_t));
+ memset(psmx_endpoint, 0x0, sizeof(dds_psmx_endpoint_t));
++g_mockstats.cnt_delete_endpoint;
+ g_mockstats.delete_endpoint_rcv_endpt = psmx_endpoint;
return DDS_RETCODE_OK;
}
@@ -128,7 +145,7 @@ static dds_psmx_topic_t* dummy_psmx_create_topic(
static dds_return_t dummy_psmx_delete_topic(dds_psmx_topic_t* psmx_topic)
{
dds_psmx_topic_cleanup_generic(psmx_topic);
- memcpy(psmx_topic, (dds_psmx_topic_t*)g_mockstats.topics._buffer + (--g_mockstats.topics._length), sizeof(dds_psmx_topic_t));
+ memset(psmx_topic, 0x0, sizeof(dds_psmx_topic_t));
++g_mockstats.cnt_delete_topic;
return DDS_RETCODE_OK;
}
@@ -157,7 +174,7 @@ static dds_psmx_features_t dummy_supported_features(const dds_psmx_t* psmx)
{
(void)psmx;
++g_mockstats.cnt_supported_features;
- return DDS_PSMX_FEATURE_SHARED_MEMORY | DDS_PSMX_FEATURE_ZERO_COPY;
+ return g_mockstats.supports_shared_memory ? (DDS_PSMX_FEATURE_SHARED_MEMORY | DDS_PSMX_FEATURE_ZERO_COPY) : 0;
}
dds_return_t dummy_create_psmx(dds_psmx_t** psmx_out, dds_psmx_instance_id_t instance_id, const char* config)
@@ -166,22 +183,21 @@ dds_return_t dummy_create_psmx(dds_psmx_t** psmx_out, dds_psmx_instance_id_t ins
memset(&g_mockstats, 0, sizeof(dummy_mockstats_t));
g_mockstats.cnt_create_psmx = 1;
- dummy_psmx_t* psmx = dds_alloc(sizeof(dummy_psmx_t));
- memset(psmx, 0, sizeof(dummy_psmx_t));
- psmx->c.instance_name = dds_string_dup("dummy_psmx");
- psmx->c.instance_id = instance_id;
+ dds_psmx_t* psmx = dds_alloc(sizeof(dds_psmx_t));
+ memset(psmx, 0, sizeof(dds_psmx_t));
+ psmx->instance_name = dds_string_dup("dummy_psmx");
+ psmx->instance_id = instance_id;
- psmx->c.ops.type_qos_supported = dummy_psmx_type_qos_supported;
- psmx->c.ops.create_topic = dummy_psmx_create_topic;
- psmx->c.ops.delete_topic = dummy_psmx_delete_topic;
- psmx->c.ops.deinit = dummy_psmx_deinit;
- psmx->c.ops.get_node_id = dummy_psmx_get_node_id;
- psmx->c.ops.supported_features = dummy_supported_features;
- dds_psmx_init_generic(&psmx->c);
+ psmx->ops.type_qos_supported = dummy_psmx_type_qos_supported;
+ psmx->ops.create_topic = dummy_psmx_create_topic;
+ psmx->ops.delete_topic = dummy_psmx_delete_topic;
+ psmx->ops.deinit = dummy_psmx_deinit;
+ psmx->ops.get_node_id = dummy_psmx_get_node_id;
+ psmx->ops.supported_features = dummy_supported_features;
+ dds_psmx_init_generic(psmx);
g_mockstats.config = ddsrt_strdup(config);
- psmx->mockstats_get_ptr = dummy_mockstats_get_ptr;
- *psmx_out = (dds_psmx_t*)psmx;
+ *psmx_out = psmx;
return DDS_RETCODE_OK;
}
diff --git a/src/core/ddsc/tests/psmx_dummy_public.h b/src/core/ddsc/tests/psmx_dummy_public.h
index d19cff7cd6..3037900726 100644
--- a/src/core/ddsc/tests/psmx_dummy_public.h
+++ b/src/core/ddsc/tests/psmx_dummy_public.h
@@ -17,8 +17,8 @@ extern "C" {
#endif
typedef struct dynamic_array_s{
- uint32_t _maximum;
- uint32_t _length;
+ size_t _maximum;
+ size_t _length;
void* _buffer;
}dynamic_array_t;
@@ -44,18 +44,23 @@ typedef struct dummy_mockstats_s{
int cnt_on_data_available;
// Exposed internals
+ bool supports_shared_memory;
char* config;
dynamic_array_t topics;
dynamic_array_t endpoints;
-}dummy_mockstats_t;
+ dds_loaned_sample_t loan;
+ dds_psmx_metadata_t loan_metadata;
-typedef struct dummy_psmx {
- dds_psmx_t c;
- dummy_mockstats_t* (*mockstats_get_ptr)();
-}dummy_psmx_t;
+ dds_psmx_topic_t* create_endpoint_rcv_topic;
+ dds_psmx_endpoint_t* delete_endpoint_rcv_endpt;
+ dds_psmx_endpoint_t* request_loan_rcv_endpt;
+ dds_psmx_endpoint_t* write_rcv_endpt;
+ dds_loaned_sample_t* write_rcv_loan;
+}dummy_mockstats_t;
-DDS_EXPORT void dummy_topics_alloc(dummy_mockstats_t* mockstats, uint32_t topics_capacity);
-DDS_EXPORT void dummy_endpoints_alloc(dummy_mockstats_t* mockstats, uint32_t endpoints_capacity);
+DDS_EXPORT dummy_mockstats_t* dummy_mockstats_get_ptr(void);
+DDS_EXPORT void dummy_topics_alloc(dummy_mockstats_t* mockstats, size_t topics_capacity);
+DDS_EXPORT void dummy_endpoints_alloc(dummy_mockstats_t* mockstats, size_t endpoints_capacity);
#if defined (__cplusplus)
}
diff --git a/src/core/ddsc/tests/psmxif.c b/src/core/ddsc/tests/psmxif.c
index dc0280d8d7..f5c98ff9e0 100644
--- a/src/core/ddsc/tests/psmxif.c
+++ b/src/core/ddsc/tests/psmxif.c
@@ -37,90 +37,12 @@
static void free_strings(uint32_t len, char** strings)
{
- if (len != 0 && strings != NULL) {
- for (uint32_t i = 0; i < len; i++) {
- dds_free(strings[i]);
- }
- }
- dds_free(strings);
-}
-
-/**
- * @brief Create a participant object, providing a configuration to choose the psmx interface.
- *
- * @param[in] int_dom the domain id
- * @param[in] cdds_psmx_name the name of the psmx interface to use
- * @param[in] locator an array of 16 bytes, NULL if not used
- * @return dds_entity_t the participant
- */
-static char* create_config(dds_domainid_t int_dom, const char* cdds_psmx_name, const uint8_t* locator)
-{
- char *configstr;
- char locator_str[74];
- if ( locator == NULL ) {
- locator_str[0] = 0;
- } else {
- const uint8_t *l = locator;
- snprintf(
- locator_str,
- sizeof(locator_str),
- "LOCATOR=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x;",
- l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8], l[9], l[10], l[11], l[12], l[13], l[14], l[15]
- );
- }
- ddsrt_asprintf (&configstr, "\
-${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}\
-\
- spdp\
- \
- \
- \
-\
-\
- ${CYCLONEDDS_PID}\
- 0\
-\
-\
- cdds.log.%d\
-\
-",
- cdds_psmx_name,
- cdds_psmx_name,
- locator_str,
- locator ? (int) locator[0] : -1, // This prevents plugins from forwarding across the "network".
- (int) int_dom // log file name
- );
- char *xconfigstr = ddsrt_expand_envvars (configstr, int_dom);
- ddsrt_free (configstr);
- return xconfigstr;
-}
-
-static bool endpoint_has_psmx_enabled (dds_entity_t rd_or_wr)
-{
- dds_return_t rc;
- struct dds_entity *x;
- bool psmx_enabled = false;
- rc = dds_entity_pin (rd_or_wr, &x);
- CU_ASSERT_FATAL (rc == DDS_RETCODE_OK);
- switch (dds_entity_kind (x))
- {
- case DDS_KIND_READER: {
- struct dds_reader const * const rd = (struct dds_reader *) x;
- psmx_enabled = (rd->m_endpoint.psmx_endpoints.length > 0);
- break;
- }
- case DDS_KIND_WRITER: {
- struct dds_writer const * const wr = (struct dds_writer *) x;
- psmx_enabled = (wr->m_endpoint.psmx_endpoints.length > 0);
- break;
- }
- default: {
- CU_ASSERT_FATAL (dds_entity_kind (x) == DDS_KIND_READER || dds_entity_kind (x) == DDS_KIND_WRITER);
- break;
+ if (len != 0 && strings != NULL) {
+ for (uint32_t i = 0; i < len; i++) {
+ dds_free(strings[i]);
}
}
- dds_entity_unpin (x);
- return psmx_enabled;
+ dds_free(strings);
}
/** @brief Convert a set of stats to a string.
@@ -173,6 +95,29 @@ static int dummy_mockstats_tostring(const dummy_mockstats_t* dmock, char* str_ou
);
}
+static dds_entity_t create_participant(dds_domainid_t domainId)
+{
+ char configstr[] = "\
+${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}\
+\
+spdp\
+\
+ \
+\
+\
+\
+cdds.log.0\
+\
+";
+ char* configstr_in = ddsrt_expand_envvars (configstr, domainId);
+ const dds_entity_t domain = dds_create_domain(domainId, configstr_in);
+ ddsrt_free(configstr_in);
+ CU_ASSERT_FATAL(domain > 0);
+ const dds_entity_t participant = dds_create_participant(domainId, NULL, NULL);
+ CU_ASSERT_FATAL(participant > 0);
+ return participant;
+}
+
/// @brief Check that creating a domain with more than one psmx interface fails.
/// @methodology
/// - Create a config string with two psmx interfaces.
@@ -182,18 +127,15 @@ static int dummy_mockstats_tostring(const dummy_mockstats_t* dmock, char* str_ou
CU_Test(ddsc_psmxif, config_multiple_psmx)
{
dds_domainid_t domainId = 0;
- const char* cdds_psmx_name1 = "dummy";
- const char* cdds_psmx_name2 = "iox";
char* configstr_in = NULL;
{
- char *configstr;
- ddsrt_asprintf (&configstr, "\
+ char configstr[] = "\
${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}\
\
spdp\
\
- \
- \
+ \
+ \
\
\
\
@@ -201,59 +143,89 @@ CU_Test(ddsc_psmxif, config_multiple_psmx)
0\
\
\
- cdds.log.%d\
+ cdds.log.0\
\
- ",
- cdds_psmx_name1,
- cdds_psmx_name1,
- -1, // This prevents plugins from forwarding across the "network".
- cdds_psmx_name2,
- cdds_psmx_name2,
- -1, // This prevents plugins from forwarding across the "network".
- (int) domainId // log file name
- );
- char *xconfigstr = ddsrt_expand_envvars(configstr, domainId);
- ddsrt_free(configstr);
- configstr_in = xconfigstr;
+ ";
+ configstr_in = ddsrt_expand_envvars(configstr, domainId);
}
const dds_entity_t domain = dds_create_domain (domainId, configstr_in);
CU_ASSERT_FATAL(domain <= 0);
}
-/// @brief Check that shared memory can be enabled (when supported) and the used locator can be set.
+static void assert_psmx_instance_name(dds_entity_t endpt, const char* name_expected)
+{
+ dds_qos_t* qos = dds_create_qos();
+ dds_get_qos(endpt, qos);
+ uint32_t strs_len = 0;
+ char** strs = NULL;
+ CU_ASSERT_FATAL(dds_qget_psmx_instances(qos, &strs_len, &strs));
+ CU_ASSERT_FATAL(strs_len == 1 && strcmp(strs[0], name_expected) == 0);
+ free_strings(strs_len, strs);
+ dds_delete_qos(qos);
+}
+
+/// @brief Check that the instance_name is as provided from dummy_create_psmx().
+/// @methodology
+/// - Create domain with a config containing the name for the psmx instance.
+/// - Create readers and writers.
+/// - Using the QoS interface, for each endpoint check that the instance_name is correct.
+///
+CU_Test(ddsc_psmxif, instance_name)
+{
+ const dds_domainid_t domainId = 0;
+ dds_entity_t participant = create_participant(domainId);
+ dds_entity_t domain = dds_get_parent(participant);
+ dummy_mockstats_t* dmock = dummy_mockstats_get_ptr();
+
+ dds_entity_t writer1 = 0, reader1 = 0, writer2 = 0, reader2 = 0;
+
+ char topicname[100];
+ dummy_topics_alloc(dmock, 2);
+ dummy_endpoints_alloc(dmock, 4);
+
+ create_unique_topic_name("shared_memory", topicname, sizeof(topicname));
+ dds_entity_t topic1 = dds_create_topic(participant, &SC_Model_desc, topicname, NULL, NULL);
+ CU_ASSERT_FATAL(topic1 > 0);
+ create_unique_topic_name("shared_memory", topicname, sizeof(topicname));
+ dds_entity_t topic2 = dds_create_topic(participant, &PsmxType1_desc, topicname, NULL, NULL);
+ CU_ASSERT_FATAL(topic2 > 0);
+
+ writer1 = dds_create_writer(participant, topic1, NULL, NULL);
+ CU_ASSERT_FATAL(writer1 > 0);
+ assert_psmx_instance_name(writer1, "dummy_psmx");
+ reader1 = dds_create_reader(participant, topic1, NULL, NULL);
+ CU_ASSERT_FATAL(reader1 > 0);
+ assert_psmx_instance_name(reader1, "dummy_psmx");
+ writer2 = dds_create_writer(participant, topic2, NULL, NULL);
+ CU_ASSERT_FATAL(writer2 > 0);
+ assert_psmx_instance_name(writer2, "dummy_psmx");
+ reader2 = dds_create_reader(participant, topic2, NULL, NULL);
+ CU_ASSERT_FATAL(reader2 > 0);
+ assert_psmx_instance_name(reader2, "dummy_psmx");
+ dds_delete(domain);
+}
+
+/// @brief Check that shared memory availability and entity and loan pointers are correctly propagated through the psmx interface.
/// @methodology
/// - Check that the data types I'm planning to use are actually suitable for use with shared memory.
/// - Expectation: They are memcopy-safe.
///
-/// - Create a configuration with a psmx interface and specify the locator.
+/// - Create a configuration with a psmx interface.
/// - Create a domain using this configuration.
-/// - Check the locator used by the psmx instance.
-/// - Expectation: The locator is the same as specified in the config for the domain.
-/// - Query whether shared memory is supported.
/// - Assert that there is exactly one psmx instance.
-/// - Assert that the psmx instance has a nonempty instance_name.
+/// - Decide whether shared memory is supported (communicated to the dummy psmx).
/// - Create some entities
-/// - Check if shared memory is enabled.
-/// - Expectation: Shared memory is enabled iff the psmx interface supports it (use queried value).
-/// - Delete the domain
-/// - Check the function call counts of the dummy psmx.
-/// - Expectation: The counts match expectations. In particular, create counts must match their delete counterpart.
-///
-/// - Create a configuration with a psmx interface capable of shared memory and don't specify a locator.
-/// - Create a domain using this configuration.
-/// - Query whether shared memory is supported.
-/// - Assert that there is exactly one psmx instance.
-/// - Assert that the psmx instance has a nonempty instance_name.
-/// - Create some entities
-/// - Check if shared memory is enabled.
-/// - Expectation: Shared memory is enabled iff the psmx interface supports it (use queried value).
+/// - Assert that the psmx_topic created during dummy_psmx_create_topic, is propagated to dummy_psmx_create_endpoint().
+/// - Assert that the psmx_endpoint created during dummy_psmx_create_endpoint(), is propagated to dummy_psmx_request_loan(), dummy_psmx_write(), dummy_psmx_delete_endpoint().
+/// - Assert that the loan created during dummy_psmx_request_loan(), is propagated to dummy_psmx_write().
+/// - Check if shared memory is available.
+/// - Expectation: Shared memory is available iff the psmx interface supports it (check for the false and the true case).
/// - Delete the domain
/// - Check the function call counts of the dummy psmx.
/// - Expectation: The counts match expectations. In particular, create counts must match their delete counterpart.
///
CU_Test(ddsc_psmxif, shared_memory)
{
- dummy_mockstats_t* dmock = NULL;
char strbuf[512];
const size_t strbuf_size = sizeof(strbuf);
{
@@ -265,155 +237,103 @@ CU_Test(ddsc_psmxif, shared_memory)
CU_ASSERT_FATAL((props & DDS_DATA_TYPE_IS_MEMCPY_SAFE) == DDS_DATA_TYPE_IS_MEMCPY_SAFE);
}
- const dds_domainid_t domainId = 0;
- bool supports_shared_memory_expected = true;
- dds_psmx_endpoint_t* psmx_endpt_expected = NULL;
- dds_psmx_topic_t* psmx_topic_expected = NULL;
- bool specify_locator[] = {true, false};
- uint8_t locator_in[16];
- memset(locator_in, 0x0, sizeof(locator_in)); // Avoid warning 'uninitialized value'.
- ((uint64_t*)locator_in)[0] = (uint64_t)0x4a4d203df6996395;
- ((uint64_t*)locator_in)[1] = (uint64_t)0xe1412fbecc2de4b6;
-
- int N = sizeof(specify_locator) / sizeof(specify_locator[0]);
- for (int i = 0; i < N; ++i)
- {
- const uint8_t* locator = specify_locator[i] ? locator_in : NULL;
- char* configstr_in = create_config(domainId, "dummy", locator);
- const dds_entity_t domain = dds_create_domain(domainId, configstr_in);
- CU_ASSERT_FATAL(domain > 0);
- const dds_entity_t participant = dds_create_participant(domainId, NULL, NULL);
- CU_ASSERT_FATAL(participant > 0);
+ for (size_t i = 0; i < 2; ++i) {
+ const dds_domainid_t domainId = 0;
+ dds_entity_t participant = create_participant(domainId);
+ dds_entity_t domain = dds_get_parent(participant);
+ dummy_mockstats_t* dmock = dummy_mockstats_get_ptr();
+ CU_ASSERT_FATAL(dmock->cnt_create_psmx == 1); // Confirm the dummy psmx has been loaded.
{
- // Query whether shared memory is supported.
- dds_domain* dom = NULL;
- {
- dds_entity* x = NULL;
- dds_return_t rc = dds_entity_pin(domain, &x);
- CU_ASSERT_FATAL(rc == DDS_RETCODE_OK && dds_entity_kind(x) == DDS_KIND_DOMAIN);
- dom = (dds_domain*)x;
- }
- assert(dom->psmx_instances.length >= 1);
- struct dummy_psmx* dpsmx = (struct dummy_psmx*)dom->psmx_instances.instances[0];
- dmock = dpsmx->mockstats_get_ptr();
- CU_ASSERT_FATAL(dmock->cnt_create_psmx == 1); // Confirm the dummy psmx has been loaded.
- dds_entity_unpin(&dom->m_entity);
+ // Assert that there is exactly one psmx instance.
+ dds_entity* x = NULL;
+ CU_ASSERT_FATAL(dds_entity_pin(domain, &x) == DDS_RETCODE_OK && dds_entity_kind(x) == DDS_KIND_DOMAIN);
+ CU_ASSERT_FATAL(((dds_domain*)x)->psmx_instances.length == 1);
+ dds_entity_unpin(x);
}
+
+ bool supports_shared_memory_expected = (bool)i;
+ dmock->supports_shared_memory = supports_shared_memory_expected;
+
+ dds_psmx_topic_t* psmx_topic_expected = NULL;
+ dds_psmx_endpoint_t* psmx_endpt_expected = NULL;
+ dds_psmx_endpoint_t* delete_endpoint_expected[4];
+ memset(delete_endpoint_expected, 0x0, sizeof(delete_endpoint_expected));
+ size_t delete_endpoint_idx = 0;
+ const size_t endpt_cnt = sizeof(delete_endpoint_expected) / sizeof(delete_endpoint_expected[0]);
+
// Check that the config string passed to `dds_create_domain()` has been correctly forwarded to the dummy psmx.
- CU_ASSERT_FATAL(strstr(configstr_in, dmock->config) != NULL); // dmock->config is a substring of the original xml.
- ddsrt_free(configstr_in);
+ char dmock_config_expected[] = "LOCATOR=4a4d203df6996395e1412fbecc2de4b6;SERVICE_NAME=service_psmx_dummy;KEYED_TOPICS=true;";
+ CU_ASSERT_FATAL(strcmp(dmock->config, dmock_config_expected) == 0);
+ void* sample = NULL;
dds_entity_t writer1 = 0, reader1 = 0, writer2 = 0, reader2 = 0;
- {
- char topicname[100];
- dummy_topics_alloc(dmock, 2);
- dummy_endpoints_alloc(dmock, 4);
-
- create_unique_topic_name("shared_memory", topicname, sizeof(topicname));
- psmx_topic_expected = (dds_psmx_topic_t*)dmock->topics._buffer + dmock->topics._length;
- dds_entity_t topic1 = dds_create_topic(participant, &SC_Model_desc, topicname, NULL, NULL);
- CU_ASSERT_FATAL(topic1 > 0);
- {
- dds_entity* x = NULL;
- dds_return_t rc = dds_entity_pin(topic1, &x);
- CU_ASSERT_FATAL(rc == DDS_RETCODE_OK && dds_entity_kind(x) == DDS_KIND_TOPIC);
- struct dds_psmx_topics_set* topics_set = &((dds_topic*)x)->m_ktopic->psmx_topics;
- CU_ASSERT_FATAL(topics_set->length == 1 && topics_set->topics[0] == psmx_topic_expected);
- dds_entity_unpin(x);
- }
-
- psmx_endpt_expected = (dds_psmx_endpoint_t*)dmock->endpoints._buffer + dmock->endpoints._length;
- writer1 = dds_create_writer(participant, topic1, NULL, NULL);
- CU_ASSERT_FATAL(writer1 > 0);
- {
- dds_entity* x = NULL;
- dds_return_t rc = dds_entity_pin(writer1, &x);
- CU_ASSERT_FATAL(rc == DDS_RETCODE_OK && dds_entity_kind(x) == DDS_KIND_WRITER);
- struct dds_psmx_endpoints_set* endpt_set = &((dds_writer*)x)->m_endpoint.psmx_endpoints;
- CU_ASSERT_FATAL(endpt_set->length == 1 && endpt_set->endpoints[0] == psmx_endpt_expected);
- dds_entity_unpin(x);
- }
-
- psmx_endpt_expected = (dds_psmx_endpoint_t*)dmock->endpoints._buffer + dmock->endpoints._length;
- reader1 = dds_create_reader(participant, topic1, NULL, NULL);
- CU_ASSERT_FATAL(reader1 > 0);
- {
- // Check the dummy psmx instance_name.
- dds_qos_t* qos = dds_create_qos();
- dds_get_qos(reader1, qos);
- uint32_t strs_len = 0;
- char** strs = NULL;
- CU_ASSERT_FATAL(dds_qget_psmx_instances(qos, &strs_len, &strs));
- CU_ASSERT_FATAL(strs_len == 1 && strcmp(strs[0], "dummy_psmx") == 0);
- free_strings(strs_len, strs);
- dds_delete_qos(qos);
- }
- {
- dds_entity* x = NULL;
- dds_return_t rc = dds_entity_pin(reader1, &x);
- CU_ASSERT_FATAL(rc == DDS_RETCODE_OK && dds_entity_kind(x) == DDS_KIND_READER);
- struct dds_psmx_endpoints_set* endpt_set = &((dds_reader*)x)->m_endpoint.psmx_endpoints;
- CU_ASSERT_FATAL(endpt_set->length == 1 && endpt_set->endpoints[0] == psmx_endpt_expected);
- dds_entity_unpin(x);
- }
-
- create_unique_topic_name("shared_memory", topicname, sizeof(topicname));
- psmx_topic_expected = (dds_psmx_topic_t*)dmock->topics._buffer + dmock->topics._length;
- dds_entity_t topic2 = dds_create_topic(participant, &PsmxType1_desc, topicname, NULL, NULL);
- CU_ASSERT_FATAL(topic2 > 0);
- {
- dds_entity* x = NULL;
- dds_return_t rc = dds_entity_pin(topic2, &x);
- CU_ASSERT_FATAL(rc == DDS_RETCODE_OK && dds_entity_kind(x) == DDS_KIND_TOPIC);
- struct dds_psmx_topics_set* topics_set = &((dds_topic*)x)->m_ktopic->psmx_topics;
- CU_ASSERT_FATAL(topics_set->length == 1 && topics_set->topics[0] == psmx_topic_expected);
- dds_entity_unpin(x);
- }
-
- psmx_endpt_expected = (dds_psmx_endpoint_t*)dmock->endpoints._buffer + dmock->endpoints._length;
- writer2 = dds_create_writer(participant, topic2, NULL, NULL);
- CU_ASSERT_FATAL(writer2 > 0);
- {
- dds_entity* x = NULL;
- dds_return_t rc = dds_entity_pin(writer2, &x);
- CU_ASSERT_FATAL(rc == DDS_RETCODE_OK && dds_entity_kind(x) == DDS_KIND_WRITER);
- struct dds_psmx_endpoints_set* endpt_set = &((dds_writer*)x)->m_endpoint.psmx_endpoints;
- CU_ASSERT_FATAL(endpt_set->length == 1 && endpt_set->endpoints[0] == psmx_endpt_expected);
- dds_entity_unpin(x);
- }
-
- psmx_endpt_expected = (dds_psmx_endpoint_t*)dmock->endpoints._buffer + dmock->endpoints._length;
- reader2 = dds_create_reader(participant, topic2, NULL, NULL);
- CU_ASSERT_FATAL(reader2 > 0);
- {
- dds_entity* x = NULL;
- dds_return_t rc = dds_entity_pin(reader2, &x);
- CU_ASSERT_FATAL(rc == DDS_RETCODE_OK && dds_entity_kind(x) == DDS_KIND_READER);
- struct dds_psmx_endpoints_set* endpt_set = &((dds_reader*)x)->m_endpoint.psmx_endpoints;
- CU_ASSERT_FATAL(endpt_set->length == 1 && endpt_set->endpoints[0] == psmx_endpt_expected);
- dds_entity_unpin(x);
- }
- }
- {
- // Check that shared memory is enabled when it should, and not enabled when it shouldn't.
- bool psmx_enabled;
- psmx_enabled = endpoint_has_psmx_enabled(writer1);
- CU_ASSERT_FATAL(psmx_enabled);
- CU_ASSERT_FATAL(dds_is_shared_memory_available(writer1) == supports_shared_memory_expected);
-
- psmx_enabled = endpoint_has_psmx_enabled(reader1);
- CU_ASSERT_FATAL(psmx_enabled);
- CU_ASSERT_FATAL(dds_is_shared_memory_available(reader1) == supports_shared_memory_expected);
-
- psmx_enabled = endpoint_has_psmx_enabled(writer2);
- CU_ASSERT_FATAL(psmx_enabled);
- CU_ASSERT_FATAL(dds_is_shared_memory_available(writer2) == supports_shared_memory_expected);
-
- psmx_enabled = endpoint_has_psmx_enabled(reader2);
- CU_ASSERT_FATAL(psmx_enabled);
- CU_ASSERT_FATAL(dds_is_shared_memory_available(reader2) == supports_shared_memory_expected);
- }
+ char topicname[100];
+ dummy_topics_alloc(dmock, 2);
+ dummy_endpoints_alloc(dmock, endpt_cnt);
+
+ create_unique_topic_name("shared_memory", topicname, sizeof(topicname));
+ psmx_topic_expected = (dds_psmx_topic_t*)dmock->topics._buffer + dmock->topics._length;
+ dds_entity_t topic1 = dds_create_topic(participant, &SC_Model_desc, topicname, NULL, NULL);
+ CU_ASSERT_FATAL(topic1 > 0);
+
+ psmx_endpt_expected = (dds_psmx_endpoint_t*)dmock->endpoints._buffer + dmock->endpoints._length;
+ delete_endpoint_expected[delete_endpoint_idx++] = psmx_endpt_expected;
+ writer1 = dds_create_writer(participant, topic1, NULL, NULL);
+ CU_ASSERT_FATAL(writer1 > 0);
+ CU_ASSERT_FATAL(dmock->create_endpoint_rcv_topic == psmx_topic_expected);
+ CU_ASSERT_FATAL(dds_request_loan(writer1, &sample) == DDS_RETCODE_OK);
+ CU_ASSERT_FATAL(dmock->request_loan_rcv_endpt == psmx_endpt_expected);
+ dmock->write_rcv_loan = NULL;
+ CU_ASSERT_FATAL(dds_write(writer1, sample) == DDS_RETCODE_OK);
+ CU_ASSERT_FATAL(dmock->write_rcv_endpt == psmx_endpt_expected);
+ CU_ASSERT_FATAL(dmock->write_rcv_loan == &dmock->loan);
+
+ psmx_endpt_expected = (dds_psmx_endpoint_t*)dmock->endpoints._buffer + dmock->endpoints._length;
+ delete_endpoint_expected[delete_endpoint_idx++] = psmx_endpt_expected;
+ reader1 = dds_create_reader(participant, topic1, NULL, NULL);
+ CU_ASSERT_FATAL(reader1 > 0);
+ CU_ASSERT_FATAL(dmock->create_endpoint_rcv_topic == psmx_topic_expected);
+
+ create_unique_topic_name("shared_memory", topicname, sizeof(topicname));
+ psmx_topic_expected = (dds_psmx_topic_t*)dmock->topics._buffer + dmock->topics._length;
+ dds_entity_t topic2 = dds_create_topic(participant, &PsmxType1_desc, topicname, NULL, NULL);
+ CU_ASSERT_FATAL(topic2 > 0);
+
+ psmx_endpt_expected = (dds_psmx_endpoint_t*)dmock->endpoints._buffer + dmock->endpoints._length;
+ delete_endpoint_expected[delete_endpoint_idx++] = psmx_endpt_expected;
+ writer2 = dds_create_writer(participant, topic2, NULL, NULL);
+ CU_ASSERT_FATAL(writer2 > 0);
+ CU_ASSERT_FATAL(dmock->create_endpoint_rcv_topic == psmx_topic_expected);
+ CU_ASSERT_FATAL(dds_request_loan(writer2, &sample) == DDS_RETCODE_OK);
+ CU_ASSERT_FATAL(dmock->request_loan_rcv_endpt == psmx_endpt_expected);
+ dmock->write_rcv_loan = NULL;
+ CU_ASSERT_FATAL(dds_write(writer2, sample) == DDS_RETCODE_OK);
+ CU_ASSERT_FATAL(dmock->write_rcv_endpt == psmx_endpt_expected);
+ CU_ASSERT_FATAL(dmock->write_rcv_loan == &dmock->loan);
+
+ psmx_endpt_expected = (dds_psmx_endpoint_t*)dmock->endpoints._buffer + dmock->endpoints._length;
+ delete_endpoint_expected[delete_endpoint_idx++] = psmx_endpt_expected;
+ reader2 = dds_create_reader(participant, topic2, NULL, NULL);
+ CU_ASSERT_FATAL(reader2 > 0);
+ CU_ASSERT_FATAL(dmock->create_endpoint_rcv_topic == psmx_topic_expected);
+
+ // Check that shared memory is available when it should, and not available when it shouldn't.
+ CU_ASSERT_FATAL(dds_is_shared_memory_available(writer1) == supports_shared_memory_expected);
+ CU_ASSERT_FATAL(dds_is_shared_memory_available(reader1) == supports_shared_memory_expected);
+ CU_ASSERT_FATAL(dds_is_shared_memory_available(writer2) == supports_shared_memory_expected);
+ CU_ASSERT_FATAL(dds_is_shared_memory_available(reader2) == supports_shared_memory_expected);
+
+ // Check that psmx_endpoint pointers originally from `dummy_psmx_create_endpoint()`, end up in `dummy_psmx_delete_endpoint()`.
+ CU_ASSERT_FATAL(delete_endpoint_idx == endpt_cnt);
+ dds_delete(reader2);
+ CU_ASSERT_FATAL(dmock->delete_endpoint_rcv_endpt == delete_endpoint_expected[--delete_endpoint_idx]);
+ dds_delete(writer2);
+ CU_ASSERT_FATAL(dmock->delete_endpoint_rcv_endpt == delete_endpoint_expected[--delete_endpoint_idx]);
+ dds_delete(reader1);
+ CU_ASSERT_FATAL(dmock->delete_endpoint_rcv_endpt == delete_endpoint_expected[--delete_endpoint_idx]);
+ dds_delete(writer1);
+ CU_ASSERT_FATAL(dmock->delete_endpoint_rcv_endpt == delete_endpoint_expected[--delete_endpoint_idx]);
dds_delete(domain);
// Check number of calls against expected counts.
@@ -432,10 +352,9 @@ CU_Test(ddsc_psmxif, shared_memory)
CU_ASSERT_FATAL(dmock->cnt_create_endpoint == 4);
CU_ASSERT_FATAL(dmock->cnt_delete_endpoint == 4);
- CU_ASSERT_FATAL(dmock->cnt_request_loan == 0);
- CU_ASSERT_FATAL(dmock->cnt_write == 0);
+ CU_ASSERT_FATAL(dmock->cnt_request_loan == 2);
+ CU_ASSERT_FATAL(dmock->cnt_write == 2);
CU_ASSERT_FATAL(dmock->cnt_take == 0);
CU_ASSERT_FATAL(dmock->cnt_on_data_available == 2);
- dmock = NULL;
}
-}
\ No newline at end of file
+}