Add a test for cross-topic use of instance handles

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2020-04-01 10:50:55 +02:00 committed by eboasson
parent 17da91409a
commit 9239547d34
3 changed files with 160 additions and 1 deletions

View file

@ -15,6 +15,7 @@ idlc_generate(RoundTrip RoundTrip.idl)
idlc_generate(Space Space.idl) idlc_generate(Space Space.idl)
idlc_generate(TypesArrayKey TypesArrayKey.idl) idlc_generate(TypesArrayKey TypesArrayKey.idl)
idlc_generate(WriteTypes WriteTypes.idl) idlc_generate(WriteTypes WriteTypes.idl)
idlc_generate(InstanceHandleTypes InstanceHandleTypes.idl)
set(ddsc_test_sources set(ddsc_test_sources
"basic.c" "basic.c"
@ -28,6 +29,7 @@ set(ddsc_test_sources
"entity_status.c" "entity_status.c"
"err.c" "err.c"
"instance_get_key.c" "instance_get_key.c"
"instance_handle.c"
"listener.c" "listener.c"
"liveliness.c" "liveliness.c"
"loan.c" "loan.c"
@ -73,7 +75,7 @@ target_include_directories(
"$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src/include/>" "$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src/include/>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsc/src>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsc/src>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsi/include>") "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsi/include>")
target_link_libraries(cunit_ddsc PRIVATE RoundTrip Space TypesArrayKey WriteTypes ddsc) target_link_libraries(cunit_ddsc PRIVATE RoundTrip Space TypesArrayKey WriteTypes InstanceHandleTypes ddsc)
# Setup environment for config-tests # Setup environment for config-tests
get_test_property(CUnit_ddsc_config_simple_udp ENVIRONMENT CUnit_ddsc_config_simple_udp_env) get_test_property(CUnit_ddsc_config_simple_udp ENVIRONMENT CUnit_ddsc_config_simple_udp_env)

View file

@ -0,0 +1,23 @@
/*
* Copyright(c) 2020 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
module InstanceHandleTypes {
struct A {
unsigned long k; //@Key
unsigned long v;
};
#pragma keylist A k
struct C {
octet k[4]; //@Key
unsigned long v;
};
#pragma keylist C k
};

View file

@ -0,0 +1,134 @@
/*
* Copyright(c) 2020 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include <assert.h>
#include <limits.h>
#include "dds/dds.h"
#include "dds/ddsrt/bswap.h"
#include "test_common.h"
#include "InstanceHandleTypes.h"
static dds_entity_t dp, tp[3], rd[3], wr[3];
static void instance_handle_init (void)
{
char topicname[100];
dds_qos_t *qos;
dp = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
CU_ASSERT_FATAL (dp > 0);
/* not strictly necessary to explicitly set KEEP_LAST (it is the default), nor to make
it reliable (it is only used inside a process without any limits that might cause it
to drop samples) */
qos = dds_create_qos ();
CU_ASSERT_FATAL (qos != NULL);
dds_qset_history (qos, DDS_HISTORY_KEEP_LAST, 1);
dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_INFINITY);
create_unique_topic_name ("instance_handle", topicname, sizeof (topicname));
tp[0] = dds_create_topic (dp, &InstanceHandleTypes_A_desc, topicname, NULL, NULL);
CU_ASSERT_FATAL (tp[0] > 0);
create_unique_topic_name ("instance_handle", topicname, sizeof (topicname));
tp[1] = dds_create_topic (dp, &InstanceHandleTypes_A_desc, topicname, NULL, NULL);
CU_ASSERT_FATAL (tp[1] > 0);
create_unique_topic_name ("instance_handle", topicname, sizeof (topicname));
tp[2] = dds_create_topic (dp, &InstanceHandleTypes_C_desc, topicname, NULL, NULL);
CU_ASSERT_FATAL (tp[2] > 0);
dds_delete_qos (qos);
for (size_t i = 0; i < 3; i++)
{
rd[i] = dds_create_reader (dp, tp[i], NULL, NULL);
CU_ASSERT_FATAL (rd[i] > 0);
wr[i] = dds_create_writer (dp, tp[i], NULL, NULL);
CU_ASSERT_FATAL (wr[i] > 0);
}
}
static void instance_handle_fini (void)
{
dds_return_t rc;
rc = dds_delete (dp);
CU_ASSERT_FATAL (rc == 0);
}
CU_Test (ddsc_instance_handle, a, .init = instance_handle_init, .fini = instance_handle_fini)
{
/* By design, Cyclone maintains a global map of (topic class, X, key value) to instance handle,
where the "topic class" is the implementation of the topic (e.g., "default" or "builtin"),
"X" is dependent on the topic class but by design is a fixed constant for the default one,
and key value, again by design, is taken as the serialised representation of the key value.
The point behind this model is that it allows one to use an instance handle obtained on
one reader and use it to read the matching instance in another reader. So that bit of
behaviour needs to be checked.
I'm not sure whether the "serialised" part should be included in the test, I don't think
that's something that should be guaranteed in the API. However, it is worth verifying that
it doesn't go off and do something weird. */
InstanceHandleTypes_A a, b;
InstanceHandleTypes_C c;
dds_return_t rc;
for (uint32_t i = 1; i <= 5; i++)
{
a.k = i;
a.v = i;
b.k = i;
b.v = 2 * a.k;
const uint32_t a_k_be = ddsrt_toBE4u (a.k);
memcpy (c.k, &a_k_be, sizeof (c.k));
c.v = 3 * a.k;
rc = dds_write (wr[0], &a);
CU_ASSERT_FATAL (rc == 0);
rc = dds_write (wr[1], &b);
CU_ASSERT_FATAL (rc == 0);
rc = dds_write (wr[2], &c);
CU_ASSERT_FATAL (rc == 0);
}
for (uint32_t i = 1; i <= 5; i++)
{
dds_sample_info_t siA, siB, siC;
void *rawA = &a, *rawB = &b, *rawC = &c;
/* take one sample from A; no guarantee about the order in which the data is returned */
rc = dds_take (rd[0], &rawA, &siA, 1, 1);
CU_ASSERT_FATAL (rc == 1);
CU_ASSERT_FATAL (siA.valid_data);
CU_ASSERT_FATAL (1 <= a.k && a.k <= 5 && a.v == a.k);
/* take one sample from B using the instance handle just returned */
rc = dds_take_instance (rd[1], &rawB, &siB, 1, 1, siA.instance_handle);
CU_ASSERT_FATAL (rc == 1);
CU_ASSERT_FATAL (siB.valid_data);
CU_ASSERT_FATAL (siB.instance_handle == siA.instance_handle);
CU_ASSERT_FATAL (b.k == a.k && b.v == 2 * a.k);
/* take one sample from C using the instance handle just returned, this should work
even though C uses an array of octets as key */
rc = dds_take_instance (rd[2], &rawC, &siC, 1, 1, siA.instance_handle);
CU_ASSERT_FATAL (rc == 1);
CU_ASSERT_FATAL (siC.valid_data);
CU_ASSERT_FATAL (siC.instance_handle == siA.instance_handle);
const uint32_t a_k_be = ddsrt_toBE4u (a.k);
CU_ASSERT_FATAL (memcmp (c.k, &a_k_be, sizeof (c.k)) == 0 && c.v == 3 * a.k);
}
/* there should be no data left */
for (size_t i = 0; i < 3; i++)
{
dds_sample_info_t si;
void *raw = NULL;
rc = dds_take (rd[0], &raw, &si, 1, 1);
CU_ASSERT_FATAL (rc == 0);
}
}