|
22 | 22 | #include "PubSubParticipant.hpp"
|
23 | 23 |
|
24 | 24 | #include <fastrtps/rtps/common/Locator.h>
|
| 25 | +#include <fastdds/rtps/transport/shared_mem/SharedMemTransportDescriptor.h> |
25 | 26 | #include <fastrtps/utils/IPFinder.h>
|
26 | 27 |
|
27 | 28 | using namespace eprosima::fastrtps;
|
@@ -165,6 +166,107 @@ TEST_P(NetworkConfig, sub_unique_network_flows)
|
165 | 166 | }
|
166 | 167 | }
|
167 | 168 |
|
| 169 | +// Regression test for redmine issue #22519 to check that readers using unique network flows cannot share locators |
| 170 | +// with other readers. The mentioned issue referred to the case where TCP + builtin transports are present. |
| 171 | +// In that concrete scenario, the problem was that while the TCP (and UDP) transports rightly were able |
| 172 | +// to create a receiver in the dedicated "unique flow" port, shared memory failed for that same port as the other |
| 173 | +// process (or participant) is already listening on it. However this was not being handled properly, so once matched, |
| 174 | +// the publisher attempts to send data to the wrongfully announced shared memory locator. |
| 175 | +// Note that the underlying problem is that, when creating unique network flows, all transports are requested to |
| 176 | +// create a receiver for a specific port all together. This is, the creation of unique flow receivers is only |
| 177 | +// considered to fail when it fails for all transports, instead of decoupling them and keep trying for alternative |
| 178 | +// ports when the creation of a specific transport receiver fails. |
| 179 | +// In this test a similar scenario is presented, but using instead UDP and shared memory transports. In the first |
| 180 | +// participant, only shared memory is used (which should create a SHM receiver in the first "unique" port attempted). |
| 181 | +// In the second participant both UDP and shared memory are used (which should create a UDP receiver in the first |
| 182 | +// "unique" port attempted, and a shared memory receiver in the second "unique" port attempted, as the first one is |
| 183 | +// already being used by the first participant). As a result, the listening shared memory locators of each data |
| 184 | +// reader should be different. Finally, a third data reader is created in the second participant, and it is verified |
| 185 | +// that its listening locators are different from those of the other reader created in the same participant, as well as |
| 186 | +// from the (SHM) one of the reader created in the first participant. |
| 187 | +TEST_P(NetworkConfig, sub_unique_network_flows_multiple_locators) |
| 188 | +{ |
| 189 | + // Enable unique network flows feature |
| 190 | + PropertyPolicy properties; |
| 191 | + properties.properties().emplace_back("fastdds.unique_network_flows", ""); |
| 192 | + |
| 193 | + // First participant |
| 194 | + PubSubParticipant<HelloWorldPubSubType> participant(0, 1, 0, 0); |
| 195 | + |
| 196 | + participant.sub_topic_name(TEST_TOPIC_NAME).sub_property_policy(properties); |
| 197 | + |
| 198 | + std::shared_ptr<eprosima::fastdds::rtps::SharedMemTransportDescriptor> shm_descriptor = |
| 199 | + std::make_shared<eprosima::fastdds::rtps::SharedMemTransportDescriptor>(); |
| 200 | + // Use only SHM transport in the first participant |
| 201 | + participant.disable_builtin_transport().add_user_transport_to_pparams(shm_descriptor); |
| 202 | + |
| 203 | + ASSERT_TRUE(participant.init_participant()); |
| 204 | + ASSERT_TRUE(participant.init_subscriber(0)); |
| 205 | + |
| 206 | + LocatorList_t locators; |
| 207 | + |
| 208 | + participant.get_native_reader(0).get_listening_locators(locators); |
| 209 | + ASSERT_EQ(locators.size(), 1u); |
| 210 | + ASSERT_EQ((*locators.begin()).kind, LOCATOR_KIND_SHM); |
| 211 | + |
| 212 | + // Second participant |
| 213 | + PubSubParticipant<HelloWorldPubSubType> participant2(0, 2, 0, 0); |
| 214 | + |
| 215 | + participant2.sub_topic_name(TEST_TOPIC_NAME).sub_property_policy(properties); |
| 216 | + |
| 217 | + // Use both UDP and SHM in the second participant |
| 218 | + if (!use_udpv4) |
| 219 | + { |
| 220 | + participant2.disable_builtin_transport().add_user_transport_to_pparams(descriptor_). |
| 221 | + add_user_transport_to_pparams(shm_descriptor); |
| 222 | + } |
| 223 | + |
| 224 | + ASSERT_TRUE(participant2.init_participant()); |
| 225 | + ASSERT_TRUE(participant2.init_subscriber(0)); |
| 226 | + |
| 227 | + LocatorList_t locators2_1; |
| 228 | + |
| 229 | + participant2.get_native_reader(0).get_listening_locators(locators2_1); |
| 230 | + ASSERT_TRUE(locators2_1.size() >= 2u); // There should be at least two locators, one for SHM and N(#interfaces) for UDP |
| 231 | + |
| 232 | + // Check SHM locator is different from the one in the first participant |
| 233 | + for (const Locator_t& loc : locators2_1) |
| 234 | + { |
| 235 | + if (LOCATOR_KIND_SHM == loc.kind) |
| 236 | + { |
| 237 | + // Ports should be different (expected second and first values of the unique network flows port range) |
| 238 | + ASSERT_FALSE(loc == *locators.begin()); |
| 239 | + } |
| 240 | + } |
| 241 | + |
| 242 | + // Now create a second reader in the second participant |
| 243 | + ASSERT_TRUE(participant2.init_subscriber(1)); |
| 244 | + |
| 245 | + LocatorList_t locators2_2; |
| 246 | + |
| 247 | + participant2.get_native_reader(1).get_listening_locators(locators2_2); |
| 248 | + ASSERT_TRUE(locators2_2.size() >= 2u); // There should be at least two locators, one for SHM and N(#interfaces) for UDP |
| 249 | + |
| 250 | + // Check SHM locator is different from the one in the first participant |
| 251 | + for (const Locator_t& loc : locators2_2) |
| 252 | + { |
| 253 | + if (LOCATOR_KIND_SHM == loc.kind) |
| 254 | + { |
| 255 | + // Ports should be different (expected third and first values of the unique network flows port range) |
| 256 | + ASSERT_FALSE(loc == *locators.begin()); |
| 257 | + } |
| 258 | + } |
| 259 | + |
| 260 | + // Now check no locators are shared between the two readers in the second participant |
| 261 | + for (const Locator_t& loc_1 : locators2_1) |
| 262 | + { |
| 263 | + for (const Locator_t& loc_2 : locators2_2) |
| 264 | + { |
| 265 | + ASSERT_FALSE(loc_1 == loc_2); |
| 266 | + } |
| 267 | + } |
| 268 | +} |
| 269 | + |
168 | 270 | //Verify that outLocatorList is used to select the desired output channel
|
169 | 271 | TEST_P(NetworkConfig, PubSubOutLocatorSelection)
|
170 | 272 | {
|
|
0 commit comments