Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add psmx test to check whether shared memory can be enabled and the l… #1939

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions src/core/ddsc/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ set(ddsc_test_sources
"nwpart.c"
"participant.c"
"pp_lease_dur.c"
"psmxif.c"
"publisher.c"
"qos.c"
"qosmatch.c"
Expand Down Expand Up @@ -157,6 +158,43 @@ if(ENABLE_QOS_PROVIDER)
"qos_provider.c")
endif()

# PSMX dummy implementation for interface testing
set(
psmx_dummy_sources
"psmx_dummy_impl.c"
"psmx_dummy_impl.h"
)
if(BUILD_SHARED_LIBS)
add_library(psmx_dummy SHARED ${psmx_dummy_sources})
else()
add_library(psmx_dummy OBJECT ${psmx_dummy_sources})
set_property(GLOBAL APPEND PROPERTY cdds_plugin_list psmx_dummy)
set_property(GLOBAL PROPERTY psmx_dummy_symbols dummy_create_psmx)
endif()
generate_export_header(psmx_dummy BASE_NAME PSMX_DUMMY EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/include/dds/psmx_dummy/export.h")
target_include_directories(
psmx_dummy PRIVATE
"$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src/ddsrt/include>"
"$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src/core/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/src/core/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../../ddsrt/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsc/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsi/include>"
)
if(BUILD_SHARED_LIBS)
target_link_libraries(psmx_dummy PRIVATE ddsc)
else()
install(
TARGETS psmx_dummy
EXPORT "${PROJECT_NAME}"
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
endif()


add_cunit_executable(cunit_ddsc ${ddsc_test_sources})
target_include_directories(
cunit_ddsc PRIVATE
Expand All @@ -181,6 +219,7 @@ target_link_libraries(cunit_ddsc PRIVATE
CdrStreamSkipDefault
CdrStreamDataTypeInfo
PsmxDataModels
psmx_dummy
DynamicData
Array100
CdrStreamKeySize
Expand Down Expand Up @@ -243,7 +282,6 @@ target_include_directories(

target_link_libraries(oneliner PRIVATE RoundTrip Space ddsc)


# PSMX implementation with Cyclone as transport, for testing
if (BUILD_SHARED_LIBS)
idlc_generate(TARGET psmx_cdds_data FILES psmx_cdds_data.idl)
Expand All @@ -258,10 +296,6 @@ if (BUILD_SHARED_LIBS)
target_link_libraries(psmx_cdds PRIVATE ddsc psmx_cdds_data)

generate_export_header(psmx_cdds BASE_NAME PSMX_CDDS EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/include/dds/psmx_cdds/export.h")

install(TARGETS psmx_cdds
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
endif()

# If Iceoryx is available, then also run all PSMX tests using Iceoryx. Colcon complicates
Expand Down
49 changes: 33 additions & 16 deletions src/core/ddsc/tests/psmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
203 changes: 203 additions & 0 deletions src/core/ddsc/tests/psmx_dummy_impl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@

#include <string.h>
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/string.h"
#include "dds/ddsrt/strtol.h"
#include "dds/ddsi/ddsi_locator.h"
#include "dds/ddsc/dds_psmx.h"
#include "psmx_dummy_public.h"
#include "psmx_dummy_impl.h"

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, 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 void dummy_psmx_loan_free(dds_loaned_sample_t* loan)
{
(void)loan;
}

static dds_loaned_sample_t* dummy_psmx_ep_request_loan(dds_psmx_endpoint_t* psmx_endpoint, uint32_t size_requested)
{
(void)size_requested;
++g_mockstats.cnt_request_loan;
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)
{
(void)psmx_endpoint;
(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;
}

static dds_loaned_sample_t* dummy_psmx_ep_take(dds_psmx_endpoint_t* psmx_endpoint)
{
(void)psmx_endpoint;
// Details yet to be implemented
++g_mockstats.cnt_take;
return NULL;
}

static dds_return_t dummy_psmx_ep_on_data_available(dds_psmx_endpoint_t* psmx_endpoint, dds_entity_t reader)
{
(void)psmx_endpoint;
(void)reader;
// Details yet to be implemented
++g_mockstats.cnt_on_data_available;
return DDS_RETCODE_OK;
}

static dds_psmx_endpoint_t* dummy_psmx_create_endpoint(
dds_psmx_topic_t* psmx_topic,
const struct dds_qos* qos,
dds_psmx_endpoint_type_t endpoint_type
) {
(void)qos;
dds_psmx_endpoint_t* endp = (dds_psmx_endpoint_t*)g_mockstats.endpoints._buffer + g_mockstats.endpoints._length++;
memset(endp, 0, sizeof(dds_psmx_endpoint_t));
endp->ops.request_loan = dummy_psmx_ep_request_loan;
endp->ops.write = dummy_psmx_ep_write;
endp->ops.take = dummy_psmx_ep_take;
endp->ops.on_data_available = dummy_psmx_ep_on_data_available;

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)
{
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;
}

static bool dummy_psmx_type_qos_supported(
dds_psmx_t* psmx,
dds_psmx_endpoint_type_t forwhat,
dds_data_type_properties_t data_type_props,
const struct dds_qos* qos
) {
(void)psmx;
(void)forwhat;
(void)data_type_props;
(void)qos;
++g_mockstats.cnt_type_qos_supported;
return true;
}

static dds_psmx_topic_t* dummy_psmx_create_topic(
dds_psmx_t* psmx,
const char* topic_name,
const char* type_name,
dds_data_type_properties_t data_type_props
) {
(void)data_type_props;
assert(g_mockstats.topics._length < g_mockstats.topics._maximum);
dds_psmx_topic_t* topic = (dds_psmx_topic_t*)g_mockstats.topics._buffer + g_mockstats.topics._length++;
memset(topic, 0, sizeof(dds_psmx_topic_t));
topic->ops.create_endpoint = dummy_psmx_create_endpoint;
topic->ops.delete_endpoint = dummy_psmx_delete_endpoint;
topic->psmx_instance = psmx;
topic->topic_name = ddsrt_strdup(topic_name);
topic->type_name = ddsrt_strdup(type_name);
dds_add_psmx_topic_to_list(topic, &psmx->psmx_topics);
++g_mockstats.cnt_create_topic;
return topic;
}

static dds_return_t dummy_psmx_delete_topic(dds_psmx_topic_t* psmx_topic)
{
dds_psmx_topic_cleanup_generic(psmx_topic);
memset(psmx_topic, 0x0, sizeof(dds_psmx_topic_t));
++g_mockstats.cnt_delete_topic;
return DDS_RETCODE_OK;
}

static dds_return_t dummy_psmx_deinit(dds_psmx_t* psmx)
{
dds_psmx_cleanup_generic(psmx);
dds_free(psmx);
++g_mockstats.cnt_deinit;
ddsrt_free(g_mockstats.config);
ddsrt_free(g_mockstats.topics._buffer);
ddsrt_free(g_mockstats.endpoints._buffer);
return DDS_RETCODE_OK;
}

static dds_psmx_node_identifier_t dummy_psmx_get_node_id(const dds_psmx_t* psmx)
{
(void)psmx;
dds_psmx_node_identifier_t node_id;
memset(&node_id, 0, sizeof(dds_psmx_node_identifier_t));
++g_mockstats.cnt_get_node_id;
return node_id;
}

static dds_psmx_features_t dummy_supported_features(const dds_psmx_t* psmx)
{
(void)psmx;
++g_mockstats.cnt_supported_features;
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)
{
assert(psmx_out);
memset(&g_mockstats, 0, sizeof(dummy_mockstats_t));
g_mockstats.cnt_create_psmx = 1;

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->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_out = psmx;
return DDS_RETCODE_OK;
}
26 changes: 26 additions & 0 deletions src/core/ddsc/tests/psmx_dummy_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright(c) 2023 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause

#ifndef PSMX_DUMMY_IMPL_H
#define PSMX_DUMMY_IMPL_H

#include "dds/psmx_dummy/export.h"

#if defined (__cplusplus)
extern "C" {
#endif

PSMX_DUMMY_EXPORT dds_return_t dummy_create_psmx(dds_psmx_t **psmx, dds_psmx_instance_id_t instance_id, const char *config);

#if defined (__cplusplus)
}
#endif

#endif /* PSMX_DUMMY_IMPL_H */
Loading
Loading