Skip to content

Commit 10553bb

Browse files
authored
Add missing tests of 'Yaml validator v2' (#189)
* [#20274] Added tests for 'YamlReader.ipp' & 'YamlReader_generic.cpp' Signed-off-by: danipiza <dpizarrogallego@gmail.com> * [#20274] Added tests for 'YamlValidator.cpp' Signed-off-by: danipiza <dpizarrogallego@gmail.com> * [#20274] Added tests for 'YamlReader_participants' & 'XmlHandlerConfiguration' Signed-off-by: danipiza <dpizarrogallego@gmail.com> * [#20274] Applied uncrustify Signed-off-by: danipiza <dpizarrogallego@gmail.com> --------- Signed-off-by: danipiza <dpizarrogallego@gmail.com>
1 parent d07191f commit 10553bb

7 files changed

Lines changed: 576 additions & 4 deletions

File tree

ddspipe_yaml/test/unittest/yaml_reader/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
###################
1818

1919
add_subdirectory(scalar)
20+
add_subdirectory(participants)
2021
add_subdirectory(forwarding_routes)
2122
add_subdirectory(log_configuration)
2223
add_subdirectory(monitoring)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Copyright 2026 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
#################################
16+
# Yaml Reader Participants Test #
17+
#################################
18+
19+
set(TEST_NAME YamlReaderParticipantsTest)
20+
21+
set(TEST_SOURCES
22+
${PROJECT_SOURCE_DIR}/src/cpp/YamlReader_generic.cpp
23+
${PROJECT_SOURCE_DIR}/src/cpp/YamlReader_participants.cpp
24+
${PROJECT_SOURCE_DIR}/src/cpp/YamlReader_types.cpp
25+
YamlReaderParticipantsTest.cpp
26+
)
27+
28+
set(TEST_LIST
29+
read_participant_and_echo_configuration
30+
read_simple_participant_optional_fields
31+
read_discovery_server_participant_across_versions
32+
read_initial_peers_and_xml_participant_configuration
33+
xml_handler_configuration_invalid_file_message
34+
)
35+
36+
set(TEST_EXTRA_LIBRARIES
37+
yaml-cpp
38+
fastcdr
39+
fastdds
40+
cpp_utils
41+
ddspipe_core
42+
ddspipe_participants
43+
)
44+
45+
add_unittest_executable(
46+
"${TEST_NAME}"
47+
"${TEST_SOURCES}"
48+
"${TEST_LIST}"
49+
"${TEST_EXTRA_LIBRARIES}")
Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
// Copyright 2026 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <sstream>
16+
17+
#include <cpp_utils/testing/gtest_aux.hpp>
18+
#include <gtest/gtest.h>
19+
20+
#include <ddspipe_core/types/dds/CustomTransport.hpp>
21+
#include <ddspipe_core/types/dds/GuidPrefix.hpp>
22+
23+
#include <ddspipe_participants/configuration/DiscoveryServerParticipantConfiguration.hpp>
24+
#include <ddspipe_participants/configuration/EchoParticipantConfiguration.hpp>
25+
#include <ddspipe_participants/configuration/InitialPeersParticipantConfiguration.hpp>
26+
#include <ddspipe_participants/configuration/ParticipantConfiguration.hpp>
27+
#include <ddspipe_participants/configuration/SimpleParticipantConfiguration.hpp>
28+
#include <ddspipe_participants/configuration/XmlParticipantConfiguration.hpp>
29+
#include <ddspipe_participants/types/address/Address.hpp>
30+
#include <ddspipe_participants/types/security/tls/TlsConfiguration.hpp>
31+
#include <ddspipe_participants/xml/XmlHandlerConfiguration.hpp>
32+
33+
#include <ddspipe_yaml/YamlReader.hpp>
34+
#include <ddspipe_yaml/testing/generate_yaml.hpp>
35+
#include <ddspipe_yaml/yaml_configuration_tags.hpp>
36+
37+
using namespace eprosima;
38+
using namespace eprosima::ddspipe;
39+
using namespace eprosima::ddspipe::yaml;
40+
using namespace eprosima::ddspipe::yaml::testing;
41+
42+
namespace test {
43+
44+
participants::types::Address make_udp_address(
45+
const std::string& ip,
46+
uint16_t port)
47+
{
48+
return participants::types::Address(
49+
ip,
50+
port,
51+
port,
52+
participants::types::IpVersion::v4,
53+
participants::types::TransportProtocol::udp);
54+
}
55+
56+
participants::types::Address make_tcp_address(
57+
const std::string& ip,
58+
uint16_t port)
59+
{
60+
return participants::types::Address(
61+
ip,
62+
port,
63+
port,
64+
participants::types::IpVersion::v4,
65+
participants::types::TransportProtocol::tcp);
66+
}
67+
68+
Yaml address_sequence(
69+
const std::vector<participants::types::Address>& addresses)
70+
{
71+
Yaml yml;
72+
for (const auto& address : addresses)
73+
{
74+
Yaml address_yml;
75+
address_to_yaml(address_yml, address);
76+
yml.push_back(address_yml);
77+
}
78+
79+
return yml;
80+
}
81+
82+
Yaml tls_yaml()
83+
{
84+
Yaml yml;
85+
yml[TLS_PRIVATE_KEY_TAG] = "server.key";
86+
yml[TLS_CERT_TAG] = "server.crt";
87+
yml[TLS_DHPARAMS_TAG] = "dh.pem";
88+
yml[TLS_PEER_VERIFICATION_TAG] = false;
89+
return yml;
90+
}
91+
92+
} // namespace test
93+
94+
/**
95+
* Test that the base participant configuration reads the required id and that
96+
* the echo participant reads all its optional boolean flags.
97+
*/
98+
TEST(YamlReaderParticipantsTest, read_participant_and_echo_configuration)
99+
{
100+
Yaml participant_yml;
101+
participantid_to_yaml(participant_yml, core::types::ParticipantId("base_participant"));
102+
103+
auto participant = YamlReader::get<participants::ParticipantConfiguration>(participant_yml, LATEST);
104+
ASSERT_EQ(participant.id, core::types::ParticipantId("base_participant"));
105+
106+
Yaml echo_yml = participant_yml;
107+
echo_yml[ECHO_DATA_TAG] = true;
108+
echo_yml[ECHO_DISCOVERY_TAG] = false;
109+
echo_yml[ECHO_VERBOSE_TAG] = true;
110+
111+
auto echo = YamlReader::get<participants::EchoParticipantConfiguration>(echo_yml, LATEST);
112+
ASSERT_EQ(echo.id, core::types::ParticipantId("base_participant"));
113+
ASSERT_TRUE(echo.echo_data);
114+
ASSERT_FALSE(echo.echo_discovery);
115+
ASSERT_TRUE(echo.verbose);
116+
}
117+
118+
/**
119+
* Test that the simple participant configuration reads all optional fields:
120+
* domain, whitelist, easy mode ip, transport, ignore flags, and participant QoS.
121+
*/
122+
TEST(YamlReaderParticipantsTest, read_simple_participant_optional_fields)
123+
{
124+
Yaml yml;
125+
participantid_to_yaml(yml, core::types::ParticipantId("simple_participant"));
126+
domain_to_yaml(yml, core::types::DomainId(static_cast<core::types::DomainIdType>(42)));
127+
yml[WHITELIST_INTERFACES_TAG].push_back("127.0.0.1");
128+
yml[WHITELIST_INTERFACES_TAG].push_back("lo");
129+
easy_mode_ip_to_yaml(yml, "192.168.1.50");
130+
yml[TRANSPORT_DESCRIPTORS_TRANSPORT_TAG] = TRANSPORT_DESCRIPTORS_UDP_TAG;
131+
yml[IGNORE_PARTICIPANT_FLAGS_TAG] = IGNORE_PARTICIPANT_FLAGS_SAME_PROCESS_TAG;
132+
yml[PARTICIPANT_QOS_TAG][QOS_RELIABLE_TAG] = true;
133+
134+
auto participant = YamlReader::get<participants::SimpleParticipantConfiguration>(yml, LATEST);
135+
136+
ASSERT_EQ(participant.id, core::types::ParticipantId("simple_participant"));
137+
ASSERT_EQ(participant.domain.domain_id, 42);
138+
ASSERT_EQ(participant.whitelist.size(), 2u);
139+
ASSERT_TRUE(participant.whitelist.find("127.0.0.1") != participant.whitelist.end());
140+
ASSERT_TRUE(participant.whitelist.find("lo") != participant.whitelist.end());
141+
ASSERT_EQ(participant.easy_mode_ip, "192.168.1.50");
142+
ASSERT_EQ(participant.transport, core::types::TransportDescriptors::udp_only);
143+
ASSERT_EQ(participant.ignore_participant_flags, core::types::IgnoreParticipantFlags::filter_same_process);
144+
ASSERT_TRUE(participant.topic_qos.is_reliable());
145+
}
146+
147+
/**
148+
* Test discovery server participant parsing across the versions that differ in
149+
* guid-prefix handling, and check optional addresses and TLS configuration.
150+
*/
151+
TEST(YamlReaderParticipantsTest, read_discovery_server_participant_across_versions)
152+
{
153+
const auto listening = test::make_udp_address("127.0.0.1", 7400);
154+
const auto connection = test::make_tcp_address("192.168.1.20", 7410);
155+
const core::types::GuidPrefix guid_prefix("01.0f.00.00.00.00.00.00.00.00.ab.cd");
156+
157+
// V_1_0 reads the guid directly from the participant root.
158+
{
159+
Yaml yml;
160+
participantid_to_yaml(yml, core::types::ParticipantId("ds_v1"));
161+
guid_prefix_to_yaml(yml, guid_prefix);
162+
163+
auto participant = YamlReader::get<participants::DiscoveryServerParticipantConfiguration>(yml, V_1_0);
164+
ASSERT_EQ(participant.id, core::types::ParticipantId("ds_v1"));
165+
ASSERT_EQ(participant.discovery_server_guid_prefix, guid_prefix);
166+
}
167+
168+
// V_4_0 uses the dedicated discovery-server-guid tag and parses the optional branches.
169+
{
170+
Yaml yml;
171+
participantid_to_yaml(yml, core::types::ParticipantId("ds_v4"));
172+
yml[LISTENING_ADDRESSES_TAG] = test::address_sequence({listening});
173+
yml[CONNECTION_ADDRESSES_TAG] = test::address_sequence({connection});
174+
yml[TLS_TAG] = test::tls_yaml();
175+
discovery_server_guid_prefix_to_yaml(yml, guid_prefix);
176+
177+
auto participant = YamlReader::get<participants::DiscoveryServerParticipantConfiguration>(yml, V_4_0);
178+
ASSERT_EQ(participant.id, core::types::ParticipantId("ds_v4"));
179+
ASSERT_EQ(participant.listening_addresses.size(), 1u);
180+
ASSERT_EQ(participant.connection_addresses.size(), 1u);
181+
ASSERT_EQ(*participant.listening_addresses.begin(), listening);
182+
ASSERT_EQ(*participant.connection_addresses.begin(), connection);
183+
ASSERT_EQ(participant.discovery_server_guid_prefix, guid_prefix);
184+
ASSERT_EQ(participant.tls_configuration.kind, participants::types::TlsKind::both);
185+
ASSERT_FALSE(participant.tls_configuration.verify_peer);
186+
ASSERT_EQ(participant.tls_configuration.private_key_file, "server.key");
187+
}
188+
189+
// V_5_0 keeps the guid optional.
190+
{
191+
Yaml yml;
192+
participantid_to_yaml(yml, core::types::ParticipantId("ds_v5"));
193+
194+
auto participant = YamlReader::get<participants::DiscoveryServerParticipantConfiguration>(yml, V_5_0);
195+
ASSERT_EQ(participant.id, core::types::ParticipantId("ds_v5"));
196+
ASSERT_EQ(participant.discovery_server_guid_prefix, core::types::GuidPrefix());
197+
}
198+
}
199+
200+
/**
201+
* Test that the initial peers and xml participant configurations read their
202+
* participant-specific optional fields correctly.
203+
*/
204+
TEST(YamlReaderParticipantsTest, read_initial_peers_and_xml_participant_configuration)
205+
{
206+
const auto listening = test::make_udp_address("10.0.0.1", 11811);
207+
const auto connection = test::make_tcp_address("10.0.0.2", 11812);
208+
209+
{
210+
Yaml yml;
211+
participantid_to_yaml(yml, core::types::ParticipantId("initial_peers"));
212+
yml[LISTENING_ADDRESSES_TAG] = test::address_sequence({listening});
213+
yml[CONNECTION_ADDRESSES_TAG] = test::address_sequence({connection});
214+
yml[TLS_TAG] = test::tls_yaml();
215+
repeater_to_yaml(yml, true);
216+
217+
auto participant = YamlReader::get<participants::InitialPeersParticipantConfiguration>(yml, LATEST);
218+
ASSERT_EQ(participant.id, core::types::ParticipantId("initial_peers"));
219+
ASSERT_TRUE(participant.is_repeater);
220+
ASSERT_EQ(participant.listening_addresses.size(), 1u);
221+
ASSERT_EQ(participant.connection_addresses.size(), 1u);
222+
ASSERT_EQ(*participant.listening_addresses.begin(), listening);
223+
ASSERT_EQ(*participant.connection_addresses.begin(), connection);
224+
ASSERT_EQ(participant.tls_configuration.kind, participants::types::TlsKind::both);
225+
}
226+
227+
{
228+
Yaml yml;
229+
participantid_to_yaml(yml, core::types::ParticipantId("xml_participant"));
230+
yml[XML_PARTICIPANT_PROFILE_TAG] = "participant_profile";
231+
repeater_to_yaml(yml, true);
232+
233+
auto participant = YamlReader::get<participants::XmlParticipantConfiguration>(yml, LATEST);
234+
ASSERT_EQ(participant.id, core::types::ParticipantId("xml_participant"));
235+
ASSERT_TRUE(participant.is_repeater);
236+
ASSERT_TRUE(participant.participant_profile.is_set());
237+
ASSERT_EQ(participant.participant_profile.get_reference(), "participant_profile");
238+
}
239+
}
240+
241+
/**
242+
* Test that the XML handler configuration reports the updated missing-file
243+
* validation message when a configured XML file is not accessible.
244+
*/
245+
TEST(YamlReaderParticipantsTest, xml_handler_configuration_invalid_file_message)
246+
{
247+
participants::XmlHandlerConfiguration conf;
248+
conf.files.insert("./missing_xml_handler_configuration_test_file.xml");
249+
250+
utils::Formatter error_msg;
251+
std::ostringstream ss;
252+
253+
ASSERT_FALSE(conf.is_valid(error_msg));
254+
ss << error_msg;
255+
ASSERT_EQ(
256+
ss.str(),
257+
"File ./missing_xml_handler_configuration_test_file.xml does not exist or does not have read access. ");
258+
}
259+
260+
int main(
261+
int argc,
262+
char** argv)
263+
{
264+
::testing::InitGoogleTest(&argc, argv);
265+
return RUN_ALL_TESTS();
266+
}

ddspipe_yaml/test/unittest/yaml_reader/scalar/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ set(TEST_LIST
3232
get_scalar_string
3333
get_scalar_from_tag
3434
get_scalar_negative_cases
35+
get_positive_and_nonnegative_numbers_from_tag
36+
get_list_and_set_helpers
37+
get_timestamp
3538
)
3639

3740
set(TEST_EXTRA_LIBRARIES

0 commit comments

Comments
 (0)