diff --git a/src/cpp/StatisticsBackend.cpp b/src/cpp/StatisticsBackend.cpp index 190151190..a75e15d03 100644 --- a/src/cpp/StatisticsBackend.cpp +++ b/src/cpp/StatisticsBackend.cpp @@ -956,7 +956,10 @@ void StatisticsBackend::set_alias( { entity->alias = alias; std::vector domains = StatisticsBackend::get_entities(EntityKind::DOMAIN, entity_id); - StatisticsBackendData::get_instance()->database_->update_graph_on_updated_entity(domains[0], entity_id); + if(!domains.empty()) + { + StatisticsBackendData::get_instance()->database_->update_graph_on_updated_entity(domains[0], entity_id); + } } } diff --git a/test/dds/communication/Monitor.cpp b/test/dds/communication/Monitor.cpp index c2acf9d21..2fa28eeab 100644 --- a/test/dds/communication/Monitor.cpp +++ b/test/dds/communication/Monitor.cpp @@ -152,6 +152,9 @@ int main( int arg_count = 1; uint32_t seed = 7800; unsigned int num_participants = 2; + unsigned int num_hosts = 1; + unsigned int num_users = 1; + unsigned int num_processes = 2; unsigned int num_readers = 1; // Each participant creates a meta traffic endpoint unsigned int num_writers = num_participants + 1; @@ -266,11 +269,20 @@ int main( // and check that all entities are active try { - if (!StatisticsBackend::get_entities(EntityKind::HOST).empty() || - !StatisticsBackend::get_entities(EntityKind::USER).empty() || - !StatisticsBackend::get_entities(EntityKind::PROCESS).empty()) + if (StatisticsBackend::get_entities(EntityKind::HOST).size() != num_hosts || + StatisticsBackend::get_entities(EntityKind::HOST, monitor_id).size() != num_hosts) { - throw Error("Error: database contains unexpected entities"); + throw Error("Error: database contains unexpected HOST"); + } + else if (StatisticsBackend::get_entities(EntityKind::USER).size() != num_users || + StatisticsBackend::get_entities(EntityKind::USER, monitor_id).size() != num_users) + { + throw Error("Error: database contains unexpected USER"); + } + else if (StatisticsBackend::get_entities(EntityKind::PROCESS).size() != num_processes || + StatisticsBackend::get_entities(EntityKind::PROCESS, monitor_id).size() != num_processes) + { + throw Error("Error: database contains unexpected PROCESS"); } else if (StatisticsBackend::get_entities(EntityKind::DOMAIN).size() != 1 || StatisticsBackend::get_entities(EntityKind::DOMAIN).begin()->value() != monitor_id) @@ -327,6 +339,30 @@ int main( entity.value()) + " is inactive after discovering participants"); } } + for (auto entity : StatisticsBackend::get_entities(EntityKind::HOST, monitor_id)) + { + if (!StatisticsBackend::is_active(entity)) + { + throw Error("Error: HOST with id: " + std::to_string( + entity.value()) + " is inactive after discovering participants"); + } + } + for (auto entity : StatisticsBackend::get_entities(EntityKind::USER, monitor_id)) + { + if (!StatisticsBackend::is_active(entity)) + { + throw Error("Error: USER with id: " + std::to_string( + entity.value()) + " is inactive after discovering participants"); + } + } + for (auto entity : StatisticsBackend::get_entities(EntityKind::PROCESS, monitor_id)) + { + if (!StatisticsBackend::is_active(entity)) + { + throw Error("Error: PROCESS with id: " + std::to_string( + entity.value()) + " is inactive after discovering participants"); + } + } for (auto entity : StatisticsBackend::get_entities(EntityKind::DATAWRITER, monitor_id)) { if (!StatisticsBackend::is_active(entity)) @@ -366,11 +402,20 @@ int main( // and check that all entities except the monitor are inactive try { - if (!StatisticsBackend::get_entities(EntityKind::HOST).empty() || - !StatisticsBackend::get_entities(EntityKind::USER).empty() || - !StatisticsBackend::get_entities(EntityKind::PROCESS).empty()) + if (StatisticsBackend::get_entities(EntityKind::HOST).size() != num_hosts || + StatisticsBackend::get_entities(EntityKind::HOST, monitor_id).size() != num_hosts) { - throw Error("Error: database contains unexpected entities"); + throw Error("Error: database contains unexpected HOST"); + } + else if (StatisticsBackend::get_entities(EntityKind::USER).size() != num_users || + StatisticsBackend::get_entities(EntityKind::USER, monitor_id).size() != num_users) + { + throw Error("Error: database contains unexpected USER"); + } + else if (StatisticsBackend::get_entities(EntityKind::PROCESS).size() != num_processes || + StatisticsBackend::get_entities(EntityKind::PROCESS, monitor_id).size() != num_processes) + { + throw Error("Error: database contains unexpected PROCESS"); } else if (StatisticsBackend::get_entities(EntityKind::DOMAIN).size() != 1 || StatisticsBackend::get_entities(EntityKind::DOMAIN).begin()->value() != monitor_id) @@ -408,7 +453,7 @@ int main( if (!StatisticsBackend::is_active(entity)) { throw Error("Error: DOMAIN with id: " + std::to_string( - entity.value()) + " is inactive after undiscovering participants"); + entity.value()) + " is active after undiscovering participants"); } } for (auto entity : StatisticsBackend::get_entities(EntityKind::TOPIC, monitor_id)) @@ -427,6 +472,30 @@ int main( entity.value()) + " is active after undiscovering participants"); } } + for (auto entity : StatisticsBackend::get_entities(EntityKind::HOST, monitor_id)) + { + if (StatisticsBackend::is_active(entity)) + { + throw Error("Error: HOST with id: " + std::to_string( + entity.value()) + " is active after undiscovering participants"); + } + } + for (auto entity : StatisticsBackend::get_entities(EntityKind::USER, monitor_id)) + { + if (StatisticsBackend::is_active(entity)) + { + throw Error("Error: USER with id: " + std::to_string( + entity.value()) + " is active after undiscovering participants"); + } + } + for (auto entity : StatisticsBackend::get_entities(EntityKind::PROCESS, monitor_id)) + { + if (StatisticsBackend::is_active(entity)) + { + throw Error("Error: PROCESS with id: " + std::to_string( + entity.value()) + " is active after undiscovering participants"); + } + } for (auto entity : StatisticsBackend::get_entities(EntityKind::DATAWRITER, monitor_id)) { if (StatisticsBackend::is_active(entity)) @@ -468,11 +537,20 @@ int main( // and check that all entities are inactive try { - if (!StatisticsBackend::get_entities(EntityKind::HOST).empty() || - !StatisticsBackend::get_entities(EntityKind::USER).empty() || - !StatisticsBackend::get_entities(EntityKind::PROCESS).empty()) + if (StatisticsBackend::get_entities(EntityKind::HOST).size() != num_hosts || + StatisticsBackend::get_entities(EntityKind::HOST, monitor_id).size() != num_hosts) { - throw Error("Error: database contains unexpected entities"); + throw Error("Error: database contains unexpected HOST"); + } + else if (StatisticsBackend::get_entities(EntityKind::USER).size() != num_users || + StatisticsBackend::get_entities(EntityKind::USER, monitor_id).size() != num_users) + { + throw Error("Error: database contains unexpected USER"); + } + else if (StatisticsBackend::get_entities(EntityKind::PROCESS).size() != num_processes || + StatisticsBackend::get_entities(EntityKind::PROCESS, monitor_id).size() != num_processes) + { + throw Error("Error: database contains unexpected PROCESS"); } else if (StatisticsBackend::get_entities(EntityKind::DOMAIN).size() != 1 || StatisticsBackend::get_entities(EntityKind::DOMAIN).begin()->value() != monitor_id) @@ -529,6 +607,30 @@ int main( entity.value()) + " is active after stopping monitor"); } } + for (auto entity : StatisticsBackend::get_entities(EntityKind::HOST, monitor_id)) + { + if (StatisticsBackend::is_active(entity)) + { + throw Error("Error: HOST with id: " + std::to_string( + entity.value()) + " is active after stopping monitor"); + } + } + for (auto entity : StatisticsBackend::get_entities(EntityKind::USER, monitor_id)) + { + if (StatisticsBackend::is_active(entity)) + { + throw Error("Error: USER with id: " + std::to_string( + entity.value()) + " is active after stopping monitor"); + } + } + for (auto entity : StatisticsBackend::get_entities(EntityKind::PROCESS, monitor_id)) + { + if (StatisticsBackend::is_active(entity)) + { + throw Error("Error: PROCESS with id: " + std::to_string( + entity.value()) + " is active after stopping monitor"); + } + } for (auto entity : StatisticsBackend::get_entities(EntityKind::DATAWRITER, monitor_id)) { if (StatisticsBackend::is_active(entity)) diff --git a/test/unittest/Database/DatabaseLoadTests.cpp b/test/unittest/Database/DatabaseLoadTests.cpp index aeca7ad49..e051a3b06 100644 --- a/test/unittest/Database/DatabaseLoadTests.cpp +++ b/test/unittest/Database/DatabaseLoadTests.cpp @@ -129,8 +129,9 @@ TEST(database_load_tests, load_and_dump_complex_erased_database) // Check that the next_id_ is the expected EXPECT_EQ(db.next_id(), 27); - // Check that EntityId 13 (domain_1) does not exist in the database - EXPECT_THROW(db.get_entity(13), BadParameter); + // Check that EntityId 13 (domain_1) does not contain participants nor topics + EXPECT_TRUE(std::dynamic_pointer_cast(db.get_entity(13))->participants.empty()); + EXPECT_TRUE(std::dynamic_pointer_cast(db.get_entity(13))->topics.empty()); // Compare the dumps to ensure that the entities have been created with the same ids. ASSERT_EQ(dump, loadedDump); diff --git a/test/unittest/StatisticsParticipantListener/StatisticsParticipantListenerTests.cpp b/test/unittest/StatisticsParticipantListener/StatisticsParticipantListenerTests.cpp index 9c60fbd3f..3febae57e 100644 --- a/test/unittest/StatisticsParticipantListener/StatisticsParticipantListenerTests.cpp +++ b/test/unittest/StatisticsParticipantListener/StatisticsParticipantListenerTests.cpp @@ -99,6 +99,21 @@ class statistics_participant_listener_tests : public ::testing::Test std::string domain_name_; std::shared_ptr domain_; + // Entity Qos + Qos entity_qos; + + // Host entity + std::string host_name_; + std::shared_ptr host_; + + // User entity + std::string user_name_; + std::shared_ptr user_; + + // Process entity + std::string process_name_; + std::shared_ptr process_; + // Participant entity std::string participant_name_; Qos participant_qos_; @@ -154,6 +169,18 @@ class statistics_participant_listener_tests : public ::testing::Test domain_ = std::make_shared(domain_name_); domain_->id = 0; + // Host entity + host_name_ = "host_name"; + host_ = std::make_shared(host_name_); + + // User entity + user_name_ = "user_name"; + user_ = std::make_shared(user_name_, host_); + + // Process entity + process_name_ = "process_name"; + process_ = std::make_shared(process_name_, process_name_, user_); + // Participant entity participant_name_ = "participant_ name"; participant_prefix_str_ = "01.02.03.04.05.06.07.08.09.0a.0b.0c"; @@ -236,87 +263,108 @@ class statistics_participant_listener_tests : public ::testing::Test #if !defined(_WIN32) TEST_F(statistics_participant_listener_tests, new_participant_discovered) { - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); - // Precondition: The Participant does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) - .Times(AnyNumber()) - .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) - .WillRepeatedly(Return(std::pair(0, 10))); - EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) - .WillRepeatedly(Return(std::shared_ptr())); + // Precondition: The Participant does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) + .Times(AnyNumber()) + .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) + .WillRepeatedly(Return(std::pair(0, 10))); + EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) + .WillRepeatedly(Return(std::shared_ptr())); + + // Precondition: The Host does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::HOST, host_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The Metatrafic Topic does not exist - EXPECT_CALL(database, - get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(0))); + // Precondition: The User does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::USER, user_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The Metatrafic Endpoint does not exist - EXPECT_CALL(database, - get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + // Precondition: The Process does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::PROCESS, process_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: There are unicast locators in database - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:1")) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(1))))); - EXPECT_CALL(database, - get_entity(EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(metatraffic_unicast_locator)); + // Precondition: The Metatrafic Topic does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:3")) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()).WillRepeatedly(Return(default_unicast_locator)); + // Precondition: The Metatrafic Endpoint does not exist + EXPECT_CALL(database, + get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Precondition: There are not multicast locators in database - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:2")) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, - get_entity(EntityId(2))).Times(AnyNumber()).WillRepeatedly(Return(metatraffic_multicast_locator)); + // Precondition: There are unicast locators in database + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:1")) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(1))))); + EXPECT_CALL(database, + get_entity(EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(metatraffic_unicast_locator)); - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:4")) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(4))))); - EXPECT_CALL(database, - get_entity(EntityId(4))).Times(AnyNumber()).WillRepeatedly(Return(default_multicast_locator)); + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:3")) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()).WillRepeatedly(Return(default_unicast_locator)); - // Start building the discovered reader info - eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; - eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); + // Precondition: There are not multicast locators in database + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:2")) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, + get_entity(EntityId(2))).Times(AnyNumber()).WillRepeatedly(Return(metatraffic_multicast_locator)); - // Precondition: The discovered participant has the given GUID and name - data.m_guid = participant_guid_; - data.m_participantName = participant_name_; + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:4")) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(4))))); + EXPECT_CALL(database, + get_entity(EntityId(4))).Times(AnyNumber()).WillRepeatedly(Return(default_multicast_locator)); - // Precondition: The discovered participant has unicast and multicast locators associated - data.metatraffic_locators.unicast.push_back(1); - data.metatraffic_locators.multicast.push_back(2); - data.default_locators.unicast.push_back(3); - data.default_locators.multicast.push_back(4); + // Start building the discovered reader info + eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; + eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); + // Precondition: The discovered participant has the given GUID and name + data.m_guid = participant_guid_; + data.m_participantName = participant_name_; + + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_host, host_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_user, user_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_process, process_name_); + + // Precondition: The discovered participant has unicast and multicast locators associated + data.metatraffic_locators.unicast.push_back(1); + data.metatraffic_locators.multicast.push_back(2); + data.default_locators.unicast.push_back(3); + data.default_locators.multicast.push_back(4); + + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); - // Expectation: The Participant is added to the database. We do not care about the given ID - InsertEntityArgs insert_args([&]( + // Expectation: The Participant is added to the database. We do not care about the given ID + InsertEntityArgs insert_args([&]( std::shared_ptr entity) - { + { EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); EXPECT_EQ(entity->name, participant_name_); EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); @@ -324,220 +372,308 @@ TEST_F(statistics_participant_listener_tests, new_participant_discovered) participant_proxy_data_to_backend_qos(info.info)); return EntityId(10); - }); + }); + + // Expectation: The host is created and given ID 13 + InsertEntityArgs insert_args_host([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::HOST); + EXPECT_EQ(entity->name, host_name_); + EXPECT_EQ(entity->alias, host_name_); - // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID - InsertEntityArgs insert_topic_args([&]( + return EntityId(13); + }); + + // Expectation: The user is created and given ID 14 + InsertEntityArgs insert_args_user([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::USER); + EXPECT_EQ(entity->name, user_name_); + EXPECT_EQ(entity->alias, user_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->host, insert_args_host.entity_); + + return EntityId(14); + }); + + // Expectation: The process is created and given ID 15 + InsertEntityArgs insert_args_process([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PROCESS); + EXPECT_EQ(entity->name, process_name_); + EXPECT_EQ(entity->alias, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->pid, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->user, insert_args_user.entity_); + + return EntityId(15); + }); + + // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID + InsertEntityArgs insert_topic_args([&]( std::shared_ptr entity) - { + { EXPECT_EQ(entity->kind, EntityKind::TOPIC); EXPECT_EQ(entity->name, metatraffic_prefix + "TOPIC"); EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, metatraffic_prefix + "TYPE"); return EntityId(11); - }); + }); - // Expectation: The Metatraffic Endpoint is added to the database. We do not care about the given ID - InsertEntityArgs insert_datawriter_args([&]( + // Expectation: The Metatraffic Endpoint is added to the database. We do not care about the given ID + InsertEntityArgs insert_datawriter_args([&]( std::shared_ptr entity) - { + { EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); return EntityId(12); - }); + }); + + EXPECT_CALL(database, insert(_)).Times(6) + .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_host, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_user, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_process, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); - EXPECT_CALL(database, insert(_)).Times(3) - .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + // Expectation: The link method is called with appropriate arguments + EXPECT_CALL(database, link_participant_with_process(EntityId(10), EntityId(15))).Times(1); - // Expectation: The Participant is discovered - EXPECT_CALL( + // Expectation: Modify graph + EXPECT_CALL(database, update_participant_in_graph(EntityId(0),EntityId(13),EntityId(14),EntityId(15),EntityId(10))).Times(1).WillOnce(Return(true)); + + // Expectation: The Participant is discovered + EXPECT_CALL( *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - // Expectation: The metatraffic endpoint change it status - EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + // Expectation: The metatraffic endpoint change it status + EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(10),EntityId(11),EntityId(12))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(2); - // Expectation: The metatraffic endpoint is discovered - EXPECT_CALL( + // Expectation: The metatraffic endpoint is discovered + EXPECT_CALL( *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - // Expectation: The topic is discovered - EXPECT_CALL( + // Expectation: The topic is discovered + EXPECT_CALL( *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::TOPIC, eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - // Execution: Call the listener - info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; - participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + // Execution: Call the listener + info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; + participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); } TEST_F(statistics_participant_listener_tests, new_participant_discovered_not_first) { - // Participant_2 entity - std::string participant_2_name = "participant_ name"; - Qos participant_2_qos; - std::string participant_2_prefix_str = "01.02.03.04.05.06.07.08.09.0a.0b.1c"; - eprosima::fastrtps::rtps::GuidPrefix_t guid_2_prefix; - std::stringstream(participant_2_prefix_str) >> guid_2_prefix; - std::string participant_2_guid_str = participant_2_prefix_str + "|0.0.1.c1"; - eprosima::fastrtps::rtps::GUID_t participant_2_guid; - std::stringstream(participant_2_guid_str) >> participant_2_guid; - std::shared_ptr participant_2 = - std::make_shared(participant_2_name, participant_2_qos, participant_2_guid_str, - std::shared_ptr(), domain_); - - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); - - // Precondition: Participant_5 exists and has ID 5 - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(5)))); - EXPECT_CALL(database, get_entity(EntityId(5))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - EXPECT_CALL(database, get_entities(EntityKind::PARTICIPANT, EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, participant_))); - - // Precondition: The Metatrafic Topic exists and has ID 6 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(6))))); - EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) - .WillRepeatedly(Return(metatraffic_topic_)); - - // Precondition: The Participant_1 Metatrafic Endpoint exists and has ID 7 - EXPECT_CALL(database, - get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(7)))); - EXPECT_CALL(database, get_entity(EntityId(7))).Times(AnyNumber()) - .WillRepeatedly(Return(metatraffic_endpoint_)); - - // Precondition: The new Participant does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_2_guid_str)).Times(AnyNumber()) - .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) - .WillRepeatedly(Return(std::pair(0, 10))); - EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) - .WillRepeatedly(Return(std::shared_ptr())); - - // Precondition: The Metatrafic Endpoint does not exist - EXPECT_CALL(database, - get_entity_by_guid(EntityKind::DATAWRITER, participant_2_guid_str)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - - // Precondition: There are unicast locators in database - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:1")) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(1))))); - EXPECT_CALL(database, - get_entity(EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(metatraffic_unicast_locator)); - - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:3")) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()).WillRepeatedly(Return(default_unicast_locator)); - - // Precondition: There are not multicast locators in database - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:2")) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, - get_entity(EntityId(2))).Times(AnyNumber()).WillRepeatedly(Return(metatraffic_multicast_locator)); + // Participant_2 entity + std::string participant_2_name = "participant_ name"; + Qos participant_2_qos; + std::string participant_2_prefix_str = "01.02.03.04.05.06.07.08.09.0a.0b.1c"; + eprosima::fastrtps::rtps::GuidPrefix_t guid_2_prefix; + std::stringstream(participant_2_prefix_str) >> guid_2_prefix; + std::string participant_2_guid_str = participant_2_prefix_str + "|0.0.1.c1"; + eprosima::fastrtps::rtps::GUID_t participant_2_guid; + std::stringstream(participant_2_guid_str) >> participant_2_guid; + std::shared_ptr participant_2 = + std::make_shared(participant_2_name, participant_2_qos, participant_2_guid_str, + std::shared_ptr(), domain_); - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:4")) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(4))))); - EXPECT_CALL(database, - get_entity(EntityId(4))).Times(AnyNumber()).WillRepeatedly(Return(default_multicast_locator)); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); + + // Precondition: Participant_5 exists and has ID 5 + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(5)))); + EXPECT_CALL(database, get_entity(EntityId(5))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); + EXPECT_CALL(database, get_entities(EntityKind::PARTICIPANT, EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, participant_))); + + // Precondition: The Host exists + EXPECT_CALL(database, + get_entities_by_name(EntityKind::HOST, host_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, std::make_pair(EntityId(0), EntityId(13))))); + host_->id = EntityId(13); + EXPECT_CALL(database, get_entity(EntityId(13))).Times(AnyNumber()) + .WillRepeatedly(Return(host_)); - // Start building the discovered reader info - eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; - eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); + // Precondition: The User exists + EXPECT_CALL(database, + get_entities_by_name(EntityKind::USER, user_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, std::make_pair(EntityId(0), EntityId(14))))); + user_->id = EntityId(14); + EXPECT_CALL(database, get_entity(EntityId(14))).Times(AnyNumber()) + .WillRepeatedly(Return(user_)); - // Precondition: The discovered participant has the given GUID and name - data.m_guid = participant_2_guid; - data.m_participantName = participant_2_name; + // Precondition: The Process exists + EXPECT_CALL(database, + get_entities_by_name(EntityKind::PROCESS, process_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, std::make_pair(EntityId(0), EntityId(15))))); + process_->id = EntityId(15); + participant_->process = process_; + EXPECT_CALL(database, get_entity(EntityId(15))).Times(AnyNumber()) + .WillRepeatedly(Return(process_)); + + // Precondition: The Metatrafic Topic exists and has ID 6 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(6))))); + EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) + .WillRepeatedly(Return(metatraffic_topic_)); - // Precondition: The discovered participant has unicast and multicast locators associated - data.metatraffic_locators.unicast.push_back(1); - data.metatraffic_locators.multicast.push_back(2); - data.default_locators.unicast.push_back(3); - data.default_locators.multicast.push_back(4); + // Precondition: The Participant_1 Metatrafic Endpoint exists and has ID 7 + EXPECT_CALL(database, + get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(7)))); + EXPECT_CALL(database, get_entity(EntityId(7))).Times(AnyNumber()) + .WillRepeatedly(Return(metatraffic_endpoint_)); + + // Precondition: The new Participant does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_2_guid_str)).Times(AnyNumber()) + .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) + .WillRepeatedly(Return(std::pair(0, 10))); + EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) + .WillRepeatedly(Return(std::shared_ptr())); + + // Precondition: The Metatrafic Endpoint does not exist + EXPECT_CALL(database, + get_entity_by_guid(EntityKind::DATAWRITER, participant_2_guid_str)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); + // Precondition: There are unicast locators in database + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:1")) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(1))))); + EXPECT_CALL(database, + get_entity(EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(metatraffic_unicast_locator)); - // Expectation: The Participant_2 is added to the database. We do not care about the given ID - InsertEntityArgs insert_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); - EXPECT_EQ(entity->name, participant_2_name); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_2_guid_str); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - participant_proxy_data_to_backend_qos(info.info)); + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:3")) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()).WillRepeatedly(Return(default_unicast_locator)); - return EntityId(10); - }); + // Precondition: There are not multicast locators in database + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:2")) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, + get_entity(EntityId(2))).Times(AnyNumber()).WillRepeatedly(Return(metatraffic_multicast_locator)); - // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID - InsertEntityArgs insert_datawriter_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); - EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_2_guid_str); + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:4")) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(4))))); + EXPECT_CALL(database, + get_entity(EntityId(4))).Times(AnyNumber()).WillRepeatedly(Return(default_multicast_locator)); - return EntityId(12); - }); + // Start building the discovered reader info + eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; + eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); - EXPECT_CALL(database, insert(_)).Times(2) - .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + // Precondition: The discovered participant has the given GUID and name + data.m_guid = participant_2_guid; + data.m_participantName = participant_2_name; - // Expectation: The Participant is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_host, host_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_user, user_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_process, process_name_); - // Expectation: The metatraffic endpoint change it status - EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + // Precondition: The discovered participant has unicast and multicast locators associated + data.metatraffic_locators.unicast.push_back(1); + data.metatraffic_locators.multicast.push_back(2); + data.default_locators.unicast.push_back(3); + data.default_locators.multicast.push_back(4); - // Expectation: The metatraffic endpoint is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); - // Execution: Call the listener - info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; - participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + // Expectation: The Participant_2 is added to the database. We do not care about the given ID + InsertEntityArgs insert_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); + EXPECT_EQ(entity->name, participant_2_name); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_2_guid_str); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + participant_proxy_data_to_backend_qos(info.info)); + + return EntityId(10); + }); + + // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID + InsertEntityArgs insert_datawriter_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); + EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_2_guid_str); + + return EntityId(12); + }); + + EXPECT_CALL(database, insert(_)).Times(2) + .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + + // Expectation: The link method is called with appropriate arguments + EXPECT_CALL(database, link_participant_with_process(EntityId(10), EntityId(15))).Times(1); + + // Expectation: Modify graph + EXPECT_CALL(database, update_participant_in_graph(EntityId(0),EntityId(13),EntityId(14),EntityId(15),EntityId(10))).Times(1).WillOnce(Return(true)); + + // Expectation: The Participant is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Expectation: The metatraffic endpoint change it status + EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(10),EntityId(6),EntityId(12))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(2); + + // Expectation: The metatraffic endpoint is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener + info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; + participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); } TEST_F(statistics_participant_listener_tests, new_participant_undiscovered) @@ -588,969 +724,1387 @@ TEST_F(statistics_participant_listener_tests, new_participant_undiscovered) // Participant name will be localhost:participant_id TEST_F(statistics_participant_listener_tests, new_participant_discovered_empty_name_no_locators) { - participant_name_ = ""; + participant_name_ = ""; - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()).WillRepeatedly(Return(domain_)); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()).WillRepeatedly(Return(domain_)); - // Precondition: The Participant does not exist - EXPECT_CALL(database, - get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) - .Times(AnyNumber()) - .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) - .WillRepeatedly(Return(std::pair(0, 10))); - EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) - .WillRepeatedly(Return(std::shared_ptr())); + // Precondition: The Participant does not exist + EXPECT_CALL(database, + get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) + .Times(AnyNumber()) + .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) + .WillRepeatedly(Return(std::pair(0, 10))); + EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) + .WillRepeatedly(Return(std::shared_ptr())); + + // Precondition: The Host does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::HOST, host_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The Metatrafic Topic does not exist - EXPECT_CALL(database, - get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(0))); + // Precondition: The User does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::USER, user_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The Metatrafic Endpoint does not exist - EXPECT_CALL(database, - get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + // Precondition: The Process does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::PROCESS, process_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Start building the discovered reader info - eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; - eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); + // Precondition: The Metatrafic Topic does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The discovered participant has the given GUID and name - data.m_guid = participant_guid_; - data.m_participantName = participant_name_; + // Precondition: The Metatrafic Endpoint does not exist + EXPECT_CALL(database, + get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); + // Start building the discovered reader info + eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; + eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); - // Expectation: The Participant is added to the database. We do not care about the given ID - InsertEntityArgs insert_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); - EXPECT_EQ(entity->name, "localhost:09.0a.0b.0c"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - participant_proxy_data_to_backend_qos(info.info)); + // Precondition: The discovered participant has the given GUID and name + data.m_guid = participant_guid_; + data.m_participantName = participant_name_; - return EntityId(10); - }); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_host, host_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_user, user_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_process, process_name_); - // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID - InsertEntityArgs insert_topic_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::TOPIC); - EXPECT_EQ(entity->name, metatraffic_prefix + "TOPIC"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, metatraffic_prefix + "TYPE"); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); - return EntityId(11); - }); + // Expectation: The Participant is added to the database. We do not care about the given ID + InsertEntityArgs insert_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); + EXPECT_EQ(entity->name, "localhost:09.0a.0b.0c"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + participant_proxy_data_to_backend_qos(info.info)); + + return EntityId(10); + }); + + // Expectation: The host is created and given ID 13 + InsertEntityArgs insert_args_host([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::HOST); + EXPECT_EQ(entity->name, host_name_); + EXPECT_EQ(entity->alias, host_name_); - // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID - InsertEntityArgs insert_datawriter_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); - EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + return EntityId(13); + }); - return EntityId(12); - }); + // Expectation: The user is created and given ID 14 + InsertEntityArgs insert_args_user([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::USER); + EXPECT_EQ(entity->name, user_name_); + EXPECT_EQ(entity->alias, user_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->host, insert_args_host.entity_); - EXPECT_CALL(database, insert(_)).Times(3) - .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + return EntityId(14); + }); - // Expectation: The Participant is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The process is created and given ID 15 + InsertEntityArgs insert_args_process([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PROCESS); + EXPECT_EQ(entity->name, process_name_); + EXPECT_EQ(entity->alias, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->pid, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->user, insert_args_user.entity_); + + return EntityId(15); + }); + + // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID + InsertEntityArgs insert_topic_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::TOPIC); + EXPECT_EQ(entity->name, metatraffic_prefix + "TOPIC"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, metatraffic_prefix + "TYPE"); - // Expectation: The metatraffic endpoint change it status - EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + return EntityId(11); + }); - // Expectation: The metatraffic endpoint is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - - // Expectation: The topic is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::TOPIC, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - - // Execution: Call the listener - info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; - participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID + InsertEntityArgs insert_datawriter_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); + EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + + return EntityId(12); + }); + + EXPECT_CALL(database, insert(_)).Times(6) + .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_host, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_user, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_process, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + + // Expectation: The link method is called with appropriate arguments + EXPECT_CALL(database, link_participant_with_process(EntityId(10), EntityId(15))).Times(1); + + // Expectation: Modify graph + EXPECT_CALL(database, update_participant_in_graph(EntityId(0),EntityId(13),EntityId(14),EntityId(15),EntityId(10))).Times(1).WillOnce(Return(true)); + + // Expectation: The Participant is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Expectation: The metatraffic endpoint change it status + EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(10),EntityId(11),EntityId(12))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(2); + + // Expectation: The metatraffic endpoint is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Expectation: The topic is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::TOPIC, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener + info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; + participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); } // Test that discovers a participant with a locator associated and an empty name. // Participant name will be locator_IP:participant_id TEST_F(statistics_participant_listener_tests, new_participant_discovered_empty_name_default_unicast_locator) { - participant_name_ = ""; - - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) - .Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()).WillRepeatedly(Return(domain_)); - - // Precondition: The Participant does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) - .Times(AnyNumber()) - .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) - .WillRepeatedly(Return(std::pair(0, 10))); - EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) - .WillRepeatedly(Return(std::shared_ptr())); - - // Precondition: The Metatrafic Topic does not exist - EXPECT_CALL(database, - get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(0))); - - // Precondition: The Metatrafic Endpoint does not exist - EXPECT_CALL(database, - get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - - // Start building the discovered reader info - eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; - eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); + participant_name_ = ""; - // Precondition: The discovered participant has the given GUID and name - data.m_guid = participant_guid_; - data.m_participantName = participant_name_; - - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); - - // Precondition: The Unicast Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 37; - dds_existing_unicast_locator.address[13] = 11; - dds_existing_unicast_locator.address[14] = 18; - dds_existing_unicast_locator.address[15] = 30; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()).WillRepeatedly(Return( - std::vector>(1, std::make_pair( - EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()).WillRepeatedly(Return(existing_unicast_locator)); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) + .Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()).WillRepeatedly(Return(domain_)); - // Precondition: The discovered reader contains the locator - data.default_locators.add_unicast_locator(dds_existing_unicast_locator); - - // Precondition: The Unicast Metatraffic Locator exists and has ID 4 - eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_metatraffic_unicast_locator.address[12] = 38; - dds_existing_metatraffic_unicast_locator.address[13] = 12; - dds_existing_metatraffic_unicast_locator.address[14] = 19; - dds_existing_metatraffic_unicast_locator.address[15] = 31; - std::string existing_metatraffic_unicast_locator_name = to_string(dds_existing_metatraffic_unicast_locator); - std::shared_ptr existing_metatraffic_unicast_locator = - std::make_shared(existing_metatraffic_unicast_locator_name); - existing_metatraffic_unicast_locator->id = 4; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_unicast_locator_name)).Times( - AnyNumber()).WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(4))))); - EXPECT_CALL(database, - get_entity(EntityId(4))).Times(AnyNumber()).WillRepeatedly(Return(existing_metatraffic_unicast_locator)); + // Precondition: The Participant does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) + .Times(AnyNumber()) + .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) + .WillRepeatedly(Return(std::pair(0, 10))); + EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) + .WillRepeatedly(Return(std::shared_ptr())); + + // Precondition: The Host does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::HOST, host_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The discovered reader contains the locator - data.metatraffic_locators.add_unicast_locator(dds_existing_metatraffic_unicast_locator); - - // Precondition: The Multicast Locator exists and has ID 5 - eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_multicast_locator.address[12] = 36; - dds_existing_multicast_locator.address[13] = 10; - dds_existing_multicast_locator.address[14] = 17; - dds_existing_multicast_locator.address[15] = 29; - std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); - std::shared_ptr existing_multicast_locator = - std::make_shared(existing_multicast_locator_name); - existing_multicast_locator->id = 5; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(5))))); - EXPECT_CALL(database, get_entity(EntityId(5))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_multicast_locator)); + // Precondition: The User does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::USER, user_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The discovered reader contains the locator - data.default_locators.add_multicast_locator(dds_existing_multicast_locator); - - // Precondition: The Multicast Metatraffic Locator exists and has ID 6 - eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_metatraffic_multicast_locator.address[12] = 47; - dds_existing_metatraffic_multicast_locator.address[13] = 21; - dds_existing_metatraffic_multicast_locator.address[14] = 28; - dds_existing_metatraffic_multicast_locator.address[15] = 40; - std::string existing_metatraffic_multicast_locator_name = to_string(dds_existing_metatraffic_multicast_locator); - std::shared_ptr existing_metatraffic_multicast_locator = - std::make_shared(existing_metatraffic_multicast_locator_name); - existing_metatraffic_multicast_locator->id = 6; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_multicast_locator_name)).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(6))))); - EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_metatraffic_multicast_locator)); + // Precondition: The Process does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::PROCESS, process_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The discovered reader contains the locator - data.metatraffic_locators.add_multicast_locator(dds_existing_metatraffic_multicast_locator); + // Precondition: The Metatrafic Topic does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: There are 4 locators - EXPECT_CALL(database, - get_entities(EntityKind::LOCATOR, - EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(std::vector>({ - existing_unicast_locator, existing_metatraffic_unicast_locator, existing_multicast_locator, - existing_metatraffic_multicast_locator}))); + // Precondition: The Metatrafic Endpoint does not exist + EXPECT_CALL(database, + get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Expectation: The Participant is added to the database. We do not care about the given ID - InsertEntityArgs insert_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); - EXPECT_EQ(entity->name, "37.11.18.30:09.0a.0b.0c"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - participant_proxy_data_to_backend_qos(info.info)); + // Start building the discovered reader info + eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; + eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); - return EntityId(10); - }); + // Precondition: The discovered participant has the given GUID and name + data.m_guid = participant_guid_; + data.m_participantName = participant_name_; - // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID - InsertEntityArgs insert_topic_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::TOPIC); - EXPECT_EQ(entity->name, metatraffic_prefix + "TOPIC"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, metatraffic_prefix + "TYPE"); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_host, host_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_user, user_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_process, process_name_); - return EntityId(11); - }); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); + + // Precondition: The Unicast Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 37; + dds_existing_unicast_locator.address[13] = 11; + dds_existing_unicast_locator.address[14] = 18; + dds_existing_unicast_locator.address[15] = 30; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()).WillRepeatedly(Return( + std::vector>(1, std::make_pair( + EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()).WillRepeatedly(Return(existing_unicast_locator)); + + // Precondition: The discovered reader contains the locator + data.default_locators.add_unicast_locator(dds_existing_unicast_locator); + + // Precondition: The Unicast Metatraffic Locator exists and has ID 4 + eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_metatraffic_unicast_locator.address[12] = 38; + dds_existing_metatraffic_unicast_locator.address[13] = 12; + dds_existing_metatraffic_unicast_locator.address[14] = 19; + dds_existing_metatraffic_unicast_locator.address[15] = 31; + std::string existing_metatraffic_unicast_locator_name = to_string(dds_existing_metatraffic_unicast_locator); + std::shared_ptr existing_metatraffic_unicast_locator = + std::make_shared(existing_metatraffic_unicast_locator_name); + existing_metatraffic_unicast_locator->id = 4; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_unicast_locator_name)).Times( + AnyNumber()).WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(4))))); + EXPECT_CALL(database, + get_entity(EntityId(4))).Times(AnyNumber()).WillRepeatedly(Return(existing_metatraffic_unicast_locator)); + + // Precondition: The discovered reader contains the locator + data.metatraffic_locators.add_unicast_locator(dds_existing_metatraffic_unicast_locator); + + // Precondition: The Multicast Locator exists and has ID 5 + eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_multicast_locator.address[12] = 36; + dds_existing_multicast_locator.address[13] = 10; + dds_existing_multicast_locator.address[14] = 17; + dds_existing_multicast_locator.address[15] = 29; + std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); + std::shared_ptr existing_multicast_locator = + std::make_shared(existing_multicast_locator_name); + existing_multicast_locator->id = 5; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(5))))); + EXPECT_CALL(database, get_entity(EntityId(5))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_multicast_locator)); + + // Precondition: The discovered reader contains the locator + data.default_locators.add_multicast_locator(dds_existing_multicast_locator); + + // Precondition: The Multicast Metatraffic Locator exists and has ID 6 + eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_metatraffic_multicast_locator.address[12] = 47; + dds_existing_metatraffic_multicast_locator.address[13] = 21; + dds_existing_metatraffic_multicast_locator.address[14] = 28; + dds_existing_metatraffic_multicast_locator.address[15] = 40; + std::string existing_metatraffic_multicast_locator_name = to_string(dds_existing_metatraffic_multicast_locator); + std::shared_ptr existing_metatraffic_multicast_locator = + std::make_shared(existing_metatraffic_multicast_locator_name); + existing_metatraffic_multicast_locator->id = 6; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_multicast_locator_name)).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(6))))); + EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_metatraffic_multicast_locator)); - // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID - InsertEntityArgs insert_datawriter_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); - EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + // Precondition: The discovered reader contains the locator + data.metatraffic_locators.add_multicast_locator(dds_existing_metatraffic_multicast_locator); - return EntityId(12); - }); + // Precondition: There are 4 locators + EXPECT_CALL(database, + get_entities(EntityKind::LOCATOR, + EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(std::vector>({ + existing_unicast_locator, existing_metatraffic_unicast_locator, existing_multicast_locator, + existing_metatraffic_multicast_locator}))); + + // Expectation: The Participant is added to the database. We do not care about the given ID + InsertEntityArgs insert_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); + EXPECT_EQ(entity->name, "37.11.18.30:09.0a.0b.0c"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + participant_proxy_data_to_backend_qos(info.info)); + + return EntityId(10); + }); + + // Expectation: The host is created and given ID 13 + InsertEntityArgs insert_args_host([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::HOST); + EXPECT_EQ(entity->name, host_name_); + EXPECT_EQ(entity->alias, host_name_); - EXPECT_CALL(database, insert(_)).Times(3) - .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + return EntityId(13); + }); - // Expectation: The Participant is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The user is created and given ID 14 + InsertEntityArgs insert_args_user([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::USER); + EXPECT_EQ(entity->name, user_name_); + EXPECT_EQ(entity->alias, user_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->host, insert_args_host.entity_); - // Expectation: The metatraffic endpoint change it status - EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + return EntityId(14); + }); - // Expectation: The metatraffic endpoint is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The process is created and given ID 15 + InsertEntityArgs insert_args_process([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PROCESS); + EXPECT_EQ(entity->name, process_name_); + EXPECT_EQ(entity->alias, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->pid, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->user, insert_args_user.entity_); + + return EntityId(15); + }); + + // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID + InsertEntityArgs insert_topic_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::TOPIC); + EXPECT_EQ(entity->name, metatraffic_prefix + "TOPIC"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, metatraffic_prefix + "TYPE"); - // Expectation: The topic is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::TOPIC, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + return EntityId(11); + }); - // Execution: Call the listener - info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; - participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID + InsertEntityArgs insert_datawriter_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); + EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + + return EntityId(12); + }); + + EXPECT_CALL(database, insert(_)).Times(6) + .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_host, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_user, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_process, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + + // Expectation: The link method is called with appropriate arguments + EXPECT_CALL(database, link_participant_with_process(EntityId(10), EntityId(15))).Times(1); + + // Expectation: Modify graph and notify user + EXPECT_CALL(database, update_participant_in_graph(EntityId(0),EntityId(13),EntityId(14),EntityId(15),EntityId(10))).Times(1).WillOnce(Return(true)); + + // Expectation: The Participant is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Expectation: The metatraffic endpoint change it status + EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(10),EntityId(11),EntityId(12))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(2); + + // Expectation: The metatraffic endpoint is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Expectation: The topic is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::TOPIC, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener + info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; + participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); } // Test that discovers a participant with a locator associated and an empty name. // Participant name will be locator_IP:participant_id TEST_F(statistics_participant_listener_tests, new_participant_discovered_empty_name_metatraffic_unicast_locator) { - participant_name_ = ""; - - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) - .Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()).WillRepeatedly(Return(domain_)); - - // Precondition: The Participant does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) - .Times(AnyNumber()) - .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) - .WillRepeatedly(Return(std::pair(0, 10))); - EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) - .WillRepeatedly(Return(std::shared_ptr())); - - // Precondition: The Metatrafic Topic does not exist - EXPECT_CALL(database, - get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(0))); - - // Precondition: The Metatrafic Endpoint does not exist - EXPECT_CALL(database, - get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - - // Start building the discovered reader info - eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; - eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); + participant_name_ = ""; - // Precondition: The discovered participant has the given GUID and name - data.m_guid = participant_guid_; - data.m_participantName = participant_name_; + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) + .Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()).WillRepeatedly(Return(domain_)); - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); + // Precondition: The Participant does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) + .Times(AnyNumber()) + .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) + .WillRepeatedly(Return(std::pair(0, 10))); + EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) + .WillRepeatedly(Return(std::shared_ptr())); + + // Precondition: The Host does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::HOST, host_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The Unicast Metatraffic Locator exists and has ID 4 - eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_metatraffic_unicast_locator.address[12] = 37; - dds_existing_metatraffic_unicast_locator.address[13] = 11; - dds_existing_metatraffic_unicast_locator.address[14] = 18; - dds_existing_metatraffic_unicast_locator.address[15] = 30; - std::string existing_metatraffic_unicast_locator_name = to_string(dds_existing_metatraffic_unicast_locator); - std::shared_ptr existing_metatraffic_unicast_locator = - std::make_shared(existing_metatraffic_unicast_locator_name); - existing_metatraffic_unicast_locator->id = 4; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_unicast_locator_name)).Times( - AnyNumber()).WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(4))))); - EXPECT_CALL(database, - get_entity(EntityId(4))).Times(AnyNumber()).WillRepeatedly(Return(existing_metatraffic_unicast_locator)); + // Precondition: The User does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::USER, user_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The discovered reader contains the locator - data.metatraffic_locators.add_unicast_locator(dds_existing_metatraffic_unicast_locator); - - // Precondition: The Multicast Locator exists and has ID 5 - eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_multicast_locator.address[12] = 36; - dds_existing_multicast_locator.address[13] = 10; - dds_existing_multicast_locator.address[14] = 17; - dds_existing_multicast_locator.address[15] = 29; - std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); - std::shared_ptr existing_multicast_locator = - std::make_shared(existing_multicast_locator_name); - existing_multicast_locator->id = 5; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(5))))); - EXPECT_CALL(database, get_entity(EntityId(5))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_multicast_locator)); + // Precondition: The Process does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::PROCESS, process_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The discovered reader contains the locator - data.default_locators.add_multicast_locator(dds_existing_multicast_locator); - - // Precondition: The Multicast Metatraffic Locator exists and has ID 6 - eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_metatraffic_multicast_locator.address[12] = 47; - dds_existing_metatraffic_multicast_locator.address[13] = 21; - dds_existing_metatraffic_multicast_locator.address[14] = 28; - dds_existing_metatraffic_multicast_locator.address[15] = 40; - std::string existing_metatraffic_multicast_locator_name = to_string(dds_existing_metatraffic_multicast_locator); - std::shared_ptr existing_metatraffic_multicast_locator = - std::make_shared(existing_metatraffic_multicast_locator_name); - existing_metatraffic_multicast_locator->id = 6; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_multicast_locator_name)).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(6))))); - EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_metatraffic_multicast_locator)); + // Precondition: The Metatrafic Topic does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The discovered reader contains the locator - data.metatraffic_locators.add_multicast_locator(dds_existing_metatraffic_multicast_locator); + // Precondition: The Metatrafic Endpoint does not exist + EXPECT_CALL(database, + get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Precondition: There are 3 locators - EXPECT_CALL(database, - get_entities(EntityKind::LOCATOR, - EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(std::vector>({ - existing_metatraffic_unicast_locator, existing_multicast_locator, - existing_metatraffic_multicast_locator}))); + // Start building the discovered reader info + eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; + eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); + // Precondition: The discovered participant has the given GUID and name + data.m_guid = participant_guid_; + data.m_participantName = participant_name_; - // Expectation: The Participant is added to the database. We do not care about the given ID - InsertEntityArgs insert_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); - EXPECT_EQ(entity->name, "37.11.18.30:09.0a.0b.0c"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - participant_proxy_data_to_backend_qos(info.info)); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_host, host_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_user, user_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_process, process_name_); - return EntityId(10); - }); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); + + // Precondition: The Unicast Metatraffic Locator exists and has ID 4 + eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_metatraffic_unicast_locator.address[12] = 37; + dds_existing_metatraffic_unicast_locator.address[13] = 11; + dds_existing_metatraffic_unicast_locator.address[14] = 18; + dds_existing_metatraffic_unicast_locator.address[15] = 30; + std::string existing_metatraffic_unicast_locator_name = to_string(dds_existing_metatraffic_unicast_locator); + std::shared_ptr existing_metatraffic_unicast_locator = + std::make_shared(existing_metatraffic_unicast_locator_name); + existing_metatraffic_unicast_locator->id = 4; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_unicast_locator_name)).Times( + AnyNumber()).WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(4))))); + EXPECT_CALL(database, + get_entity(EntityId(4))).Times(AnyNumber()).WillRepeatedly(Return(existing_metatraffic_unicast_locator)); + + // Precondition: The discovered reader contains the locator + data.metatraffic_locators.add_unicast_locator(dds_existing_metatraffic_unicast_locator); + + // Precondition: The Multicast Locator exists and has ID 5 + eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_multicast_locator.address[12] = 36; + dds_existing_multicast_locator.address[13] = 10; + dds_existing_multicast_locator.address[14] = 17; + dds_existing_multicast_locator.address[15] = 29; + std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); + std::shared_ptr existing_multicast_locator = + std::make_shared(existing_multicast_locator_name); + existing_multicast_locator->id = 5; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(5))))); + EXPECT_CALL(database, get_entity(EntityId(5))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_multicast_locator)); + + // Precondition: The discovered reader contains the locator + data.default_locators.add_multicast_locator(dds_existing_multicast_locator); + + // Precondition: The Multicast Metatraffic Locator exists and has ID 6 + eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_metatraffic_multicast_locator.address[12] = 47; + dds_existing_metatraffic_multicast_locator.address[13] = 21; + dds_existing_metatraffic_multicast_locator.address[14] = 28; + dds_existing_metatraffic_multicast_locator.address[15] = 40; + std::string existing_metatraffic_multicast_locator_name = to_string(dds_existing_metatraffic_multicast_locator); + std::shared_ptr existing_metatraffic_multicast_locator = + std::make_shared(existing_metatraffic_multicast_locator_name); + existing_metatraffic_multicast_locator->id = 6; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_multicast_locator_name)).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(6))))); + EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_metatraffic_multicast_locator)); - // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID - InsertEntityArgs insert_topic_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::TOPIC); - EXPECT_EQ(entity->name, metatraffic_prefix + "TOPIC"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, metatraffic_prefix + "TYPE"); + // Precondition: The discovered reader contains the locator + data.metatraffic_locators.add_multicast_locator(dds_existing_metatraffic_multicast_locator); - return EntityId(11); - }); + // Precondition: There are 3 locators + EXPECT_CALL(database, + get_entities(EntityKind::LOCATOR, + EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(std::vector>({ + existing_metatraffic_unicast_locator, existing_multicast_locator, + existing_metatraffic_multicast_locator}))); - // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID - InsertEntityArgs insert_datawriter_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); - EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); - return EntityId(12); - }); + // Expectation: The Participant is added to the database. We do not care about the given ID + InsertEntityArgs insert_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); + EXPECT_EQ(entity->name, "37.11.18.30:09.0a.0b.0c"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + participant_proxy_data_to_backend_qos(info.info)); + + return EntityId(10); + }); + + // Expectation: The host is created and given ID 13 + InsertEntityArgs insert_args_host([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::HOST); + EXPECT_EQ(entity->name, host_name_); + EXPECT_EQ(entity->alias, host_name_); - EXPECT_CALL(database, insert(_)).Times(3) - .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + return EntityId(13); + }); - // Expectation: The Participant is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The user is created and given ID 14 + InsertEntityArgs insert_args_user([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::USER); + EXPECT_EQ(entity->name, user_name_); + EXPECT_EQ(entity->alias, user_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->host, insert_args_host.entity_); - // Expectation: The metatraffic endpoint change it status - EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + return EntityId(14); + }); - // Expectation: The metatraffic endpoint is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The process is created and given ID 15 + InsertEntityArgs insert_args_process([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PROCESS); + EXPECT_EQ(entity->name, process_name_); + EXPECT_EQ(entity->alias, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->pid, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->user, insert_args_user.entity_); + + return EntityId(15); + }); + + // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID + InsertEntityArgs insert_topic_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::TOPIC); + EXPECT_EQ(entity->name, metatraffic_prefix + "TOPIC"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, metatraffic_prefix + "TYPE"); - // Expectation: The topic is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::TOPIC, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + return EntityId(11); + }); - // Execution: Call the listener - info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; - participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID + InsertEntityArgs insert_datawriter_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); + EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + + return EntityId(12); + }); + + EXPECT_CALL(database, insert(_)).Times(6) + .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_host, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_user, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_process, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + + // Expectation: The link method is called with appropriate arguments + EXPECT_CALL(database, link_participant_with_process(EntityId(10), EntityId(15))).Times(1); + + // Expectation: Modify graph + EXPECT_CALL(database, update_participant_in_graph(EntityId(0),EntityId(13),EntityId(14),EntityId(15),EntityId(10))).Times(1).WillOnce(Return(true)); + + // Expectation: The Participant is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Expectation: The metatraffic endpoint change it status + EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + + // Expectation: Modify graph and notify user + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(10),EntityId(11),EntityId(12))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(2); + + // Expectation: The metatraffic endpoint is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Expectation: The topic is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::TOPIC, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener + info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; + participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); } // Test that discovers a participant with a locator associated and an empty name. // Participant name will be locator_IP:participant_id TEST_F(statistics_participant_listener_tests, new_participant_discovered_empty_name_default_multicast_locator) { - participant_name_ = ""; - - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) - .Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()).WillRepeatedly(Return(domain_)); + participant_name_ = ""; - // Precondition: The Participant does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) - .Times(AnyNumber()) - .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) - .WillRepeatedly(Return(std::pair(0, 10))); - EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) - .WillRepeatedly(Return(std::shared_ptr())); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) + .Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()).WillRepeatedly(Return(domain_)); - // Precondition: The Metatrafic Topic does not exist - EXPECT_CALL(database, - get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(0))); + // Precondition: The Participant does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) + .Times(AnyNumber()) + .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) + .WillRepeatedly(Return(std::pair(0, 10))); + EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) + .WillRepeatedly(Return(std::shared_ptr())); + + // Precondition: The Host does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::HOST, host_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The Metatrafic Endpoint does not exist - EXPECT_CALL(database, - get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + // Precondition: The User does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::USER, user_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Start building the discovered reader info - eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; - eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); + // Precondition: The Process does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::PROCESS, process_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The discovered participant has the given GUID and name - data.m_guid = participant_guid_; - data.m_participantName = participant_name_; + // Precondition: The Metatrafic Topic does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); + // Precondition: The Metatrafic Endpoint does not exist + EXPECT_CALL(database, + get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Precondition: The Multicast Locator exists and has ID 5 - eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_multicast_locator.address[12] = 37; - dds_existing_multicast_locator.address[13] = 11; - dds_existing_multicast_locator.address[14] = 18; - dds_existing_multicast_locator.address[15] = 30; - std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); - std::shared_ptr existing_multicast_locator = - std::make_shared(existing_multicast_locator_name); - existing_multicast_locator->id = 5; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(5))))); - EXPECT_CALL(database, get_entity(EntityId(5))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_multicast_locator)); + // Start building the discovered reader info + eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; + eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); - // Precondition: The discovered reader contains the locator - data.default_locators.add_multicast_locator(dds_existing_multicast_locator); - - // Precondition: The Multicast Metatraffic Locator exists and has ID 6 - eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_metatraffic_multicast_locator.address[12] = 47; - dds_existing_metatraffic_multicast_locator.address[13] = 21; - dds_existing_metatraffic_multicast_locator.address[14] = 28; - dds_existing_metatraffic_multicast_locator.address[15] = 40; - std::string existing_metatraffic_multicast_locator_name = to_string(dds_existing_metatraffic_multicast_locator); - std::shared_ptr existing_metatraffic_multicast_locator = - std::make_shared(existing_metatraffic_multicast_locator_name); - existing_metatraffic_multicast_locator->id = 6; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_multicast_locator_name)).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(6))))); - EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_metatraffic_multicast_locator)); + // Precondition: The discovered participant has the given GUID and name + data.m_guid = participant_guid_; + data.m_participantName = participant_name_; - // Precondition: The discovered reader contains the locator - data.metatraffic_locators.add_multicast_locator(dds_existing_metatraffic_multicast_locator); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_host, host_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_user, user_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_process, process_name_); - // Precondition: There are 2 locators - EXPECT_CALL(database, - get_entities(EntityKind::LOCATOR, - EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(std::vector>({ - existing_multicast_locator, - existing_metatraffic_multicast_locator}))); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); + + // Precondition: The Multicast Locator exists and has ID 5 + eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_multicast_locator.address[12] = 37; + dds_existing_multicast_locator.address[13] = 11; + dds_existing_multicast_locator.address[14] = 18; + dds_existing_multicast_locator.address[15] = 30; + std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); + std::shared_ptr existing_multicast_locator = + std::make_shared(existing_multicast_locator_name); + existing_multicast_locator->id = 5; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(5))))); + EXPECT_CALL(database, get_entity(EntityId(5))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_multicast_locator)); + + // Precondition: The discovered reader contains the locator + data.default_locators.add_multicast_locator(dds_existing_multicast_locator); + + // Precondition: The Multicast Metatraffic Locator exists and has ID 6 + eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_metatraffic_multicast_locator.address[12] = 47; + dds_existing_metatraffic_multicast_locator.address[13] = 21; + dds_existing_metatraffic_multicast_locator.address[14] = 28; + dds_existing_metatraffic_multicast_locator.address[15] = 40; + std::string existing_metatraffic_multicast_locator_name = to_string(dds_existing_metatraffic_multicast_locator); + std::shared_ptr existing_metatraffic_multicast_locator = + std::make_shared(existing_metatraffic_multicast_locator_name); + existing_metatraffic_multicast_locator->id = 6; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_multicast_locator_name)).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(6))))); + EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_metatraffic_multicast_locator)); - // Expectation: The Participant is added to the database. We do not care about the given ID - InsertEntityArgs insert_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); - EXPECT_EQ(entity->name, "37.11.18.30:09.0a.0b.0c"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - participant_proxy_data_to_backend_qos(info.info)); + // Precondition: The discovered reader contains the locator + data.metatraffic_locators.add_multicast_locator(dds_existing_metatraffic_multicast_locator); - return EntityId(10); - }); - - - // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID - InsertEntityArgs insert_topic_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::TOPIC); - EXPECT_EQ(entity->name, metatraffic_prefix + "TOPIC"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, metatraffic_prefix + "TYPE"); - - return EntityId(11); - }); - - // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID - InsertEntityArgs insert_datawriter_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); - EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); - - return EntityId(12); - }); + // Precondition: There are 2 locators + EXPECT_CALL(database, + get_entities(EntityKind::LOCATOR, + EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(std::vector>({ + existing_multicast_locator, + existing_metatraffic_multicast_locator}))); + + // Expectation: The Participant is added to the database. We do not care about the given ID + InsertEntityArgs insert_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); + EXPECT_EQ(entity->name, "37.11.18.30:09.0a.0b.0c"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + participant_proxy_data_to_backend_qos(info.info)); + + return EntityId(10); + }); + + // Expectation: The host is created and given ID 13 + InsertEntityArgs insert_args_host([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::HOST); + EXPECT_EQ(entity->name, host_name_); + EXPECT_EQ(entity->alias, host_name_); - EXPECT_CALL(database, insert(_)).Times(3) - .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + return EntityId(13); + }); - // Expectation: The Participant is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The user is created and given ID 14 + InsertEntityArgs insert_args_user([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::USER); + EXPECT_EQ(entity->name, user_name_); + EXPECT_EQ(entity->alias, user_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->host, insert_args_host.entity_); - // Expectation: The metatraffic endpoint change it status - EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + return EntityId(14); + }); - // Expectation: The metatraffic endpoint is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The process is created and given ID 15 + InsertEntityArgs insert_args_process([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PROCESS); + EXPECT_EQ(entity->name, process_name_); + EXPECT_EQ(entity->alias, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->pid, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->user, insert_args_user.entity_); + + return EntityId(15); + }); + + // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID + InsertEntityArgs insert_topic_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::TOPIC); + EXPECT_EQ(entity->name, metatraffic_prefix + "TOPIC"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, metatraffic_prefix + "TYPE"); - // Expectation: The topic is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::TOPIC, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + return EntityId(11); + }); - // Execution: Call the listener - info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; - participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID + InsertEntityArgs insert_datawriter_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); + EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + + return EntityId(12); + }); + + EXPECT_CALL(database, insert(_)).Times(6) + .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_host, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_user, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_process, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + + // Expectation: The link method is called with appropriate arguments + EXPECT_CALL(database, link_participant_with_process(EntityId(10), EntityId(15))).Times(1); + + // Expectation: Modify graph + EXPECT_CALL(database, update_participant_in_graph(EntityId(0),EntityId(13),EntityId(14),EntityId(15),EntityId(10))).Times(1).WillOnce(Return(true)); + + // Expectation: The Participant is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Expectation: The metatraffic endpoint change it status + EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(10),EntityId(11),EntityId(12))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(2); + + // Expectation: The metatraffic endpoint is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Expectation: The topic is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::TOPIC, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener + info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; + participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); } // Test that discovers a participant with a locator associated and an empty name. // Participant name will be locator_IP:participant_id TEST_F(statistics_participant_listener_tests, new_participant_discovered_empty_name_metatraffic_multicast_locator) { - participant_name_ = ""; - - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) - .Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()).WillRepeatedly(Return(domain_)); - - // Precondition: The Participant does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) - .Times(AnyNumber()) - .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) - .WillRepeatedly(Return(std::pair(0, 10))); - EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) - .WillRepeatedly(Return(std::shared_ptr())); - - // Precondition: The Metatrafic Topic does not exist - EXPECT_CALL(database, - get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(0))); + participant_name_ = ""; - // Precondition: The Metatrafic Endpoint does not exist - EXPECT_CALL(database, - get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) + .Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()).WillRepeatedly(Return(domain_)); - // Start building the discovered reader info - eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; - eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); + // Precondition: The Participant does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) + .Times(AnyNumber()) + .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) + .WillRepeatedly(Return(std::pair(0, 10))); + EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) + .WillRepeatedly(Return(std::shared_ptr())); + + // Precondition: The Host does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::HOST, host_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The discovered participant has the given GUID and name - data.m_guid = participant_guid_; - data.m_participantName = participant_name_; + // Precondition: The User does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::USER, user_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); + // Precondition: The Process does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::PROCESS, process_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The Multicast Metatraffic Locator exists and has ID 6 - eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_metatraffic_multicast_locator.address[12] = 37; - dds_existing_metatraffic_multicast_locator.address[13] = 11; - dds_existing_metatraffic_multicast_locator.address[14] = 18; - dds_existing_metatraffic_multicast_locator.address[15] = 30; - std::string existing_metatraffic_multicast_locator_name = to_string(dds_existing_metatraffic_multicast_locator); - std::shared_ptr existing_metatraffic_multicast_locator = - std::make_shared(existing_metatraffic_multicast_locator_name); - existing_metatraffic_multicast_locator->id = 6; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_multicast_locator_name)).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(6))))); - EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_metatraffic_multicast_locator)); + // Precondition: The Metatrafic Topic does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The discovered reader contains the locator - data.metatraffic_locators.add_multicast_locator(dds_existing_metatraffic_multicast_locator); + // Precondition: The Metatrafic Endpoint does not exist + EXPECT_CALL(database, + get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Precondition: There are 1 locator - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>({existing_metatraffic_multicast_locator}))); + // Start building the discovered reader info + eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; + eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); - // Expectation: The Participant is added to the database. We do not care about the given ID - InsertEntityArgs insert_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); - EXPECT_EQ(entity->name, "37.11.18.30:09.0a.0b.0c"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - participant_proxy_data_to_backend_qos(info.info)); + // Precondition: The discovered participant has the given GUID and name + data.m_guid = participant_guid_; + data.m_participantName = participant_name_; - return EntityId(10); - }); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_host, host_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_user, user_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_process, process_name_); - // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID - InsertEntityArgs insert_topic_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::TOPIC); - EXPECT_EQ(entity->name, metatraffic_prefix + "TOPIC"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, metatraffic_prefix + "TYPE"); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); + + // Precondition: The Multicast Metatraffic Locator exists and has ID 6 + eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_metatraffic_multicast_locator.address[12] = 37; + dds_existing_metatraffic_multicast_locator.address[13] = 11; + dds_existing_metatraffic_multicast_locator.address[14] = 18; + dds_existing_metatraffic_multicast_locator.address[15] = 30; + std::string existing_metatraffic_multicast_locator_name = to_string(dds_existing_metatraffic_multicast_locator); + std::shared_ptr existing_metatraffic_multicast_locator = + std::make_shared(existing_metatraffic_multicast_locator_name); + existing_metatraffic_multicast_locator->id = 6; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_multicast_locator_name)).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(6))))); + EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_metatraffic_multicast_locator)); - return EntityId(11); - }); + // Precondition: The discovered reader contains the locator + data.metatraffic_locators.add_multicast_locator(dds_existing_metatraffic_multicast_locator); - // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID - InsertEntityArgs insert_datawriter_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); - EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + // Precondition: There are 1 locator + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>({existing_metatraffic_multicast_locator}))); - return EntityId(12); - }); + // Expectation: The Participant is added to the database. We do not care about the given ID + InsertEntityArgs insert_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); + EXPECT_EQ(entity->name, "37.11.18.30:09.0a.0b.0c"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + participant_proxy_data_to_backend_qos(info.info)); + + return EntityId(10); + }); + + // Expectation: The host is created and given ID 13 + InsertEntityArgs insert_args_host([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::HOST); + EXPECT_EQ(entity->name, host_name_); + EXPECT_EQ(entity->alias, host_name_); - EXPECT_CALL(database, insert(_)).Times(3) - .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + return EntityId(13); + }); - // Expectation: The Participant is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The user is created and given ID 14 + InsertEntityArgs insert_args_user([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::USER); + EXPECT_EQ(entity->name, user_name_); + EXPECT_EQ(entity->alias, user_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->host, insert_args_host.entity_); - // Expectation: The metatraffic endpoint change it status - EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + return EntityId(14); + }); - // Expectation: The metatraffic endpoint is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The process is created and given ID 15 + InsertEntityArgs insert_args_process([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PROCESS); + EXPECT_EQ(entity->name, process_name_); + EXPECT_EQ(entity->alias, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->pid, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->user, insert_args_user.entity_); + + return EntityId(15); + }); + + // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID + InsertEntityArgs insert_topic_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::TOPIC); + EXPECT_EQ(entity->name, metatraffic_prefix + "TOPIC"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, metatraffic_prefix + "TYPE"); - // Expectation: The topic is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::TOPIC, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + return EntityId(11); + }); - // Execution: Call the listener - info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; - participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID + InsertEntityArgs insert_datawriter_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); + EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + + return EntityId(12); + }); + + EXPECT_CALL(database, insert(_)).Times(6) + .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_host, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_user, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_process, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + + // Expectation: The link method is called with appropriate arguments + EXPECT_CALL(database, link_participant_with_process(EntityId(10), EntityId(15))).Times(1); + + // Expectation: Modify graph + EXPECT_CALL(database, update_participant_in_graph(EntityId(0),EntityId(13),EntityId(14),EntityId(15),EntityId(10))).Times(1).WillOnce(Return(true)); + + // Expectation: The Participant is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Expectation: The metatraffic endpoint change it status + EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(10),EntityId(11),EntityId(12))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(2); + + // Expectation: The metatraffic endpoint is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Expectation: The topic is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::TOPIC, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener + info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; + participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); } // Test that discoverS a participant with localhost locators associated and an empty name. // Participant name will be localhost:participant_id TEST_F(statistics_participant_listener_tests, new_participant_discovered_empty_name_localhost_locators) { - participant_name_ = ""; - - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) - .Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()).WillRepeatedly(Return(domain_)); - - // Precondition: The Participant does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) - .Times(AnyNumber()) - .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) - .WillRepeatedly(Return(std::pair(0, 10))); - EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) - .WillRepeatedly(Return(std::shared_ptr())); - - // Precondition: The Metatrafic Topic does not exist - EXPECT_CALL(database, - get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(0))); - - // Precondition: The Metatrafic Endpoint does not exist - EXPECT_CALL(database, - get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - - // Start building the discovered reader info - eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; - eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); - - // Precondition: The discovered participant has the given GUID and name - data.m_guid = participant_guid_; - data.m_participantName = participant_name_; - - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); + participant_name_ = ""; - // Precondition: The Unicast Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()).WillRepeatedly(Return( - std::vector>(1, std::make_pair( - EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()).WillRepeatedly(Return(existing_unicast_locator)); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))) + .Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()).WillRepeatedly(Return(domain_)); - // Precondition: The discovered reader contains the locator - data.default_locators.add_unicast_locator(dds_existing_unicast_locator); - - // Precondition: The Unicast Metatraffic Locator exists and has ID 4 - eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_metatraffic_unicast_locator.address[12] = 127; - dds_existing_metatraffic_unicast_locator.address[15] = 1; - std::string existing_metatraffic_unicast_locator_name = to_string(dds_existing_metatraffic_unicast_locator); - std::shared_ptr existing_metatraffic_unicast_locator = - std::make_shared(existing_metatraffic_unicast_locator_name); - existing_metatraffic_unicast_locator->id = 4; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_unicast_locator_name)).Times( - AnyNumber()).WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(4))))); - EXPECT_CALL(database, - get_entity(EntityId(4))).Times(AnyNumber()).WillRepeatedly(Return(existing_metatraffic_unicast_locator)); + // Precondition: The Participant does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)) + .Times(AnyNumber()) + .WillOnce(Throw(eprosima::statistics_backend::BadParameter("Error"))) + .WillRepeatedly(Return(std::pair(0, 10))); + EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) + .WillRepeatedly(Return(std::shared_ptr())); + + // Precondition: The Host does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::HOST, host_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The discovered reader contains the locator - data.metatraffic_locators.add_unicast_locator(dds_existing_metatraffic_unicast_locator); - - // Precondition: The Multicast Locator exists and has ID 5 - eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_multicast_locator.address[12] = 127; - dds_existing_multicast_locator.address[15] = 1; - std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); - std::shared_ptr existing_multicast_locator = - std::make_shared(existing_multicast_locator_name); - existing_multicast_locator->id = 5; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(5))))); - EXPECT_CALL(database, get_entity(EntityId(5))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_multicast_locator)); + // Precondition: The User does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::USER, user_name_)) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The discovered reader contains the locator - data.default_locators.add_multicast_locator(dds_existing_multicast_locator); - - // Precondition: The Multicast Metatraffic Locator exists and has ID 6 - eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_metatraffic_multicast_locator.address[12] = 127; - dds_existing_metatraffic_multicast_locator.address[15] = 1; - std::string existing_metatraffic_multicast_locator_name = to_string(dds_existing_metatraffic_multicast_locator); - std::shared_ptr existing_metatraffic_multicast_locator = - std::make_shared(existing_metatraffic_multicast_locator_name); - existing_metatraffic_multicast_locator->id = 6; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_multicast_locator_name)).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(6))))); - EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_metatraffic_multicast_locator)); + // Precondition: The Process does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::PROCESS, process_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: The discovered reader contains the locator - data.metatraffic_locators.add_multicast_locator(dds_existing_metatraffic_multicast_locator); + // Precondition: The Metatrafic Topic does not exist + EXPECT_CALL(database, + get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(0))); - // Precondition: There are 4 locators - EXPECT_CALL(database, - get_entities(EntityKind::LOCATOR, - EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(std::vector>({ - existing_unicast_locator, existing_metatraffic_unicast_locator, existing_multicast_locator, - existing_metatraffic_multicast_locator}))); + // Precondition: The Metatrafic Endpoint does not exist + EXPECT_CALL(database, + get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Expectation: The Participant is added to the database. We do not care about the given ID - InsertEntityArgs insert_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); - EXPECT_EQ(entity->name, "localhost:09.0a.0b.0c"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - participant_proxy_data_to_backend_qos(info.info)); + // Start building the discovered reader info + eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; + eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); - return EntityId(10); - }); + // Precondition: The discovered participant has the given GUID and name + data.m_guid = participant_guid_; + data.m_participantName = participant_name_; - // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID - InsertEntityArgs insert_topic_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::TOPIC); - EXPECT_EQ(entity->name, metatraffic_prefix + "TOPIC"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, metatraffic_prefix + "TYPE"); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_host, host_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_user, user_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_process, process_name_); - return EntityId(11); - }); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); + + // Precondition: The Unicast Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()).WillRepeatedly(Return( + std::vector>(1, std::make_pair( + EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()).WillRepeatedly(Return(existing_unicast_locator)); + + // Precondition: The discovered reader contains the locator + data.default_locators.add_unicast_locator(dds_existing_unicast_locator); + + // Precondition: The Unicast Metatraffic Locator exists and has ID 4 + eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_metatraffic_unicast_locator.address[12] = 127; + dds_existing_metatraffic_unicast_locator.address[15] = 1; + std::string existing_metatraffic_unicast_locator_name = to_string(dds_existing_metatraffic_unicast_locator); + std::shared_ptr existing_metatraffic_unicast_locator = + std::make_shared(existing_metatraffic_unicast_locator_name); + existing_metatraffic_unicast_locator->id = 4; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_unicast_locator_name)).Times( + AnyNumber()).WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(4))))); + EXPECT_CALL(database, + get_entity(EntityId(4))).Times(AnyNumber()).WillRepeatedly(Return(existing_metatraffic_unicast_locator)); + + // Precondition: The discovered reader contains the locator + data.metatraffic_locators.add_unicast_locator(dds_existing_metatraffic_unicast_locator); + + // Precondition: The Multicast Locator exists and has ID 5 + eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_multicast_locator.address[12] = 127; + dds_existing_multicast_locator.address[15] = 1; + std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); + std::shared_ptr existing_multicast_locator = + std::make_shared(existing_multicast_locator_name); + existing_multicast_locator->id = 5; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(5))))); + EXPECT_CALL(database, get_entity(EntityId(5))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_multicast_locator)); + + // Precondition: The discovered reader contains the locator + data.default_locators.add_multicast_locator(dds_existing_multicast_locator); + + // Precondition: The Multicast Metatraffic Locator exists and has ID 6 + eprosima::fastrtps::rtps::Locator_t dds_existing_metatraffic_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_metatraffic_multicast_locator.address[12] = 127; + dds_existing_metatraffic_multicast_locator.address[15] = 1; + std::string existing_metatraffic_multicast_locator_name = to_string(dds_existing_metatraffic_multicast_locator); + std::shared_ptr existing_metatraffic_multicast_locator = + std::make_shared(existing_metatraffic_multicast_locator_name); + existing_metatraffic_multicast_locator->id = 6; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_metatraffic_multicast_locator_name)).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(6))))); + EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_metatraffic_multicast_locator)); - // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID - InsertEntityArgs insert_datawriter_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); - EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + // Precondition: The discovered reader contains the locator + data.metatraffic_locators.add_multicast_locator(dds_existing_metatraffic_multicast_locator); - return EntityId(12); - }); + // Precondition: There are 4 locators + EXPECT_CALL(database, + get_entities(EntityKind::LOCATOR, + EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(std::vector>({ + existing_unicast_locator, existing_metatraffic_unicast_locator, existing_multicast_locator, + existing_metatraffic_multicast_locator}))); + + // Expectation: The Participant is added to the database. We do not care about the given ID + InsertEntityArgs insert_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PARTICIPANT); + EXPECT_EQ(entity->name, "localhost:09.0a.0b.0c"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + participant_proxy_data_to_backend_qos(info.info)); + + return EntityId(10); + }); + + // Expectation: The host is created and given ID 13 + InsertEntityArgs insert_args_host([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::HOST); + EXPECT_EQ(entity->name, host_name_); + EXPECT_EQ(entity->alias, host_name_); - EXPECT_CALL(database, insert(_)).Times(3) - .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + return EntityId(13); + }); - // Expectation: The Participant is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The user is created and given ID 14 + InsertEntityArgs insert_args_user([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::USER); + EXPECT_EQ(entity->name, user_name_); + EXPECT_EQ(entity->alias, user_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->host, insert_args_host.entity_); - // Expectation: The metatraffic endpoint change it status - EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + return EntityId(14); + }); - // Expectation: The metatraffic endpoint is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The process is created and given ID 15 + InsertEntityArgs insert_args_process([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::PROCESS); + EXPECT_EQ(entity->name, process_name_); + EXPECT_EQ(entity->alias, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->pid, process_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->user, insert_args_user.entity_); + + return EntityId(15); + }); + + // Expectation: The Metatraffic topic is added to the database. We do not care about the given ID + InsertEntityArgs insert_topic_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::TOPIC); + EXPECT_EQ(entity->name, metatraffic_prefix + "TOPIC"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, metatraffic_prefix + "TYPE"); - // Expectation: The topic is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::TOPIC, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + return EntityId(11); + }); - // Execution: Call the listener - info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; - participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + // Expectation: The Metatraffic endpoint is added to the database. We do not care about the given ID + InsertEntityArgs insert_datawriter_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); + EXPECT_EQ(entity->name, "DataWriter_" + metatraffic_prefix + "TOPIC_0.0.1.c1"); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, metatraffic_qos_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, participant_guid_str_); + + return EntityId(12); + }); + + EXPECT_CALL(database, insert(_)).Times(6) + .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_host, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_user, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_args_process, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_datawriter_args, &InsertEntityArgs::insert)); + + // Expectation: The link method is called with appropriate arguments + EXPECT_CALL(database, link_participant_with_process(EntityId(10), EntityId(15))).Times(1); + + // Expectation: Modify graph + EXPECT_CALL(database, update_participant_in_graph(EntityId(0),EntityId(13),EntityId(14),EntityId(15),EntityId(10))).Times(1).WillOnce(Return(true)); + + // Expectation: The Participant is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::PARTICIPANT, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Expectation: The metatraffic endpoint change it status + EXPECT_CALL(database, change_entity_status(EntityId(12), true)).Times(1); + + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(10),EntityId(11),EntityId(12))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(2); + + // Expectation: The metatraffic endpoint is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(12), EntityKind::DATAWRITER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Expectation: The topic is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::TOPIC, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener + info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; + participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); } TEST_F(statistics_participant_listener_tests, new_participant_no_domain) @@ -1595,1043 +2149,344 @@ TEST_F(statistics_participant_listener_tests, new_participant_no_domain) TEST_F(statistics_participant_listener_tests, new_participant_discovered_participant_already_exists) { - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); + + // Precondition: The Participant exists and has ID 5 + participant_->id = EntityId(5); + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(5)))); + EXPECT_CALL(database, get_entity(EntityId(5))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); + EXPECT_CALL(database, get_entities(EntityKind::PARTICIPANT, EntityId(5))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(5, participant_))); + + // Precondition: The Host exists + EXPECT_CALL(database, + get_entities_by_name(EntityKind::HOST, host_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, std::make_pair(EntityId(0), EntityId(13))))); + host_->id = EntityId(13); + EXPECT_CALL(database, get_entity(EntityId(13))).Times(AnyNumber()) + .WillRepeatedly(Return(host_)); - // Precondition: The Participant exists and has ID 5 - participant_->id = EntityId(5); - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(5)))); - EXPECT_CALL(database, get_entity(EntityId(5))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - EXPECT_CALL(database, get_entities(EntityKind::PARTICIPANT, EntityId(5))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(5, participant_))); + // Precondition: The User exists + EXPECT_CALL(database, + get_entities_by_name(EntityKind::USER, user_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, std::make_pair(EntityId(0), EntityId(14))))); + user_->id = EntityId(14); + EXPECT_CALL(database, get_entity(EntityId(14))).Times(AnyNumber()) + .WillRepeatedly(Return(user_)); - // Precondition: The Metatrafic Topic exists and has ID 6 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(6))))); - EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) - .WillRepeatedly(Return(metatraffic_topic_)); + // Precondition: The Process exists + EXPECT_CALL(database, + get_entities_by_name(EntityKind::PROCESS, process_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, std::make_pair(EntityId(0), EntityId(15))))); + process_->id = EntityId(15); + participant_->process = process_; + EXPECT_CALL(database, get_entity(EntityId(15))).Times(AnyNumber()) + .WillRepeatedly(Return(process_)); + + // Precondition: The Metatrafic Topic exists and has ID 6 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::TOPIC, metatraffic_prefix + "TOPIC")).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(6))))); + EXPECT_CALL(database, get_entity(EntityId(6))).Times(AnyNumber()) + .WillRepeatedly(Return(metatraffic_topic_)); - // Precondition: The Metatrafic Endpoint exists and has ID 7 - EXPECT_CALL(database, - get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(7)))); + // Precondition: The Metatrafic Endpoint exists and has ID 7 + EXPECT_CALL(database, + get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(7)))); - // Precondition: There are unicast locators in database - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:1")) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(1))))); - EXPECT_CALL(database, - get_entity(EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(metatraffic_unicast_locator)); + // Precondition: There are unicast locators in database + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:1")) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(1))))); + EXPECT_CALL(database, + get_entity(EntityId(1))).Times(AnyNumber()).WillRepeatedly(Return(metatraffic_unicast_locator)); - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:3")) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()).WillRepeatedly(Return(default_unicast_locator)); + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:3")) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()).WillRepeatedly(Return(default_unicast_locator)); - // Precondition: There are multicast locators in database - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:2")) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, - get_entity(EntityId(2))).Times(AnyNumber()).WillRepeatedly(Return(metatraffic_multicast_locator)); - - EXPECT_CALL(database, - get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:4")) - .Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(4))))); - EXPECT_CALL(database, get_entity(EntityId(4))).Times(AnyNumber()).WillRepeatedly(Return(default_multicast_locator)); - - // Start building the discovered reader info - eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; - eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); - - // Precondition: The discovered participant has the given GUID and name - data.m_guid = participant_guid_; - data.m_participantName = participant_name_; - - // Precondition: The discovered participant has unicast and multicast locators associated - data.metatraffic_locators.unicast.push_back(1); - data.metatraffic_locators.multicast.push_back(2); - data.default_locators.unicast.push_back(3); - data.default_locators.multicast.push_back(4); - - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); - - EXPECT_CALL(database, insert(_)).Times(0); - - // Expectation: The Participant status is set to active - EXPECT_CALL(database, change_entity_status(EntityId(7), true)).Times(1); - EXPECT_CALL(database, change_entity_status(EntityId(5), true)).Times(1); - - // Expectation: The Participant is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(5), EntityKind::PARTICIPANT, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - - // Expectation: The metatraffic endpoint is discovered - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(7), EntityKind::DATAWRITER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - - // Execution: Call the listener. - info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; - participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); -} - -TEST_F(statistics_participant_listener_tests, new_participant_undiscovered_participant_already_exists) -{ - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); - - // Precondition: The Participant exists and has ID 1 - participant_->id = EntityId(1); - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - - // Metatraffic endpoint - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - - // Start building the discovered reader info - eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; - eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); - - // Precondition: The discovered participant has the given GUID and name - data.m_guid = participant_guid_; - data.m_participantName = participant_name_; - - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); - - // Expectation: The Participant is not inserted in the database. - EXPECT_CALL(database, insert(_)).Times(0); - - // Expectation: The Participant status is set to inactive - EXPECT_CALL(database, change_entity_status(EntityId(1), false)).Times(2); - - // Expectation: The user listener is called - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(1), EntityKind::PARTICIPANT, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::UNDISCOVERY)).Times(2); - - // Execution: Call the listener. - info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::REMOVED_PARTICIPANT; - participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); - - info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DROPPED_PARTICIPANT; - participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); - - entity_queue.flush(); -} - -#endif // !defined(_WIN32) - -TEST_F(statistics_participant_listener_tests, new_reader_discovered) -{ - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); - - // Precondition: The Participant exists and has ID 1 - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - - // Precondition: The Participant is linked to a host with ID 50 - std::string host_name = "hostname"; - std::shared_ptr host = std::make_shared(host_name); - - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, host))); - EXPECT_CALL(database, get_entity(EntityId(50))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); - - // Precondition: The Topic exists and has ID 2 - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_)); - - // Precondition: The Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - - // Start building the discovered reader info - eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); - - // Precondition: The discovered reader is in the participant - data.guid(reader_guid_); - - // Precondition: The discovered reader is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); - - // Precondition: The discovered reader contains the locator - data.add_unicast_locator(dds_existing_unicast_locator); - - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); - - // Precondition: The Reader does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - - // Expectation: The DataReader is added to the database. We do not care about the given ID - InsertEntityArgs insert_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAREADER); - EXPECT_EQ(entity->name, std::string("DataReader_") + topic_->name + "_" + reader_entity_id_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, reader_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - reader_proxy_data_to_backend_qos(info.info)); - - std::vector expected_locator_names; - expected_locator_names.push_back(existing_unicast_locator_name); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), - expected_locator_names.size()); - for (auto loc : std::dynamic_pointer_cast(entity)->locators) - { - EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); - EXPECT_EQ(loc.second->id, existing_unicast_locator->id); - } - - return EntityId(10); - }); - - EXPECT_CALL(database, insert(_)).Times(1) - .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)); - - // Precondition: The reader change it status - EXPECT_CALL(database, change_entity_status(EntityId(10), true)).Times(1); - - // Expectation: The user listener is called - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::DATAREADER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - - // Execution: Call the listener - participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); -} - -TEST_F(statistics_participant_listener_tests, new_reader_undiscovered) -{ - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); - - // Precondition: The Participant exists and has ID 1 - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - - // Precondition: The Participant is linked to a host with ID 50 - std::string host_name = "hostname"; - std::shared_ptr host = std::make_shared(host_name); - - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, host))); - EXPECT_CALL(database, get_entity(EntityId(50))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); - - // Precondition: The Topic exists and has ID 2 - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_)); - - // Precondition: The Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - - // Start building the discovered reader info - eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); - - // Precondition: The discovered reader is in the participant - data.guid(reader_guid_); - - // Precondition: The discovered reader is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); - - // Precondition: The discovered reader contains the locator - data.add_unicast_locator(dds_existing_unicast_locator); - - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); - - // Precondition: The Reader does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - - // Expectation: The Datareader is not added to the database. - EXPECT_CALL(database, insert(_)).Times(0); - - // Precondition: The Datareader does not change it status - EXPECT_CALL(database, change_entity_status(_, _)).Times(0); - - // Execution: Call the listener - info.status = eprosima::fastrtps::rtps::ReaderDiscoveryInfo::REMOVED_READER; - participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); -} - -TEST_F(statistics_participant_listener_tests, new_reader_no_topic) -{ - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); - - // Precondition: The Participant exists and has ID 1 - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - - // Precondition: The Participant is linked to a host with ID 50 - std::string host_name = "hostname"; - std::shared_ptr host = std::make_shared(host_name); - - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, host))); - EXPECT_CALL(database, get_entity(EntityId(50))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); - - // Precondition: The Topic does not exist - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>())); - - // Precondition: The Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - - // Start building the discovered reader info - eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); - - // Precondition: The discovered reader is in the participant - data.guid(reader_guid_); - - // Precondition: The discovered reader is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); - - // Precondition: The discovered reader contains the locator - data.add_unicast_locator(dds_existing_unicast_locator); - - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); - - // Precondition: The Reader does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - - // Expectation: The Topic is added to the database. We do not care about the given ID - InsertEntityArgs insert_topic_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::TOPIC); - EXPECT_EQ(entity->name, topic_name_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->domain, domain_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, type_name_); - - return EntityId(10); - }); - - // Expectation: The DataReader is added to the database. We do not care about the given ID - InsertEntityArgs insert_reader_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAREADER); - EXPECT_EQ(entity->name, std::string("DataReader_") + topic_->name + "_" + reader_entity_id_str_); - - EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, reader_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - reader_proxy_data_to_backend_qos(info.info)); - - // We cannot check the Topic pointer as the queue will create a new one. - // We check the topic_ data instead - EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic->name, topic_name_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic->domain, domain_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic->data_type, type_name_); - - std::vector expected_locator_names; - expected_locator_names.push_back(existing_unicast_locator_name); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), - expected_locator_names.size()); - for (auto loc : std::dynamic_pointer_cast(entity)->locators) - { - EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); - EXPECT_EQ(loc.second->id, existing_unicast_locator->id); - } - - return EntityId(11); - }); - - EXPECT_CALL(database, insert(_)).Times(2) - .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_reader_args, &InsertEntityArgs::insert)); - - // Precondition: The reader change it status - EXPECT_CALL(database, change_entity_status(EntityId(11), true)).Times(1); - - // Expectation: The user listener is called - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::DATAREADER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::TOPIC, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - - // Execution: Call the listener - participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); -} - -TEST_F(statistics_participant_listener_tests, new_reader_several_topics) -{ - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); - - // Precondition: The Participant exists and has ID 1 - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - - // Precondition: The Participant is linked to a host with ID 50 - std::string host_name = "hostname"; - std::shared_ptr host = std::make_shared(host_name); - - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, host))); - EXPECT_CALL(database, get_entity(EntityId(50))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); - - // Precondition: Another domain with ID 100 exists - std::string another_domain_name = "another_domain"; - std::shared_ptr another_domain = std::make_shared(another_domain_name); - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, another_domain_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(100), EntityId(100))))); - EXPECT_CALL(database, get_entity(EntityId(100))).Times(AnyNumber()) - .WillRepeatedly(Return(another_domain)); - - // Precondition: Another topic with the same name and type exists in domain 100 - // and has ID 101 - std::shared_ptr topic_another_domain = std::make_shared(topic_name_, type_name_, another_domain); - EXPECT_CALL(database, get_entity(EntityId(101))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_another_domain)); - - // Precondition: Another topic with the same name but different type exists in the initial domain 0 - // and has ID 102 - std::string another_type_name = "another_type"; - std::shared_ptr topic_another_type = std::make_shared(topic_name_, another_type_name, domain_); - EXPECT_CALL(database, get_entity(EntityId(102))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_another_type)); - - // Precondition: The Topic exists and has ID 2 - EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_)); - - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector> - { { EntityId(100), EntityId(101) }, - { EntityId(0), EntityId(102) }, - { EntityId(0), EntityId(2) }})); + // Precondition: There are multicast locators in database + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:2")) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, + get_entity(EntityId(2))).Times(AnyNumber()).WillRepeatedly(Return(metatraffic_multicast_locator)); - // Precondition: The Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); + EXPECT_CALL(database, + get_entities_by_name(EntityKind::LOCATOR, "UDPv4:[0.0.0.0]:4")) + .Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(4))))); + EXPECT_CALL(database, get_entity(EntityId(4))).Times(AnyNumber()).WillRepeatedly(Return(default_multicast_locator)); - // Start building the discovered reader info - eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); + // Start building the discovered reader info + eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; + eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); - // Precondition: The discovered reader is in the participant - data.guid(reader_guid_); + // Precondition: The discovered participant has the given GUID and name + data.m_guid = participant_guid_; + data.m_participantName = participant_name_; - // Precondition: The discovered reader is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_host, host_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_user, user_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_process, process_name_); - // Precondition: The discovered reader contains the locator - data.add_unicast_locator(dds_existing_unicast_locator); + // Precondition: The discovered participant has unicast and multicast locators associated + data.metatraffic_locators.unicast.push_back(1); + data.metatraffic_locators.multicast.push_back(2); + data.default_locators.unicast.push_back(3); + data.default_locators.multicast.push_back(4); - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); - // Precondition: The Reader does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + EXPECT_CALL(database, insert(_)).Times(0); - // Expectation: The DataReader is added to the database. We do not care about the given ID - InsertEntityArgs insert_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAREADER); - EXPECT_EQ(entity->name, std::string("DataReader_") + topic_->name + "_" + reader_entity_id_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, reader_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - reader_proxy_data_to_backend_qos(info.info)); - - std::vector expected_locator_names; - expected_locator_names.push_back(existing_unicast_locator_name); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), - expected_locator_names.size()); - for (auto loc : std::dynamic_pointer_cast(entity)->locators) - { - EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); - EXPECT_EQ(loc.second->id, existing_unicast_locator->id); - } + // Expectation: The Participant status is set to active + EXPECT_CALL(database, change_entity_status(EntityId(7), true)).Times(1); + EXPECT_CALL(database, change_entity_status(EntityId(5), true)).Times(1); - return EntityId(10); - }); + // Expectation: Modify graph + EXPECT_CALL(database, update_participant_in_graph(EntityId(0),EntityId(13),EntityId(14),EntityId(15),EntityId(5))).Times(1).WillOnce(Return(true)); - EXPECT_CALL(database, insert(_)).Times(1) - .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)); + // Expectation: The Participant is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(5), EntityKind::PARTICIPANT, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - // Precondition: The reader change it status - EXPECT_CALL(database, change_entity_status(EntityId(10), true)).Times(1); + // Expectation: Modify graph and notify user + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(5),EntityId(6),EntityId(7))).Times(1).WillOnce(Return(false)); - // Expectation: The user listener is called - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::DATAREADER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The metatraffic endpoint is discovered + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(7), EntityKind::DATAWRITER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - // Execution: Call the listener - participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); -} + // Execution: Call the listener. + info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT; + participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); + } -TEST_F(statistics_participant_listener_tests, new_reader_several_locators) +TEST_F(statistics_participant_listener_tests, new_participant_undiscovered_participant_already_exists) { - std::vector> existing_locators; - int64_t next_entity_id = 100; - - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); - - // Precondition: The Participant exists and has ID 1 - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - - // Precondition: The Participant is linked to a host with ID 50 - std::string host_name = "hostname"; - std::shared_ptr host = std::make_shared(host_name); - - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, host))); - EXPECT_CALL(database, get_entity(EntityId(50))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); - - // Precondition: The Topic exists and has ID 2 - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_)); - - // Precondition: One unicast Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - existing_locators.push_back(existing_unicast_locator); - - // Precondition: One multicast Locator exists and has ID 4 - eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_multicast_locator.address[12] = 127; - dds_existing_multicast_locator.address[15] = 2; - std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); - std::shared_ptr existing_multicast_locator = - std::make_shared(existing_multicast_locator_name); - existing_multicast_locator->id = 4; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(4))))); - EXPECT_CALL(database, get_entity(EntityId(4))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_multicast_locator)); - existing_locators.push_back(existing_multicast_locator); - - // Precondition: One unicast Locator does not exist - eprosima::fastrtps::rtps::Locator_t dds_new_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_new_unicast_locator.address[12] = 127; - dds_new_unicast_locator.address[15] = 3; - std::string new_unicast_locator_name = to_string(dds_new_unicast_locator); - std::shared_ptr new_unicast_locator = - std::make_shared(new_unicast_locator_name); - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>())); - - // Precondition: One multicast Locator does not exist - eprosima::fastrtps::rtps::Locator_t dds_new_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_new_multicast_locator.address[12] = 127; - dds_new_multicast_locator.address[15] = 4; - std::string new_multicast_locator_name = to_string(dds_new_multicast_locator); - std::shared_ptr new_multicast_locator = - std::make_shared(new_multicast_locator_name); - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_multicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>())); - - // Precondition: Looking for the entities from the locator returns existing locators - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_locators)); - - // Precondition: The database returns EntityIDs that are not used before - database.set_next_entity_id(next_entity_id); - - // Start building the discovered reader info - eprosima::fastrtps::rtps::ReaderProxyData data(2, 2); - - // Precondition: The discovered reader is in the participant - data.guid(reader_guid_); - - // Precondition: The discovered reader is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); - - // Precondition: The discovered reader contains the locators - data.add_unicast_locator(dds_existing_unicast_locator); - data.add_unicast_locator(dds_new_unicast_locator); - data.add_multicast_locator(dds_existing_multicast_locator); - data.add_multicast_locator(dds_new_multicast_locator); - - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); - - // Precondition: The Reader does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - - // Precondition: The writer does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - - // Expectation: The new unicast locator is added to the database and given ID 100 - InsertEntityArgs insert_unicast_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::LOCATOR); - EXPECT_EQ(entity->name, new_unicast_locator_name); - - return EntityId(100); - }); - - // Expectation: The new multicast locator is added to the database and given ID 101 - InsertEntityArgs insert_multicast_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::LOCATOR); - EXPECT_EQ(entity->name, new_multicast_locator_name); - - return EntityId(101); - }); - - // Expectation: The DataWriter is added to the database and given ID 11 - InsertEntityArgs insert_reader_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAREADER); - EXPECT_EQ(entity->name, std::string("DataReader_") + topic_->name + "_" + reader_entity_id_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, reader_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - reader_proxy_data_to_backend_qos(info.info)); - - std::vector expected_locator_names; - expected_locator_names.push_back(existing_unicast_locator_name); - expected_locator_names.push_back(existing_multicast_locator_name); - expected_locator_names.push_back(new_unicast_locator_name); - expected_locator_names.push_back(new_multicast_locator_name); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), - expected_locator_names.size()); - for (auto loc : std::dynamic_pointer_cast(entity)->locators) - { - EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); - if (loc.second->name == existing_unicast_locator->name) - { - EXPECT_EQ(loc.second->id, existing_unicast_locator->id); - } - if (loc.second->name == existing_multicast_locator->name) - { - EXPECT_EQ(loc.second->id, existing_multicast_locator->id); - } - if (loc.second->name == new_unicast_locator->name) - { - EXPECT_GE(loc.second->id, next_entity_id); - } - if (loc.second->name == new_multicast_locator->name) - { - EXPECT_GE(loc.second->id, next_entity_id); - } - } - - return EntityId(11); - }); - - EXPECT_CALL(database, insert(_)).Times(3) - .WillOnce(Invoke(&insert_unicast_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_multicast_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_reader_args, &InsertEntityArgs::insert)); - - // Precondition: The reader change it status - EXPECT_CALL(database, change_entity_status(EntityId(11), true)).Times(1); - - // Expectation: The user listener is called - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_physical_entity_discovery(EntityId(100), EntityKind::LOCATOR, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_physical_entity_discovery(EntityId(101), EntityKind::LOCATOR, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::DATAREADER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Precondition: The Participant exists and has ID 1 + participant_->id = EntityId(1); + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); - // Execution: Call the listener - participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); -} + // Metatraffic endpoint + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); -TEST_F(statistics_participant_listener_tests, new_reader_several_locators_no_host) -{ - std::vector> existing_locators; - int64_t next_entity_id = 100; + // Precondition: The Host exists + EXPECT_CALL(database, + get_entities_by_name(EntityKind::HOST, host_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, std::make_pair(EntityId(0), EntityId(13))))); + host_->id = EntityId(13); + EXPECT_CALL(database, get_entity(EntityId(13))).Times(AnyNumber()) + .WillRepeatedly(Return(host_)); - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); + // Precondition: The User exists + EXPECT_CALL(database, + get_entities_by_name(EntityKind::USER, user_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, std::make_pair(EntityId(0), EntityId(14))))); + user_->id = EntityId(14); + EXPECT_CALL(database, get_entity(EntityId(14))).Times(AnyNumber()) + .WillRepeatedly(Return(user_)); - // Precondition: The Participant exists and has ID 1 - // Precondition: The Participant is NOT linked to any host - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>())); + // Precondition: The Process exists + EXPECT_CALL(database, + get_entities_by_name(EntityKind::PROCESS, process_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, std::make_pair(EntityId(0), EntityId(15))))); + process_->id = EntityId(15); + participant_->process = process_; + EXPECT_CALL(database, get_entity(EntityId(15))).Times(AnyNumber()) + .WillRepeatedly(Return(process_)); - // Precondition: The Topic exists and has ID 2 - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_)); + // Start building the discovered reader info + eprosima::fastrtps::rtps::RTPSParticipantAllocationAttributes allocation; + eprosima::fastrtps::rtps::ParticipantProxyData data(allocation); - // Precondition: One unicast Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - existing_locators.push_back(existing_unicast_locator); - - // Precondition: One multicast Locator exists and has ID 4 - eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_multicast_locator.address[12] = 127; - dds_existing_multicast_locator.address[15] = 2; - std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); - std::shared_ptr existing_multicast_locator = - std::make_shared(existing_multicast_locator_name); - existing_multicast_locator->id = 4; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(4))))); - EXPECT_CALL(database, get_entity(EntityId(4))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_multicast_locator)); - existing_locators.push_back(existing_multicast_locator); - - // Precondition: One unicast Locator does not exist - eprosima::fastrtps::rtps::Locator_t dds_new_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_new_unicast_locator.address[12] = 127; - dds_new_unicast_locator.address[15] = 3; - std::string new_unicast_locator_name = to_string(dds_new_unicast_locator); - std::shared_ptr new_unicast_locator = - std::make_shared(new_unicast_locator_name); - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>())); + // Precondition: The discovered participant has the given GUID and name + data.m_guid = participant_guid_; + data.m_participantName = participant_name_; - // Precondition: One multicast Locator does not exist - eprosima::fastrtps::rtps::Locator_t dds_new_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_new_multicast_locator.address[12] = 127; - dds_new_multicast_locator.address[15] = 4; - std::string new_multicast_locator_name = to_string(dds_new_multicast_locator); - std::shared_ptr new_multicast_locator = - std::make_shared(new_multicast_locator_name); - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_multicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>())); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_host, host_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_user, user_name_); + data.m_properties.push_back(eprosima::fastdds::dds::parameter_policy_physical_data_process, process_name_); - // Precondition: Looking for the entities from the locator returns existing locators - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_locators)); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ParticipantDiscoveryInfo info(data); - // Precondition: The database returns EntityIDs that are not used before - database.set_next_entity_id(next_entity_id); + // Expectation: The Participant is not inserted in the database. + EXPECT_CALL(database, insert(_)).Times(0); - // Start building the discovered reader info - eprosima::fastrtps::rtps::ReaderProxyData data(2, 2); + // Expectation: The Participant status is set to inactive + EXPECT_CALL(database, change_entity_status(EntityId(1), false)).Times(2); - // Precondition: The discovered reader is in the participant - data.guid(reader_guid_); + // Expectation: Modify graph and notify user + EXPECT_CALL(database, update_participant_in_graph(EntityId(0),EntityId(13),EntityId(14),EntityId(15),EntityId(1))).Times(2) + .WillOnce(Return(true)) + .WillOnce(Return(false)); - // Precondition: The discovered reader is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(1); - // Precondition: The discovered reader contains the locators - data.add_unicast_locator(dds_existing_unicast_locator); - data.add_unicast_locator(dds_new_unicast_locator); - data.add_multicast_locator(dds_existing_multicast_locator); - data.add_multicast_locator(dds_new_multicast_locator); + // Expectation: The user listener is called + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(1), EntityKind::PARTICIPANT, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::UNDISCOVERY)).Times(2); - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); + // Execution: Call the listener. + info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::REMOVED_PARTICIPANT; + participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); - // Precondition: The Reader does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + info.status = eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DROPPED_PARTICIPANT; + participant_listener.on_participant_discovery(&statistics_participant, std::move(info)); - // Precondition: The writer does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + entity_queue.flush(); +} - // Expectation: The new unicast locator is added to the database and given ID 100 - InsertEntityArgs insert_unicast_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::LOCATOR); - EXPECT_EQ(entity->name, new_unicast_locator_name); +#endif // !defined(_WIN32) - return EntityId(100); - }); +TEST_F(statistics_participant_listener_tests, new_reader_discovered) +{ + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); - // Expectation: The new multicast locator is added to the database and given ID 101 - InsertEntityArgs insert_multicast_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::LOCATOR); - EXPECT_EQ(entity->name, new_multicast_locator_name); + // Precondition: The Participant exists and has ID 1 + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); + + // Precondition: The Topic exists and has ID 2 + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_)); + + // Precondition: The Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - return EntityId(101); - }); + // Start building the discovered reader info + eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); - // Expectation: The DataWriter is added to the database and given ID 11 - InsertEntityArgs insert_reader_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAREADER); - EXPECT_EQ(entity->name, std::string("DataReader_") + topic_->name + "_" + reader_entity_id_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, reader_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - reader_proxy_data_to_backend_qos(info.info)); - - std::vector expected_locator_names; - expected_locator_names.push_back(existing_unicast_locator_name); - expected_locator_names.push_back(existing_multicast_locator_name); - expected_locator_names.push_back(new_unicast_locator_name); - expected_locator_names.push_back(new_multicast_locator_name); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), - expected_locator_names.size()); - for (auto loc : std::dynamic_pointer_cast(entity)->locators) + // Precondition: The discovered reader is in the participant + data.guid(reader_guid_); + + // Precondition: The discovered reader is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); + + // Precondition: The discovered reader contains the locator + data.add_unicast_locator(dds_existing_unicast_locator); + + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); + + // Precondition: The Reader does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + + // Expectation: The DataReader is added to the database. We do not care about the given ID + InsertEntityArgs insert_args([&]( + std::shared_ptr entity) { - EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); - if (loc.second->name == existing_unicast_locator->name) - { + EXPECT_EQ(entity->kind, EntityKind::DATAREADER); + EXPECT_EQ(entity->name, std::string("DataReader_") + topic_->name + "_" + reader_entity_id_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, reader_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + reader_proxy_data_to_backend_qos(info.info)); + + std::vector expected_locator_names; + expected_locator_names.push_back(existing_unicast_locator_name); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), + expected_locator_names.size()); + for (auto loc : std::dynamic_pointer_cast(entity)->locators) + { + EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); EXPECT_EQ(loc.second->id, existing_unicast_locator->id); - } - if (loc.second->name == existing_multicast_locator->name) - { - EXPECT_EQ(loc.second->id, existing_multicast_locator->id); - } - if (loc.second->name == new_unicast_locator->name) - { - EXPECT_GE(loc.second->id, next_entity_id); - } - if (loc.second->name == new_multicast_locator->name) - { - EXPECT_GE(loc.second->id, next_entity_id); - } - } - - return EntityId(11); - }); + } - EXPECT_CALL(database, insert(_)).Times(3) - .WillOnce(Invoke(&insert_unicast_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_multicast_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_reader_args, &InsertEntityArgs::insert)); + return EntityId(10); + }); - // Precondition: The reader change it status - EXPECT_CALL(database, change_entity_status(EntityId(11), true)).Times(1); + EXPECT_CALL(database, insert(_)).Times(1) + .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)); - // Expectation: The user listener is called - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_physical_entity_discovery(EntityId(100), EntityKind::LOCATOR, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Precondition: The reader change it status + EXPECT_CALL(database, change_entity_status(EntityId(10), true)).Times(1); - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_physical_entity_discovery(EntityId(101), EntityKind::LOCATOR, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: Modify graph and notify user + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(1),EntityId(2),EntityId(10))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(1); - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::DATAREADER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The user listener is called + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::DATAREADER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - // Execution: Call the listener - participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + // Execution: Call the listener + participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); } -TEST_F(statistics_participant_listener_tests, new_reader_no_participant) +TEST_F(statistics_participant_listener_tests, new_reader_undiscovered) { // Precondition: The Domain 0 exists and has ID 0 EXPECT_CALL(database, @@ -2642,9 +2497,11 @@ TEST_F(statistics_participant_listener_tests, new_reader_no_participant) EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) .WillRepeatedly(Return(domain_)); - // Precondition: The Participant does not exist + // Precondition: The Participant exists and has ID 1 EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); // Precondition: The Topic exists and has ID 2 EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) @@ -2689,371 +2546,692 @@ TEST_F(statistics_participant_listener_tests, new_reader_no_participant) EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Expectation: No entity is added to the database + // Expectation: The Datareader is not added to the database. EXPECT_CALL(database, insert(_)).Times(0); - // Expectation: Nothing is inserted - participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); -} - -TEST_F(statistics_participant_listener_tests, new_reader_no_domain) -{ - // Precondition: The Domain 0 does not exist - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>())); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - - // Precondition: The Participant does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - - // Precondition: The Topic does not exist - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>())); - - // Precondition: The Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - - // Start building the discovered reader info - eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); - - // Precondition: The discovered reader is in the participant - data.guid(reader_guid_); - - // Precondition: The discovered reader is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); - - // Precondition: The Reader does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - - // Precondition: The discovered reader contains the locator - data.add_unicast_locator(dds_existing_unicast_locator); - - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); - - // Expectation: No entity is added to the database - EXPECT_CALL(database, insert(_)).Times(0); + // Precondition: The Datareader does not change it status + EXPECT_CALL(database, change_entity_status(_, _)).Times(0); - // Expectation: Exception thrown + // Execution: Call the listener + info.status = eprosima::fastrtps::rtps::ReaderDiscoveryInfo::REMOVED_READER; participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); } -TEST_F(statistics_participant_listener_tests, new_reader_discovered_reader_already_exists) +TEST_F(statistics_participant_listener_tests, new_reader_no_topic) { - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); + + // Precondition: The Participant exists and has ID 1 + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); + + // Precondition: The Topic does not exist + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>())); + + // Precondition: The Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - // Precondition: The Participant exists and has ID 1 - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); + // Start building the discovered reader info + eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); - // Precondition: The Participant is linked to a host with ID 50 - std::string host_name = "hostname"; - std::shared_ptr host = std::make_shared(host_name); + // Precondition: The discovered reader is in the participant + data.guid(reader_guid_); - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, host))); - EXPECT_CALL(database, get_entity(EntityId(50))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); + // Precondition: The discovered reader is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); - // Precondition: The Topic exists and has ID 2 - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_)); + // Precondition: The discovered reader contains the locator + data.add_unicast_locator(dds_existing_unicast_locator); - // Precondition: The Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); - // Start building the discovered reader info - eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); + // Precondition: The Reader does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Precondition: The discovered reader is in the participant - data.guid(reader_guid_); + // Expectation: The Topic is added to the database. We do not care about the given ID + InsertEntityArgs insert_topic_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::TOPIC); + EXPECT_EQ(entity->name, topic_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->domain, domain_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, type_name_); - // Precondition: The discovered reader is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); + return EntityId(10); + }); - // Precondition: The discovered reader contains the locator - data.add_unicast_locator(dds_existing_unicast_locator); + // Expectation: The DataReader is added to the database. We do not care about the given ID + InsertEntityArgs insert_reader_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAREADER); + EXPECT_EQ(entity->name, std::string("DataReader_") + topic_->name + "_" + reader_entity_id_str_); + + EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, reader_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + reader_proxy_data_to_backend_qos(info.info)); + + // We cannot check the Topic pointer as the queue will create a new one. + // We check the topic_ data instead + EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic->name, topic_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic->domain, domain_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic->data_type, type_name_); + + std::vector expected_locator_names; + expected_locator_names.push_back(existing_unicast_locator_name); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), + expected_locator_names.size()); + for (auto loc : std::dynamic_pointer_cast(entity)->locators) + { + EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); + EXPECT_EQ(loc.second->id, existing_unicast_locator->id); + } - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); + return EntityId(11); + }); - // Precondition: The Reader exists and has ID 10 - std::shared_ptr reader = - std::make_shared(reader_guid_str_, reader_proxy_data_to_backend_qos( - info.info), reader_guid_str_, participant_, topic_); - reader->id = 10; - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(10)))); - EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) - .WillRepeatedly(Return(reader)); + EXPECT_CALL(database, insert(_)).Times(2) + .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_reader_args, &InsertEntityArgs::insert)); - // Expectation: The DataReader is not inserted in the database. - EXPECT_CALL(database, insert(_)).Times(0); + // Precondition: The reader change it status + EXPECT_CALL(database, change_entity_status(EntityId(11), true)).Times(1); - // Expectation: The DataReader status is set to active - EXPECT_CALL(database, change_entity_status(EntityId(10), true)).Times(1); + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(1),EntityId(10),EntityId(11))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(1); - // Expectation: The user listener is called - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::DATAREADER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The user listener is called + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::DATAREADER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - // Execution: Call the listener. - participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::TOPIC, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener + participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); } -TEST_F(statistics_participant_listener_tests, new_reader_undiscovered_reader_already_exists) +TEST_F(statistics_participant_listener_tests, new_reader_several_topics) { - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); + + // Precondition: The Participant exists and has ID 1 + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); + + // Precondition: Another domain with ID 100 exists + std::string another_domain_name = "another_domain"; + std::shared_ptr another_domain = std::make_shared(another_domain_name); + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, another_domain_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(100), EntityId(100))))); + EXPECT_CALL(database, get_entity(EntityId(100))).Times(AnyNumber()) + .WillRepeatedly(Return(another_domain)); + + // Precondition: Another topic with the same name and type exists in domain 100 + // and has ID 101 + std::shared_ptr topic_another_domain = std::make_shared(topic_name_, type_name_, another_domain); + EXPECT_CALL(database, get_entity(EntityId(101))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_another_domain)); + + // Precondition: Another topic with the same name but different type exists in the initial domain 0 + // and has ID 102 + std::string another_type_name = "another_type"; + std::shared_ptr topic_another_type = std::make_shared(topic_name_, another_type_name, domain_); + EXPECT_CALL(database, get_entity(EntityId(102))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_another_type)); + + // Precondition: The Topic exists and has ID 2 + EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_)); + + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector> + { { EntityId(100), EntityId(101) }, + { EntityId(0), EntityId(102) }, + { EntityId(0), EntityId(2) }})); + + // Precondition: The Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - // Precondition: The Participant exists and has ID 1 - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); + // Start building the discovered reader info + eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); - // Precondition: The Participant is linked to a host with ID 50 - std::string host_name = "hostname"; - std::shared_ptr host = std::make_shared(host_name); + // Precondition: The discovered reader is in the participant + data.guid(reader_guid_); - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, host))); - EXPECT_CALL(database, get_entity(EntityId(50))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); + // Precondition: The discovered reader is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); - // Precondition: The Topic exists and has ID 2 - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_)); + // Precondition: The discovered reader contains the locator + data.add_unicast_locator(dds_existing_unicast_locator); - // Precondition: The Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); - // Start building the discovered reader info - eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); + // Precondition: The Reader does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Precondition: The discovered reader is in the participant - data.guid(reader_guid_); + // Expectation: The DataReader is added to the database. We do not care about the given ID + InsertEntityArgs insert_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAREADER); + EXPECT_EQ(entity->name, std::string("DataReader_") + topic_->name + "_" + reader_entity_id_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, reader_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + reader_proxy_data_to_backend_qos(info.info)); + + std::vector expected_locator_names; + expected_locator_names.push_back(existing_unicast_locator_name); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), + expected_locator_names.size()); + for (auto loc : std::dynamic_pointer_cast(entity)->locators) + { + EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); + EXPECT_EQ(loc.second->id, existing_unicast_locator->id); + } - // Precondition: The discovered reader is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); + return EntityId(10); + }); - // Precondition: The discovered reader contains the locator - data.add_unicast_locator(dds_existing_unicast_locator); + EXPECT_CALL(database, insert(_)).Times(1) + .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)); - // Finish building the discovered reader info - eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); + // Precondition: The reader change it status + EXPECT_CALL(database, change_entity_status(EntityId(10), true)).Times(1); - // Precondition: The Reader exists and has ID 10 - std::shared_ptr reader = - std::make_shared(reader_guid_str_, reader_proxy_data_to_backend_qos( - info.info), reader_guid_str_, participant_, topic_); - reader->id = 10; - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(10)))); - EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) - .WillRepeatedly(Return(reader)); + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(1),EntityId(2),EntityId(10))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(1); - // Expectation: The DataReader is not inserted in the database. - EXPECT_CALL(database, insert(_)).Times(0); + // Expectation: The user listener is called + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::DATAREADER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener + participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); +} + +TEST_F(statistics_participant_listener_tests, new_reader_several_locators) +{ + std::vector> existing_locators; + int64_t next_entity_id = 100; - // Expectation: The DataReader status is set to inactive - EXPECT_CALL(database, change_entity_status(EntityId(10), false)).Times(1); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); - // Expectation: The user listener is called - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::DATAREADER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::UNDISCOVERY)).Times(1); + // Precondition: The Participant exists and has ID 1 + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); - // Execution: Call the listener. - info.status = eprosima::fastrtps::rtps::ReaderDiscoveryInfo::REMOVED_READER; - participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); + // Precondition: The Topic exists and has ID 2 + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_)); + + // Precondition: One unicast Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + existing_locators.push_back(existing_unicast_locator); + + // Precondition: One multicast Locator exists and has ID 4 + eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_multicast_locator.address[12] = 127; + dds_existing_multicast_locator.address[15] = 2; + std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); + std::shared_ptr existing_multicast_locator = + std::make_shared(existing_multicast_locator_name); + existing_multicast_locator->id = 4; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(4))))); + EXPECT_CALL(database, get_entity(EntityId(4))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_multicast_locator)); + existing_locators.push_back(existing_multicast_locator); + + // Precondition: One unicast Locator does not exist + eprosima::fastrtps::rtps::Locator_t dds_new_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_new_unicast_locator.address[12] = 127; + dds_new_unicast_locator.address[15] = 3; + std::string new_unicast_locator_name = to_string(dds_new_unicast_locator); + std::shared_ptr new_unicast_locator = + std::make_shared(new_unicast_locator_name); + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>())); + + // Precondition: One multicast Locator does not exist + eprosima::fastrtps::rtps::Locator_t dds_new_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_new_multicast_locator.address[12] = 127; + dds_new_multicast_locator.address[15] = 4; + std::string new_multicast_locator_name = to_string(dds_new_multicast_locator); + std::shared_ptr new_multicast_locator = + std::make_shared(new_multicast_locator_name); + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_multicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>())); + + // Precondition: Looking for the entities from the locator returns existing locators + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_locators)); + + // Precondition: The database returns EntityIDs that are not used before + database.set_next_entity_id(next_entity_id); + + // Start building the discovered reader info + eprosima::fastrtps::rtps::ReaderProxyData data(2, 2); + + // Precondition: The discovered reader is in the participant + data.guid(reader_guid_); + + // Precondition: The discovered reader is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); + + // Precondition: The discovered reader contains the locators + data.add_unicast_locator(dds_existing_unicast_locator); + data.add_unicast_locator(dds_new_unicast_locator); + data.add_multicast_locator(dds_existing_multicast_locator); + data.add_multicast_locator(dds_new_multicast_locator); - entity_queue.flush(); -} + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); -TEST_F(statistics_participant_listener_tests, new_writer_discovered) -{ - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); + // Precondition: The Reader does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Precondition: The Participant exists and has ID 1 - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); + // Precondition: The writer does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Precondition: The Participant is linked to a host with ID 50 - std::string host_name = "hostname"; - std::shared_ptr host = std::make_shared(host_name); + // Expectation: The new unicast locator is added to the database and given ID 100 + InsertEntityArgs insert_unicast_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::LOCATOR); + EXPECT_EQ(entity->name, new_unicast_locator_name); - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, host))); - EXPECT_CALL(database, get_entity(EntityId(50))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); + return EntityId(100); + }); - // Precondition: The Topic exists and has ID 2 - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_)); + // Expectation: The new multicast locator is added to the database and given ID 101 + InsertEntityArgs insert_multicast_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::LOCATOR); + EXPECT_EQ(entity->name, new_multicast_locator_name); - // Precondition: The Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); + return EntityId(101); + }); - // Start building the discovered writer info - eprosima::fastrtps::rtps::WriterProxyData data(1, 1); + // Expectation: The DataWriter is added to the database and given ID 11 + InsertEntityArgs insert_reader_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAREADER); + EXPECT_EQ(entity->name, std::string("DataReader_") + topic_->name + "_" + reader_entity_id_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, reader_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + reader_proxy_data_to_backend_qos(info.info)); + + std::vector expected_locator_names; + expected_locator_names.push_back(existing_unicast_locator_name); + expected_locator_names.push_back(existing_multicast_locator_name); + expected_locator_names.push_back(new_unicast_locator_name); + expected_locator_names.push_back(new_multicast_locator_name); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), + expected_locator_names.size()); + for (auto loc : std::dynamic_pointer_cast(entity)->locators) + { + EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); + if (loc.second->name == existing_unicast_locator->name) + { + EXPECT_EQ(loc.second->id, existing_unicast_locator->id); + } + if (loc.second->name == existing_multicast_locator->name) + { + EXPECT_EQ(loc.second->id, existing_multicast_locator->id); + } + if (loc.second->name == new_unicast_locator->name) + { + EXPECT_GE(loc.second->id, next_entity_id); + } + if (loc.second->name == new_multicast_locator->name) + { + EXPECT_GE(loc.second->id, next_entity_id); + } + } + + return EntityId(11); + }); + + EXPECT_CALL(database, insert(_)).Times(3) + .WillOnce(Invoke(&insert_unicast_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_multicast_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_reader_args, &InsertEntityArgs::insert)); + + // Precondition: The reader change it status + EXPECT_CALL(database, change_entity_status(EntityId(11), true)).Times(1); + + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(1),EntityId(2),EntityId(11))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(1); + + // Expectation: The user listener is called + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_physical_entity_discovery(EntityId(100), EntityKind::LOCATOR, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_physical_entity_discovery(EntityId(101), EntityKind::LOCATOR, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::DATAREADER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener + participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); +} - // Precondition: The discovered writer is in the participant - data.guid(writer_guid_); +TEST_F(statistics_participant_listener_tests, new_reader_several_locators_no_host) +{ + std::vector> existing_locators; + int64_t next_entity_id = 100; - // Precondition: The discovered writer is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); + + // Precondition: The Participant exists and has ID 1 + // Precondition: The Participant is NOT linked to any host + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); + EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>())); + + // Precondition: The Topic exists and has ID 2 + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_)); + + // Precondition: One unicast Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + existing_locators.push_back(existing_unicast_locator); + + // Precondition: One multicast Locator exists and has ID 4 + eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_multicast_locator.address[12] = 127; + dds_existing_multicast_locator.address[15] = 2; + std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); + std::shared_ptr existing_multicast_locator = + std::make_shared(existing_multicast_locator_name); + existing_multicast_locator->id = 4; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(4))))); + EXPECT_CALL(database, get_entity(EntityId(4))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_multicast_locator)); + existing_locators.push_back(existing_multicast_locator); + + // Precondition: One unicast Locator does not exist + eprosima::fastrtps::rtps::Locator_t dds_new_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_new_unicast_locator.address[12] = 127; + dds_new_unicast_locator.address[15] = 3; + std::string new_unicast_locator_name = to_string(dds_new_unicast_locator); + std::shared_ptr new_unicast_locator = + std::make_shared(new_unicast_locator_name); + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>())); + + // Precondition: One multicast Locator does not exist + eprosima::fastrtps::rtps::Locator_t dds_new_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_new_multicast_locator.address[12] = 127; + dds_new_multicast_locator.address[15] = 4; + std::string new_multicast_locator_name = to_string(dds_new_multicast_locator); + std::shared_ptr new_multicast_locator = + std::make_shared(new_multicast_locator_name); + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_multicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>())); + + // Precondition: Looking for the entities from the locator returns existing locators + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_locators)); + + // Precondition: The database returns EntityIDs that are not used before + database.set_next_entity_id(next_entity_id); + + // Start building the discovered reader info + eprosima::fastrtps::rtps::ReaderProxyData data(2, 2); + + // Precondition: The discovered reader is in the participant + data.guid(reader_guid_); + + // Precondition: The discovered reader is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); + + // Precondition: The discovered reader contains the locators + data.add_unicast_locator(dds_existing_unicast_locator); + data.add_unicast_locator(dds_new_unicast_locator); + data.add_multicast_locator(dds_existing_multicast_locator); + data.add_multicast_locator(dds_new_multicast_locator); - // Precondition: The discovered writer contains the locator - data.add_unicast_locator(dds_existing_unicast_locator); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); - // Finish building the discovered writer info - eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); + // Precondition: The Reader does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Precondition: The writer does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + // Precondition: The writer does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Expectation: The DataWriter is added to the database. We do not care about the given ID - InsertEntityArgs insert_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); - EXPECT_EQ(entity->name, std::string("DataWriter_") + topic_->name + "_" + writer_entity_id_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, writer_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - writer_proxy_data_to_backend_qos(info.info)); - - std::vector expected_locator_names; - expected_locator_names.push_back(existing_unicast_locator_name); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), - expected_locator_names.size()); - for (auto loc : std::dynamic_pointer_cast(entity)->locators) + // Expectation: The new unicast locator is added to the database and given ID 100 + InsertEntityArgs insert_unicast_args([&]( + std::shared_ptr entity) { - EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); - EXPECT_EQ(loc.second->id, existing_unicast_locator->id); - } - - return EntityId(10); - }); + EXPECT_EQ(entity->kind, EntityKind::LOCATOR); + EXPECT_EQ(entity->name, new_unicast_locator_name); - EXPECT_CALL(database, insert(_)).Times(1) - .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)); + return EntityId(100); + }); - // Precondition: The writer change it status - EXPECT_CALL(database, change_entity_status(EntityId(10), true)).Times(1); + // Expectation: The new multicast locator is added to the database and given ID 101 + InsertEntityArgs insert_multicast_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::LOCATOR); + EXPECT_EQ(entity->name, new_multicast_locator_name); - // Expectation: The user listener is called - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::DATAWRITER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + return EntityId(101); + }); - // Execution: Call the listener - participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); + // Expectation: The DataWriter is added to the database and given ID 11 + InsertEntityArgs insert_reader_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAREADER); + EXPECT_EQ(entity->name, std::string("DataReader_") + topic_->name + "_" + reader_entity_id_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, reader_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + reader_proxy_data_to_backend_qos(info.info)); + + std::vector expected_locator_names; + expected_locator_names.push_back(existing_unicast_locator_name); + expected_locator_names.push_back(existing_multicast_locator_name); + expected_locator_names.push_back(new_unicast_locator_name); + expected_locator_names.push_back(new_multicast_locator_name); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), + expected_locator_names.size()); + for (auto loc : std::dynamic_pointer_cast(entity)->locators) + { + EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); + if (loc.second->name == existing_unicast_locator->name) + { + EXPECT_EQ(loc.second->id, existing_unicast_locator->id); + } + if (loc.second->name == existing_multicast_locator->name) + { + EXPECT_EQ(loc.second->id, existing_multicast_locator->id); + } + if (loc.second->name == new_unicast_locator->name) + { + EXPECT_GE(loc.second->id, next_entity_id); + } + if (loc.second->name == new_multicast_locator->name) + { + EXPECT_GE(loc.second->id, next_entity_id); + } + } + + return EntityId(11); + }); + + EXPECT_CALL(database, insert(_)).Times(3) + .WillOnce(Invoke(&insert_unicast_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_multicast_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_reader_args, &InsertEntityArgs::insert)); + + // Precondition: The reader change it status + EXPECT_CALL(database, change_entity_status(EntityId(11), true)).Times(1); + + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(1),EntityId(2),EntityId(11))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(1); + + // Expectation: The user listener is called + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_physical_entity_discovery(EntityId(100), EntityKind::LOCATOR, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_physical_entity_discovery(EntityId(101), EntityKind::LOCATOR, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::DATAREADER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener + participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); } -TEST_F(statistics_participant_listener_tests, new_writer_undiscovered) +TEST_F(statistics_participant_listener_tests, new_reader_no_participant) { // Precondition: The Domain 0 exists and has ID 0 EXPECT_CALL(database, @@ -3064,20 +3242,9 @@ TEST_F(statistics_participant_listener_tests, new_writer_undiscovered) EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) .WillRepeatedly(Return(domain_)); - // Precondition: The Participant exists and has ID 1 + // Precondition: The Participant does not exist EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - - // Precondition: The Participant is linked to a host with ID 50 - std::string host_name = "hostname"; - std::shared_ptr host = std::make_shared(host_name); - - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, host))); - EXPECT_CALL(database, get_entity(EntityId(50))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); // Precondition: The Topic exists and has ID 2 EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) @@ -3102,62 +3269,46 @@ TEST_F(statistics_participant_listener_tests, new_writer_undiscovered) EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - // Start building the discovered writer info - eprosima::fastrtps::rtps::WriterProxyData data(1, 1); + // Start building the discovered reader info + eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); - // Precondition: The discovered writer is in the participant - data.guid(writer_guid_); + // Precondition: The discovered reader is in the participant + data.guid(reader_guid_); - // Precondition: The discovered writer is in the topic + // Precondition: The discovered reader is in the topic data.topicName(topic_name_); data.typeName(type_name_); - // Precondition: The discovered writer contains the locator + // Precondition: The discovered reader contains the locator data.add_unicast_locator(dds_existing_unicast_locator); - // Finish building the discovered writer info - eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); - // Precondition: The writer does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) + // Precondition: The Reader does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Expectation: The writer is not added to the database. + // Expectation: No entity is added to the database EXPECT_CALL(database, insert(_)).Times(0); - // Precondition: The writer does not change it status - EXPECT_CALL(database, change_entity_status(_, _)).Times(0); - - // Execution: Call the listener - info.status = eprosima::fastrtps::rtps::WriterDiscoveryInfo::REMOVED_WRITER; - participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); + // Expectation: Nothing is inserted + participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); } -TEST_F(statistics_participant_listener_tests, new_writer_no_topic) +TEST_F(statistics_participant_listener_tests, new_reader_no_domain) { - // Precondition: The Domain 0 exists and has ID 0 + // Precondition: The Domain 0 does not exist EXPECT_CALL(database, get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); + .WillRepeatedly(Return(std::vector>())); EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Precondition: The Participant exists and has ID 1 + // Precondition: The Participant does not exist EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - - // Precondition: The Participant is linked to a host with ID 50 - std::string host_name = "hostname"; - std::shared_ptr host = std::make_shared(host_name); - - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, host))); - EXPECT_CALL(database, get_entity(EntityId(50))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); // Precondition: The Topic does not exist EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) @@ -3179,504 +3330,920 @@ TEST_F(statistics_participant_listener_tests, new_writer_no_topic) EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - // Start building the discovered writer info - eprosima::fastrtps::rtps::WriterProxyData data(1, 1); + // Start building the discovered reader info + eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); - // Precondition: The discovered writer is in the participant - data.guid(writer_guid_); + // Precondition: The discovered reader is in the participant + data.guid(reader_guid_); - // Precondition: The discovered writer is in the topic + // Precondition: The discovered reader is in the topic data.topicName(topic_name_); data.typeName(type_name_); - // Precondition: The discovered writer contains the locator + // Precondition: The Reader does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + + // Precondition: The discovered reader contains the locator data.add_unicast_locator(dds_existing_unicast_locator); - // Finish building the discovered writer info - eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); - // Precondition: The writer does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + // Expectation: No entity is added to the database + EXPECT_CALL(database, insert(_)).Times(0); - // Expectation: The Topic is added to the database. We do not care about the given ID - InsertEntityArgs insert_topic_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::TOPIC); - EXPECT_EQ(entity->name, topic_name_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->domain, domain_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, type_name_); + // Expectation: Exception thrown + participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); +} - return EntityId(10); - }); +TEST_F(statistics_participant_listener_tests, new_reader_discovered_reader_already_exists) +{ + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); - // Expectation: The DataWriter is added to the database. We do not care about the given ID - InsertEntityArgs insert_writer_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); - EXPECT_EQ(entity->name, std::string("DataWriter_") + topic_->name + "_" + writer_entity_id_str_); - - EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, writer_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - writer_proxy_data_to_backend_qos(info.info)); - - // We cannot check the Topic pointer as the queue will create a new one. - // We check the topic_ data instead - EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic->name, topic_name_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic->domain, domain_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic->data_type, type_name_); - - std::vector expected_locator_names; - expected_locator_names.push_back(existing_unicast_locator_name); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), - expected_locator_names.size()); - for (auto loc : std::dynamic_pointer_cast(entity)->locators) - { - EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); - EXPECT_EQ(loc.second->id, existing_unicast_locator->id); - } + // Precondition: The Participant exists and has ID 1 + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); - return EntityId(11); - }); + // Precondition: The Topic exists and has ID 2 + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_)); + + // Precondition: The Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - EXPECT_CALL(database, insert(_)).Times(2) - .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_writer_args, &InsertEntityArgs::insert)); + // Start building the discovered reader info + eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); - // Precondition: The writer change it status - EXPECT_CALL(database, change_entity_status(EntityId(11), true)).Times(1); + // Precondition: The discovered reader is in the participant + data.guid(reader_guid_); - // Expectation: The user listener is called - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::TOPIC, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Precondition: The discovered reader is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::DATAWRITER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Precondition: The discovered reader contains the locator + data.add_unicast_locator(dds_existing_unicast_locator); - // Execution: Call the listener - participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); + + // Precondition: The Reader exists and has ID 10 + std::shared_ptr reader = + std::make_shared(reader_guid_str_, reader_proxy_data_to_backend_qos( + info.info), reader_guid_str_, participant_, topic_); + reader->id = 10; + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(10)))); + EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) + .WillRepeatedly(Return(reader)); + + // Expectation: The DataReader is not inserted in the database. + EXPECT_CALL(database, insert(_)).Times(0); + + // Expectation: The DataReader status is set to active + EXPECT_CALL(database, change_entity_status(EntityId(10), true)).Times(1); + + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(1),EntityId(2),EntityId(10))).Times(1).WillOnce(Return(false)); + + // Expectation: The user listener is called + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::DATAREADER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener. + participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); } -TEST_F(statistics_participant_listener_tests, new_writer_several_locators - ) +TEST_F(statistics_participant_listener_tests, new_reader_undiscovered_reader_already_exists) { - std::vector> existing_locators; - int64_t next_entity_id = 100; + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); + // Precondition: The Participant exists and has ID 1 + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); - // Precondition: The Participant exists and has ID 1 - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); + // Precondition: The Topic exists and has ID 2 + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_)); + + // Precondition: The Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - // Precondition: The Participant is linked to a host with ID 50 - std::string host_name = "hostname"; - std::shared_ptr host = std::make_shared(host_name); + // Start building the discovered reader info + eprosima::fastrtps::rtps::ReaderProxyData data(1, 1); - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, host))); - EXPECT_CALL(database, get_entity(EntityId(50))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); + // Precondition: The discovered reader is in the participant + data.guid(reader_guid_); - // Precondition: The Topic exists and has ID 2 - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_)); + // Precondition: The discovered reader is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); - // Precondition: One unicast Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - existing_locators.push_back(existing_unicast_locator); - - // Precondition: One multicast Locator exists and has ID 4 - eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_multicast_locator.address[12] = 127; - dds_existing_multicast_locator.address[15] = 2; - std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); - std::shared_ptr existing_multicast_locator = - std::make_shared(existing_multicast_locator_name); - existing_multicast_locator->id = 4; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(4))))); - EXPECT_CALL(database, get_entity(EntityId(4))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_multicast_locator)); - existing_locators.push_back(existing_multicast_locator); - - // Precondition: One unicast Locator does not exist - eprosima::fastrtps::rtps::Locator_t dds_new_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_new_unicast_locator.address[12] = 127; - dds_new_unicast_locator.address[15] = 3; - std::string new_unicast_locator_name = to_string(dds_new_unicast_locator); - std::shared_ptr new_unicast_locator = - std::make_shared(new_unicast_locator_name); - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>())); + // Precondition: The discovered reader contains the locator + data.add_unicast_locator(dds_existing_unicast_locator); - // Precondition: One multicast Locator does not exist - eprosima::fastrtps::rtps::Locator_t dds_new_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_new_multicast_locator.address[12] = 127; - dds_new_multicast_locator.address[15] = 4; - std::string new_multicast_locator_name = to_string(dds_new_multicast_locator); - std::shared_ptr new_multicast_locator = - std::make_shared(new_multicast_locator_name); - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_multicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>())); + // Finish building the discovered reader info + eprosima::fastrtps::rtps::ReaderDiscoveryInfo info(data); + + // Precondition: The Reader exists and has ID 10 + std::shared_ptr reader = + std::make_shared(reader_guid_str_, reader_proxy_data_to_backend_qos( + info.info), reader_guid_str_, participant_, topic_); + reader->id = 10; + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAREADER, reader_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(10)))); + EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) + .WillRepeatedly(Return(reader)); + + // Expectation: The DataReader is not inserted in the database. + EXPECT_CALL(database, insert(_)).Times(0); + + // Expectation: The DataReader status is set to inactive + EXPECT_CALL(database, change_entity_status(EntityId(10), false)).Times(1); + + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(1),EntityId(2),EntityId(10))).Times(1).WillOnce(Return(false)); + + // Expectation: The user listener is called + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::DATAREADER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::UNDISCOVERY)).Times(1); + + // Execution: Call the listener. + info.status = eprosima::fastrtps::rtps::ReaderDiscoveryInfo::REMOVED_READER; + participant_listener.on_subscriber_discovery(&statistics_participant, std::move(info)); + + entity_queue.flush(); +} - // Precondition: Looking for the entities from the locator returns existing locators - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_locators)); +TEST_F(statistics_participant_listener_tests, new_writer_discovered) +{ + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); - // Precondition: The database returns EntityIDs that are not used before - database.set_next_entity_id(next_entity_id); + // Precondition: The Participant exists and has ID 1 + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); - // Start building the discovered writer info - eprosima::fastrtps::rtps::WriterProxyData data(2, 2); + // Precondition: The Topic exists and has ID 2 + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_)); + + // Precondition: The Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - // Precondition: The discovered writer is in the participant - data.guid(writer_guid_); + // Start building the discovered writer info + eprosima::fastrtps::rtps::WriterProxyData data(1, 1); - // Precondition: The discovered writer is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); + // Precondition: The discovered writer is in the participant + data.guid(writer_guid_); - // Precondition: The discovered writer contains the locators - data.add_unicast_locator(dds_existing_unicast_locator); - data.add_unicast_locator(dds_new_unicast_locator); - data.add_multicast_locator(dds_existing_multicast_locator); - data.add_multicast_locator(dds_new_multicast_locator); + // Precondition: The discovered writer is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); - // Finish building the discovered writer info - eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); + // Precondition: The discovered writer contains the locator + data.add_unicast_locator(dds_existing_unicast_locator); + + // Finish building the discovered writer info + eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); + + // Precondition: The writer does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + + // Expectation: The DataWriter is added to the database. We do not care about the given ID + InsertEntityArgs insert_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); + EXPECT_EQ(entity->name, std::string("DataWriter_") + topic_->name + "_" + writer_entity_id_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, writer_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + writer_proxy_data_to_backend_qos(info.info)); + + std::vector expected_locator_names; + expected_locator_names.push_back(existing_unicast_locator_name); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), + expected_locator_names.size()); + for (auto loc : std::dynamic_pointer_cast(entity)->locators) + { + EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); + EXPECT_EQ(loc.second->id, existing_unicast_locator->id); + } + + return EntityId(10); + }); + + EXPECT_CALL(database, insert(_)).Times(1) + .WillOnce(Invoke(&insert_args, &InsertEntityArgs::insert)); + + // Precondition: The writer change it status + EXPECT_CALL(database, change_entity_status(EntityId(10), true)).Times(1); - // Precondition: The writer does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + // Expectation: Modify graph and notify user + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(1),EntityId(2),EntityId(10))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(1); - // Precondition: The writer does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + // Expectation: The user listener is called + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::DATAWRITER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - // Expectation: The new unicast locator is added to the database and given ID 100 - InsertEntityArgs insert_unicast_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::LOCATOR); - EXPECT_EQ(entity->name, new_unicast_locator_name); + // Execution: Call the listener + participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); +} - return EntityId(100); - }); +TEST_F(statistics_participant_listener_tests, new_writer_undiscovered) +{ + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); - // Expectation: The new multicast locator is added to the database and given ID 101 - InsertEntityArgs insert_multicast_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::LOCATOR); - EXPECT_EQ(entity->name, new_multicast_locator_name); + // Precondition: The Participant exists and has ID 1 + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); + + // Precondition: The Topic exists and has ID 2 + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_)); + + // Precondition: The Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - return EntityId(101); - }); + // Start building the discovered writer info + eprosima::fastrtps::rtps::WriterProxyData data(1, 1); - // Expectation: The DataWriter is added to the database and given ID 11 - InsertEntityArgs insert_writer_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); - EXPECT_EQ(entity->name, std::string("DataWriter_") + topic_->name + "_" + writer_entity_id_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, writer_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - writer_proxy_data_to_backend_qos(info.info)); - - std::vector expected_locator_names; - expected_locator_names.push_back(existing_unicast_locator_name); - expected_locator_names.push_back(existing_multicast_locator_name); - expected_locator_names.push_back(new_unicast_locator_name); - expected_locator_names.push_back(new_multicast_locator_name); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), - expected_locator_names.size()); - for (auto loc : std::dynamic_pointer_cast(entity)->locators) - { - EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); - if (loc.second->name == existing_unicast_locator->name) - { - EXPECT_EQ(loc.second->id, existing_unicast_locator->id); - } - if (loc.second->name == existing_multicast_locator->name) - { - EXPECT_EQ(loc.second->id, existing_multicast_locator->id); - } - if (loc.second->name == new_unicast_locator->name) - { - EXPECT_GE(loc.second->id, next_entity_id); - } - if (loc.second->name == new_multicast_locator->name) - { - EXPECT_GE(loc.second->id, next_entity_id); - } - } + // Precondition: The discovered writer is in the participant + data.guid(writer_guid_); - return EntityId(11); - }); + // Precondition: The discovered writer is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); - EXPECT_CALL(database, insert(_)).Times(3) - .WillOnce(Invoke(&insert_unicast_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_multicast_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_writer_args, &InsertEntityArgs::insert)); + // Precondition: The discovered writer contains the locator + data.add_unicast_locator(dds_existing_unicast_locator); - // Precondition: The writer change it status - EXPECT_CALL(database, change_entity_status(EntityId(11), true)).Times(1); + // Finish building the discovered writer info + eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); - // Expectation: The user listener is called - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_physical_entity_discovery( EntityId(100), EntityKind::LOCATOR, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Precondition: The writer does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_physical_entity_discovery(EntityId(101), EntityKind::LOCATOR, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The writer is not added to the database. + EXPECT_CALL(database, insert(_)).Times(0); - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::DATAWRITER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Precondition: The writer does not change it status + EXPECT_CALL(database, change_entity_status(_, _)).Times(0); - // Execution: Call the listener - participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + // Execution: Call the listener + info.status = eprosima::fastrtps::rtps::WriterDiscoveryInfo::REMOVED_WRITER; + participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); } -TEST_F(statistics_participant_listener_tests, new_writer_several_locators_no_host) +TEST_F(statistics_participant_listener_tests, new_writer_no_topic) { - std::vector> existing_locators; - int64_t next_entity_id = 100; + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); + + // Precondition: The Participant exists and has ID 1 + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); + + // Precondition: The Topic does not exist + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>())); + + // Precondition: The Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); + // Start building the discovered writer info + eprosima::fastrtps::rtps::WriterProxyData data(1, 1); - // Precondition: The Participant exists and has ID 1 - // Precondition: The Participant is NOT linked to any host - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>())); + // Precondition: The discovered writer is in the participant + data.guid(writer_guid_); - // Precondition: The Topic exists and has ID 2 - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_)); + // Precondition: The discovered writer is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); - // Precondition: One unicast Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - existing_locators.push_back(existing_unicast_locator); - - // Precondition: One multicast Locator exists and has ID 4 - eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_multicast_locator.address[12] = 127; - dds_existing_multicast_locator.address[15] = 2; - std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); - std::shared_ptr existing_multicast_locator = - std::make_shared(existing_multicast_locator_name); - existing_multicast_locator->id = 4; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(4))))); - EXPECT_CALL(database, get_entity(EntityId(4))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_multicast_locator)); - existing_locators.push_back(existing_multicast_locator); - - // Precondition: One unicast Locator does not exist - eprosima::fastrtps::rtps::Locator_t dds_new_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_new_unicast_locator.address[12] = 127; - dds_new_unicast_locator.address[15] = 3; - std::string new_unicast_locator_name = to_string(dds_new_unicast_locator); - std::shared_ptr new_unicast_locator = - std::make_shared(new_unicast_locator_name); - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>())); + // Precondition: The discovered writer contains the locator + data.add_unicast_locator(dds_existing_unicast_locator); - // Precondition: One multicast Locator does not exist - eprosima::fastrtps::rtps::Locator_t dds_new_multicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_new_multicast_locator.address[12] = 127; - dds_new_multicast_locator.address[15] = 4; - std::string new_multicast_locator_name = to_string(dds_new_multicast_locator); - std::shared_ptr new_multicast_locator = - std::make_shared(new_multicast_locator_name); - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_multicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>())); + // Finish building the discovered writer info + eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); - // Precondition: Looking for the entities from the locator returns existing locators - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_locators)); + // Precondition: The writer does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); - // Precondition: The database returns EntityIDs that are not used before - database.set_next_entity_id(next_entity_id); + // Expectation: The Topic is added to the database. We do not care about the given ID + InsertEntityArgs insert_topic_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::TOPIC); + EXPECT_EQ(entity->name, topic_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->domain, domain_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->data_type, type_name_); - // Start building the discovered writer info - eprosima::fastrtps::rtps::WriterProxyData data(2, 2); + return EntityId(10); + }); - // Precondition: The discovered writer is in the participant - data.guid(writer_guid_); + // Expectation: The DataWriter is added to the database. We do not care about the given ID + InsertEntityArgs insert_writer_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); + EXPECT_EQ(entity->name, std::string("DataWriter_") + topic_->name + "_" + writer_entity_id_str_); + + EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, writer_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + writer_proxy_data_to_backend_qos(info.info)); + + // We cannot check the Topic pointer as the queue will create a new one. + // We check the topic_ data instead + EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic->name, topic_name_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic->domain, domain_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic->data_type, type_name_); + + std::vector expected_locator_names; + expected_locator_names.push_back(existing_unicast_locator_name); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), + expected_locator_names.size()); + for (auto loc : std::dynamic_pointer_cast(entity)->locators) + { + EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); + EXPECT_EQ(loc.second->id, existing_unicast_locator->id); + } - // Precondition: The discovered writer is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); + return EntityId(11); + }); - // Precondition: The discovered writer contains the locators - data.add_unicast_locator(dds_existing_unicast_locator); - data.add_unicast_locator(dds_new_unicast_locator); - data.add_multicast_locator(dds_existing_multicast_locator); - data.add_multicast_locator(dds_new_multicast_locator); + EXPECT_CALL(database, insert(_)).Times(2) + .WillOnce(Invoke(&insert_topic_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_writer_args, &InsertEntityArgs::insert)); - // Finish building the discovered writer info - eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); + // Precondition: The writer change it status + EXPECT_CALL(database, change_entity_status(EntityId(11), true)).Times(1); - // Precondition: The writer does not exist - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(1),EntityId(10),EntityId(11))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(1); - // Expectation: The new unicast locator is added to the database and given ID 100 - InsertEntityArgs insert_unicast_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::LOCATOR); - EXPECT_EQ(entity->name, new_unicast_locator_name); + // Expectation: The user listener is called + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::TOPIC, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - return EntityId(100); - }); + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::DATAWRITER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - // Expectation: The new multicast locator is added to the database and given ID 101 - InsertEntityArgs insert_multicast_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::LOCATOR); - EXPECT_EQ(entity->name, new_multicast_locator_name); + // Execution: Call the listener + participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); +} - return EntityId(101); - }); +TEST_F(statistics_participant_listener_tests, new_writer_several_locators) +{ + std::vector> existing_locators; + int64_t next_entity_id = 100; - // Expectation: The DataWriter is added to the database and given ID 11 - InsertEntityArgs insert_writer_args([&]( - std::shared_ptr entity) - { - EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); - EXPECT_EQ(entity->name, std::string("DataWriter_") + topic_->name + "_" + writer_entity_id_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, writer_guid_str_); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, - writer_proxy_data_to_backend_qos(info.info)); - - std::vector expected_locator_names; - expected_locator_names.push_back(existing_unicast_locator_name); - expected_locator_names.push_back(existing_multicast_locator_name); - expected_locator_names.push_back(new_unicast_locator_name); - expected_locator_names.push_back(new_multicast_locator_name); - EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), - expected_locator_names.size()); - for (auto loc : std::dynamic_pointer_cast(entity)->locators) + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); + + // Precondition: The Participant exists and has ID 1 + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); + + // Precondition: The Topic exists and has ID 2 + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_)); + + // Precondition: One unicast Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + existing_locators.push_back(existing_unicast_locator); + + // Precondition: One multicast Locator exists and has ID 4 + eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_multicast_locator.address[12] = 127; + dds_existing_multicast_locator.address[15] = 2; + std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); + std::shared_ptr existing_multicast_locator = + std::make_shared(existing_multicast_locator_name); + existing_multicast_locator->id = 4; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(4))))); + EXPECT_CALL(database, get_entity(EntityId(4))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_multicast_locator)); + existing_locators.push_back(existing_multicast_locator); + + // Precondition: One unicast Locator does not exist + eprosima::fastrtps::rtps::Locator_t dds_new_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_new_unicast_locator.address[12] = 127; + dds_new_unicast_locator.address[15] = 3; + std::string new_unicast_locator_name = to_string(dds_new_unicast_locator); + std::shared_ptr new_unicast_locator = + std::make_shared(new_unicast_locator_name); + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>())); + + // Precondition: One multicast Locator does not exist + eprosima::fastrtps::rtps::Locator_t dds_new_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_new_multicast_locator.address[12] = 127; + dds_new_multicast_locator.address[15] = 4; + std::string new_multicast_locator_name = to_string(dds_new_multicast_locator); + std::shared_ptr new_multicast_locator = + std::make_shared(new_multicast_locator_name); + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_multicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>())); + + // Precondition: Looking for the entities from the locator returns existing locators + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_locators)); + + // Precondition: The database returns EntityIDs that are not used before + database.set_next_entity_id(next_entity_id); + + // Start building the discovered writer info + eprosima::fastrtps::rtps::WriterProxyData data(2, 2); + + // Precondition: The discovered writer is in the participant + data.guid(writer_guid_); + + // Precondition: The discovered writer is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); + + // Precondition: The discovered writer contains the locators + data.add_unicast_locator(dds_existing_unicast_locator); + data.add_unicast_locator(dds_new_unicast_locator); + data.add_multicast_locator(dds_existing_multicast_locator); + data.add_multicast_locator(dds_new_multicast_locator); + + // Finish building the discovered writer info + eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); + + // Precondition: The writer does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + + // Precondition: The writer does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + + // Expectation: The new unicast locator is added to the database and given ID 100 + InsertEntityArgs insert_unicast_args([&]( + std::shared_ptr entity) { - EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); - if (loc.second->name == existing_unicast_locator->name) - { - EXPECT_EQ(loc.second->id, existing_unicast_locator->id); - } - if (loc.second->name == existing_multicast_locator->name) - { - EXPECT_EQ(loc.second->id, existing_multicast_locator->id); - } - if (loc.second->name == new_unicast_locator->name) - { - EXPECT_GE(loc.second->id, next_entity_id); - } - if (loc.second->name == new_multicast_locator->name) - { - EXPECT_GE(loc.second->id, next_entity_id); - } - } + EXPECT_EQ(entity->kind, EntityKind::LOCATOR); + EXPECT_EQ(entity->name, new_unicast_locator_name); - return EntityId(11); - }); + return EntityId(100); + }); - EXPECT_CALL(database, insert(_)).Times(3) - .WillOnce(Invoke(&insert_unicast_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_multicast_args, &InsertEntityArgs::insert)) - .WillOnce(Invoke(&insert_writer_args, &InsertEntityArgs::insert)); + // Expectation: The new multicast locator is added to the database and given ID 101 + InsertEntityArgs insert_multicast_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::LOCATOR); + EXPECT_EQ(entity->name, new_multicast_locator_name); - // Precondition: The writer change it status - EXPECT_CALL(database, change_entity_status(EntityId(11), true)).Times(1); + return EntityId(101); + }); - // Expectation: The user listener is called - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_physical_entity_discovery(EntityId(100), EntityKind::LOCATOR, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Expectation: The DataWriter is added to the database and given ID 11 + InsertEntityArgs insert_writer_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); + EXPECT_EQ(entity->name, std::string("DataWriter_") + topic_->name + "_" + writer_entity_id_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, writer_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + writer_proxy_data_to_backend_qos(info.info)); + + std::vector expected_locator_names; + expected_locator_names.push_back(existing_unicast_locator_name); + expected_locator_names.push_back(existing_multicast_locator_name); + expected_locator_names.push_back(new_unicast_locator_name); + expected_locator_names.push_back(new_multicast_locator_name); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), + expected_locator_names.size()); + for (auto loc : std::dynamic_pointer_cast(entity)->locators) + { + EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); + if (loc.second->name == existing_unicast_locator->name) + { + EXPECT_EQ(loc.second->id, existing_unicast_locator->id); + } + if (loc.second->name == existing_multicast_locator->name) + { + EXPECT_EQ(loc.second->id, existing_multicast_locator->id); + } + if (loc.second->name == new_unicast_locator->name) + { + EXPECT_GE(loc.second->id, next_entity_id); + } + if (loc.second->name == new_multicast_locator->name) + { + EXPECT_GE(loc.second->id, next_entity_id); + } + } + + return EntityId(11); + }); + + EXPECT_CALL(database, insert(_)).Times(3) + .WillOnce(Invoke(&insert_unicast_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_multicast_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_writer_args, &InsertEntityArgs::insert)); + + // Precondition: The writer change it status + EXPECT_CALL(database, change_entity_status(EntityId(11), true)).Times(1); + + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(1),EntityId(2),EntityId(11))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(1); + + // Expectation: The user listener is called + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_physical_entity_discovery( EntityId(100), EntityKind::LOCATOR, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_physical_entity_discovery(EntityId(101), EntityKind::LOCATOR, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::DATAWRITER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener + participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); +} - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_physical_entity_discovery(EntityId(101), EntityKind::LOCATOR, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); +TEST_F(statistics_participant_listener_tests, new_writer_several_locators_no_host) +{ + std::vector> existing_locators; + int64_t next_entity_id = 100; - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::DATAWRITER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); + + // Precondition: The Participant exists and has ID 1 + // Precondition: The Participant is NOT linked to any host + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); + EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>())); + + // Precondition: The Topic exists and has ID 2 + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_)); + + // Precondition: One unicast Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + existing_locators.push_back(existing_unicast_locator); + + // Precondition: One multicast Locator exists and has ID 4 + eprosima::fastrtps::rtps::Locator_t dds_existing_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_multicast_locator.address[12] = 127; + dds_existing_multicast_locator.address[15] = 2; + std::string existing_multicast_locator_name = to_string(dds_existing_multicast_locator); + std::shared_ptr existing_multicast_locator = + std::make_shared(existing_multicast_locator_name); + existing_multicast_locator->id = 4; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_multicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(4))))); + EXPECT_CALL(database, get_entity(EntityId(4))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_multicast_locator)); + existing_locators.push_back(existing_multicast_locator); + + // Precondition: One unicast Locator does not exist + eprosima::fastrtps::rtps::Locator_t dds_new_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_new_unicast_locator.address[12] = 127; + dds_new_unicast_locator.address[15] = 3; + std::string new_unicast_locator_name = to_string(dds_new_unicast_locator); + std::shared_ptr new_unicast_locator = + std::make_shared(new_unicast_locator_name); + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>())); + + // Precondition: One multicast Locator does not exist + eprosima::fastrtps::rtps::Locator_t dds_new_multicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_new_multicast_locator.address[12] = 127; + dds_new_multicast_locator.address[15] = 4; + std::string new_multicast_locator_name = to_string(dds_new_multicast_locator); + std::shared_ptr new_multicast_locator = + std::make_shared(new_multicast_locator_name); + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, new_multicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>())); + + // Precondition: Looking for the entities from the locator returns existing locators + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_locators)); + + // Precondition: The database returns EntityIDs that are not used before + database.set_next_entity_id(next_entity_id); + + // Start building the discovered writer info + eprosima::fastrtps::rtps::WriterProxyData data(2, 2); + + // Precondition: The discovered writer is in the participant + data.guid(writer_guid_); + + // Precondition: The discovered writer is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); + + // Precondition: The discovered writer contains the locators + data.add_unicast_locator(dds_existing_unicast_locator); + data.add_unicast_locator(dds_new_unicast_locator); + data.add_multicast_locator(dds_existing_multicast_locator); + data.add_multicast_locator(dds_new_multicast_locator); + + // Finish building the discovered writer info + eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); + + // Precondition: The writer does not exist + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Throw(eprosima::statistics_backend::BadParameter("Error"))); + + // Expectation: The new unicast locator is added to the database and given ID 100 + InsertEntityArgs insert_unicast_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::LOCATOR); + EXPECT_EQ(entity->name, new_unicast_locator_name); - // Execution: Call the listener - participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + return EntityId(100); + }); + + // Expectation: The new multicast locator is added to the database and given ID 101 + InsertEntityArgs insert_multicast_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::LOCATOR); + EXPECT_EQ(entity->name, new_multicast_locator_name); + + return EntityId(101); + }); + + // Expectation: The DataWriter is added to the database and given ID 11 + InsertEntityArgs insert_writer_args([&]( + std::shared_ptr entity) + { + EXPECT_EQ(entity->kind, EntityKind::DATAWRITER); + EXPECT_EQ(entity->name, std::string("DataWriter_") + topic_->name + "_" + writer_entity_id_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->topic, topic_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->participant, participant_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->guid, writer_guid_str_); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->qos, + writer_proxy_data_to_backend_qos(info.info)); + + std::vector expected_locator_names; + expected_locator_names.push_back(existing_unicast_locator_name); + expected_locator_names.push_back(existing_multicast_locator_name); + expected_locator_names.push_back(new_unicast_locator_name); + expected_locator_names.push_back(new_multicast_locator_name); + EXPECT_EQ(std::dynamic_pointer_cast(entity)->locators.size(), + expected_locator_names.size()); + for (auto loc : std::dynamic_pointer_cast(entity)->locators) + { + EXPECT_THAT(expected_locator_names, Contains(loc.second->name)); + if (loc.second->name == existing_unicast_locator->name) + { + EXPECT_EQ(loc.second->id, existing_unicast_locator->id); + } + if (loc.second->name == existing_multicast_locator->name) + { + EXPECT_EQ(loc.second->id, existing_multicast_locator->id); + } + if (loc.second->name == new_unicast_locator->name) + { + EXPECT_GE(loc.second->id, next_entity_id); + } + if (loc.second->name == new_multicast_locator->name) + { + EXPECT_GE(loc.second->id, next_entity_id); + } + } + + return EntityId(11); + }); + + EXPECT_CALL(database, insert(_)).Times(3) + .WillOnce(Invoke(&insert_unicast_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_multicast_args, &InsertEntityArgs::insert)) + .WillOnce(Invoke(&insert_writer_args, &InsertEntityArgs::insert)); + + // Precondition: The writer change it status + EXPECT_CALL(database, change_entity_status(EntityId(11), true)).Times(1); + + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(1),EntityId(2),EntityId(11))).Times(1).WillOnce(Return(true)); + EXPECT_CALL(*eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_graph_update(EntityId(0))).Times(1); + + // Expectation: The user listener is called + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_physical_entity_discovery(EntityId(100), EntityKind::LOCATOR, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_physical_entity_discovery(EntityId(101), EntityKind::LOCATOR, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(11), EntityKind::DATAWRITER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); + + // Execution: Call the listener + participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); } TEST_F(statistics_participant_listener_tests, new_writer_no_participant) @@ -3809,186 +4376,174 @@ TEST_F(statistics_participant_listener_tests, new_writer_no_domain) TEST_F(statistics_participant_listener_tests, new_writer_discovered_writer_already_exists) { // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); - - // Precondition: The Participant exists and has ID 1 - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - - // Precondition: The Participant is linked to a host with ID 50 - std::string host_name = "hostname"; - std::shared_ptr host = std::make_shared(host_name); - - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, host))); - EXPECT_CALL(database, get_entity(EntityId(50))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); - // Precondition: The Topic exists and has ID 2 - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_)); + // Precondition: The Participant exists and has ID 1 + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); - // Precondition: The Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); + // Precondition: The Topic exists and has ID 2 + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_)); + + // Precondition: The Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - // Start building the discovered writer info - eprosima::fastrtps::rtps::WriterProxyData data(1, 1); + // Start building the discovered writer info + eprosima::fastrtps::rtps::WriterProxyData data(1, 1); - // Precondition: The discovered writer is in the participant - data.guid(writer_guid_); + // Precondition: The discovered writer is in the participant + data.guid(writer_guid_); - // Precondition: The discovered writer is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); + // Precondition: The discovered writer is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); - // Precondition: The discovered writer contains the locator - data.add_unicast_locator(dds_existing_unicast_locator); + // Precondition: The discovered writer contains the locator + data.add_unicast_locator(dds_existing_unicast_locator); - // Finish building the discovered writer info - eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); + // Finish building the discovered writer info + eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); - // Precondition: The writer exists and has ID 10 - std::shared_ptr writer = - std::make_shared(writer_guid_str_, writer_proxy_data_to_backend_qos( + // Precondition: The writer exists and has ID 10 + std::shared_ptr writer = + std::make_shared(writer_guid_str_, writer_proxy_data_to_backend_qos( info.info), writer_guid_str_, participant_, topic_); - writer->id = EntityId(10); - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(10)))); - EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) - .WillRepeatedly(Return(writer)); + writer->id = EntityId(10); + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(10)))); + EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) + .WillRepeatedly(Return(writer)); - // Expectation: The DataWriter is not inserted in the database. - EXPECT_CALL(database, insert(_)).Times(0); + // Expectation: The DataWriter is not inserted in the database. + EXPECT_CALL(database, insert(_)).Times(0); - // Expectation: The DataWriter status is set to active - EXPECT_CALL(database, change_entity_status(EntityId(10), true)).Times(1); + // Expectation: The DataWriter status is set to active + EXPECT_CALL(database, change_entity_status(EntityId(10), true)).Times(1); - // Expectation: The user listener is called - EXPECT_CALL( + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(1),EntityId(2),EntityId(10))).Times(1).WillOnce(Return(false)); + + // Expectation: The user listener is called + EXPECT_CALL( *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::DATAWRITER, eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::DISCOVERY)).Times(1); - // Execution: Call the listener. - participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + // Execution: Call the listener. + participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); } TEST_F(statistics_participant_listener_tests, new_writer_undiscovered_writer_already_exists) { - // Precondition: The Domain 0 exists and has ID 0 - EXPECT_CALL(database, - get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( - AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(0))))); - EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) - .WillRepeatedly(Return(domain_)); - - // Precondition: The Participant exists and has ID 1 - EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(participant_)); - - // Precondition: The Participant is linked to a host with ID 50 - std::string host_name = "hostname"; - std::shared_ptr host = std::make_shared(host_name); - - EXPECT_CALL(database, get_entities(EntityKind::HOST, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, host))); - EXPECT_CALL(database, get_entity(EntityId(50))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); - - // Precondition: The Topic exists and has ID 2 - EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) - .WillRepeatedly(Return(topic_)); - - // Precondition: The Locator exists and has ID 3 - eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); - dds_existing_unicast_locator.address[12] = 127; - dds_existing_unicast_locator.address[15] = 1; - std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); - std::shared_ptr existing_unicast_locator = - std::make_shared(existing_unicast_locator_name); - existing_unicast_locator->id = 3; - EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(), EntityId(3))))); - EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(existing_unicast_locator)); - EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); - - // Start building the discovered writer info - eprosima::fastrtps::rtps::WriterProxyData data(1, 1); - - // Precondition: The discovered writer is in the participant - data.guid(writer_guid_); - - // Precondition: The discovered writer is in the topic - data.topicName(topic_name_); - data.typeName(type_name_); - - // Precondition: The discovered writer contains the locator - data.add_unicast_locator(dds_existing_unicast_locator); - - // Finish building the discovered writer info - eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); - - // Precondition: The writer exists and has ID 10 - std::shared_ptr writer = - std::make_shared(writer_guid_str_, writer_proxy_data_to_backend_qos( - info.info), writer_guid_str_, participant_, topic_); - writer->id = EntityId(10); - EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(10)))); - EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) - .WillRepeatedly(Return(writer)); - - // Expectation: The DataWriter is not inserted in the database. - EXPECT_CALL(database, insert(_)).Times(0); - - // Expectation: The DataWriter status is set to active - EXPECT_CALL(database, change_entity_status(EntityId(10), false)).Times(1); + // Precondition: The Domain 0 exists and has ID 0 + EXPECT_CALL(database, + get_entities_by_name(EntityKind::DOMAIN, std::to_string(statistics_participant.domain_id_))).Times( + AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(0))))); + EXPECT_CALL(database, get_entity(EntityId(0))).Times(AnyNumber()) + .WillRepeatedly(Return(domain_)); - // Expectation: The user listener is called - EXPECT_CALL( - *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), - on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::DATAWRITER, - eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::UNDISCOVERY)).Times(1); + // Precondition: The Participant exists and has ID 1 + EXPECT_CALL(database, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); + EXPECT_CALL(database, get_entity(EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(participant_)); - // Execution: Call the listener. - info.status = eprosima::fastrtps::rtps::WriterDiscoveryInfo::REMOVED_WRITER; - participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); - entity_queue.flush(); + // Precondition: The Topic exists and has ID 2 + EXPECT_CALL(database, get_entities_by_name(EntityKind::TOPIC, topic_name_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(0), EntityId(2))))); + EXPECT_CALL(database, get_entity(EntityId(2))).Times(AnyNumber()) + .WillRepeatedly(Return(topic_)); + + // Precondition: The Locator exists and has ID 3 + eprosima::fastrtps::rtps::Locator_t dds_existing_unicast_locator(LOCATOR_KIND_UDPv4, 1024); + dds_existing_unicast_locator.address[12] = 127; + dds_existing_unicast_locator.address[15] = 1; + std::string existing_unicast_locator_name = to_string(dds_existing_unicast_locator); + std::shared_ptr existing_unicast_locator = + std::make_shared(existing_unicast_locator_name); + existing_unicast_locator->id = 3; + EXPECT_CALL(database, get_entities_by_name(EntityKind::LOCATOR, existing_unicast_locator_name)).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, + std::make_pair(EntityId(), EntityId(3))))); + EXPECT_CALL(database, get_entity(EntityId(3))).Times(AnyNumber()) + .WillRepeatedly(Return(existing_unicast_locator)); + EXPECT_CALL(database, get_entities(EntityKind::LOCATOR, EntityId(1))).Times(AnyNumber()) + .WillRepeatedly(Return(std::vector>(1, existing_unicast_locator))); + + // Start building the discovered writer info + eprosima::fastrtps::rtps::WriterProxyData data(1, 1); + + // Precondition: The discovered writer is in the participant + data.guid(writer_guid_); + + // Precondition: The discovered writer is in the topic + data.topicName(topic_name_); + data.typeName(type_name_); + + // Precondition: The discovered writer contains the locator + data.add_unicast_locator(dds_existing_unicast_locator); + + // Finish building the discovered writer info + eprosima::fastrtps::rtps::WriterDiscoveryInfo info(data); + + // Precondition: The writer exists and has ID 10 + std::shared_ptr writer = + std::make_shared(writer_guid_str_, writer_proxy_data_to_backend_qos( + info.info), writer_guid_str_, participant_, topic_); + writer->id = EntityId(10); + EXPECT_CALL(database, get_entity_by_guid(EntityKind::DATAWRITER, writer_guid_str_)).Times(AnyNumber()) + .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(10)))); + EXPECT_CALL(database, get_entity(EntityId(10))).Times(AnyNumber()) + .WillRepeatedly(Return(writer)); + + // Expectation: The DataWriter is not inserted in the database. + EXPECT_CALL(database, insert(_)).Times(0); + + // Expectation: The DataWriter status is set to active + EXPECT_CALL(database, change_entity_status(EntityId(10), false)).Times(1); + + // Expectation: Modify graph and notify user (twice, also from participant update) + EXPECT_CALL(database, update_endpoint_in_graph(EntityId(0),EntityId(1),EntityId(2),EntityId(10))).Times(1).WillOnce(Return(false)); + + // Expectation: The user listener is called + EXPECT_CALL( + *eprosima::statistics_backend::details::StatisticsBackendData::get_instance(), + on_domain_entity_discovery(EntityId(0), EntityId(10), EntityKind::DATAWRITER, + eprosima::statistics_backend::details::StatisticsBackendData::DiscoveryStatus::UNDISCOVERY)).Times(1); + + // Execution: Call the listener. + info.status = eprosima::fastrtps::rtps::WriterDiscoveryInfo::REMOVED_WRITER; + participant_listener.on_publisher_discovery(&statistics_participant, std::move(info)); + entity_queue.flush(); } int main( diff --git a/test/unittest/StatisticsReaderListener/CMakeLists.txt b/test/unittest/StatisticsReaderListener/CMakeLists.txt index 8a900440b..ac9d8fd98 100644 --- a/test/unittest/StatisticsReaderListener/CMakeLists.txt +++ b/test/unittest/StatisticsReaderListener/CMakeLists.txt @@ -68,7 +68,6 @@ if(GTEST_FOUND AND GMOCK_FOUND) new_edp_count_received new_discovery_times_received new_sample_datas_received - new_physical_data_received ) foreach(test_name ${STATISTICSDATALISTENER_TEST_LIST}) diff --git a/test/unittest/StatisticsReaderListener/StatisticsReaderListenerTests.cpp b/test/unittest/StatisticsReaderListener/StatisticsReaderListenerTests.cpp index 75939b435..d06aeb990 100644 --- a/test/unittest/StatisticsReaderListener/StatisticsReaderListenerTests.cpp +++ b/test/unittest/StatisticsReaderListener/StatisticsReaderListenerTests.cpp @@ -1296,91 +1296,6 @@ TEST_F(statistics_reader_listener_tests, new_sample_datas_received) data_queue_.flush(); } -TEST_F(statistics_reader_listener_tests, new_physical_data_received) -{ - std::string processname = "command"; - std::string pid = "1234"; - std::string username = "user"; - std::string hostname = "host"; - std::string participant_guid_str = "01.02.03.04.05.06.07.08.09.0a.0b.0c|0.0.0.0"; - - // Build the participant GUID - std::array prefix = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - std::array participant_id = {0, 0, 0, 0}; - DatabaseDataQueue::StatisticsGuidPrefix participant_prefix; - participant_prefix.value(prefix); - DatabaseDataQueue::StatisticsEntityId participant_entity_id; - participant_entity_id.value(participant_id); - DatabaseDataQueue::StatisticsGuid participant_guid; - participant_guid.guidPrefix(participant_prefix); - participant_guid.entityId(participant_entity_id); - - // Build the process name - std::stringstream ss; - ss << processname << ":" << pid; - std::string processname_pid = ss.str(); - - // Build the Statistics data - DatabaseDataQueue::StatisticsPhysicalData inner_data; - inner_data.host(hostname); - inner_data.user(username); - inner_data.process(processname_pid); - inner_data.participant_guid(participant_guid); - - std::shared_ptr data = std::make_shared(); - data->physical_data(inner_data); - data->_d(EventKind::PHYSICAL_DATA); - - add_sample_to_reader_history(data, get_default_info()); - - // Precondition: The participant exists and has ID 1 - EXPECT_CALL(database_, get_entity_by_guid(EntityKind::PARTICIPANT, participant_guid_str)).Times(AnyNumber()) - .WillRepeatedly(Return(std::make_pair(EntityId(0), EntityId(1)))); - - // Precondition: The host exists and has ID 2 - EXPECT_CALL(database_, get_entities_by_name(EntityKind::HOST, hostname)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(2))))); - - auto host = std::make_shared(hostname); - host->id = EntityId(2); - EXPECT_CALL(database_, get_entity(EntityId(2))).Times(AnyNumber()) - .WillRepeatedly(Return(host)); - - // Precondition: The user exists and has ID 3 - EXPECT_CALL(database_, get_entities_by_name(EntityKind::USER, username)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(3))))); - - auto user = std::make_shared(username, host); - user->id = EntityId(3); - EXPECT_CALL(database_, get_entity(EntityId(3))).Times(AnyNumber()) - .WillRepeatedly(Return(user)); - - // Precondition: The process exists and has ID 4 - EXPECT_CALL(database_, get_entities_by_name(EntityKind::PROCESS, processname)).Times(AnyNumber()) - .WillRepeatedly(Return(std::vector>(1, - std::make_pair(EntityId(0), EntityId(4))))); - - auto process = std::make_shared(processname, pid, user); - process->id = EntityId(4); - EXPECT_CALL(database_, get_entity(EntityId(4))).Times(AnyNumber()) - .WillRepeatedly(Return(process)); - - // Expectation: The link method is called with appropriate arguments - EXPECT_CALL(database_, link_participant_with_process(EntityId(1), EntityId(4))).Times(1); - - // Insert the data on the queue and wait until processed - datareader_.set_topic_name(PHYSICAL_DATA_TOPIC); - reader_listener_.on_data_available(&datareader_); - data_queue_.flush(); - - // Expectation: The insert method is not called if there is no data in the queue - EXPECT_CALL(database_, insert(_, _, _)).Times(0); - reader_listener_.on_data_available(&datareader_); - data_queue_.flush(); -} - int main( int argc, char** argv)