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