diff --git a/src/CIface_TEST.cc b/src/CIface_TEST.cc index b67f3c97..f21cf063 100644 --- a/src/CIface_TEST.cc +++ b/src/CIface_TEST.cc @@ -20,9 +20,12 @@ #include "gz/transport/CIface.h" -#include "test_utils.hh" #include +#include "test_utils.hh" + +using CIfaceTest = testing::PartitionedTransportTest; + static int count; ////////////////////////////////////////////////// @@ -58,7 +61,7 @@ void cbNonConst(char *_data, size_t _size, char *_msgType, void *_userData) } ////////////////////////////////////////////////// -TEST(CIfaceTest, PubSub) +TEST_F(CIfaceTest, PubSub) { count = 0; GzTransportNode *node = gzTransportNodeCreate(nullptr); @@ -114,7 +117,7 @@ TEST(CIfaceTest, PubSub) } ////////////////////////////////////////////////// -TEST(CIfaceTest, PubSubPartitions) +TEST_F(CIfaceTest, PubSubPartitions) { count = 0; GzTransportNode *node = gzTransportNodeCreate(nullptr); @@ -175,19 +178,3 @@ TEST(CIfaceTest, PubSubPartitions) gzTransportNodeDestroy(&nodeBar); EXPECT_EQ(nullptr, nodeBar); } - -////////////////////////////////////////////////// -int main(int argc, char **argv) -{ - // Get a random partition name. - std::string partition = testing::getRandomNumber(); - - // Set the partition name for this process. - gz::utils::setenv("GZ_PARTITION", partition); - - // Enable verbose mode. - // gz::utils::setenv("GZ_VERBOSE", "1"); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/src/Clock_TEST.cc b/src/Clock_TEST.cc index 22547b2c..89cc5c4b 100644 --- a/src/Clock_TEST.cc +++ b/src/Clock_TEST.cc @@ -24,6 +24,7 @@ #include "gz/transport/Clock.hh" #include "gz/transport/Node.hh" #include "gz/transport/TransportTypes.hh" + #include "gtest/gtest.h" using namespace gz; diff --git a/src/Node_TEST.cc b/src/Node_TEST.cc index 0bfb79bc..b6e7e48d 100644 --- a/src/Node_TEST.cc +++ b/src/Node_TEST.cc @@ -38,7 +38,7 @@ using namespace gz; -static std::string partition; // NOLINT(*) +static std::string g_partition; // NOLINT(*) static std::string g_FQNPartition; // NOLINT(*) static std::string g_topic = "/foo"; // NOLINT(*) static std::string g_topic_remap = "/bar"; // NOLINT(*) @@ -57,6 +57,19 @@ static bool wrongResponseExecuted; static int counter = 0; static bool terminatePub = false; +/// Create a GZ_PARTITION to run each test in to prevent cross talk. +/// Additionally set the global partition and FQN partition variables +/// to be used in the free callback functions. +class NodeTest : public testing::PartitionedTransportTest +{ + protected: void SetUp() override { + testing::PartitionedTransportTest::SetUp(); + gz::utils::setenv("GZ_TOPIC_STATISTICS", "1"); + g_partition = this->Partition(); + g_FQNPartition = "/" + this->Partition(); + } +}; + ////////////////////////////////////////////////// /// \brief Initialize some global variables. void reset() @@ -519,7 +532,7 @@ void CreatePubSubTwoThreads( ////////////////////////////////////////////////// /// \brief Test the bool operator of the Node::Publisher class -TEST(NodePubTest, BoolOperatorTest) +TEST_F(NodeTest, BoolOperatorTest) { transport::Node node; transport::Node node2; @@ -536,10 +549,13 @@ TEST(NodePubTest, BoolOperatorTest) ////////////////////////////////////////////////// /// \brief A message should not be published if it is not advertised before. -TEST(NodeTest, PubWithoutAdvertise) +TEST_F(NodeTest, PubWithoutAdvertise) { reset(); + g_partition = this->Partition(); + g_FQNPartition = "/" + this->Partition(); + msgs::Int32 msg; msg.set_data(data); @@ -547,9 +563,9 @@ TEST(NodeTest, PubWithoutAdvertise) // empty namespace. transport::NodeOptions optionsNode1; transport::NodeOptions optionsNode2; - optionsNode1.SetPartition(partition); + optionsNode1.SetPartition(g_partition); optionsNode1.SetNameSpace("invalid namespace"); - optionsNode2.SetPartition(partition); + optionsNode2.SetPartition(g_partition); transport::Node node1(optionsNode1); transport::Node node2(optionsNode2); @@ -598,7 +614,7 @@ TEST(NodeTest, PubWithoutAdvertise) ////////////////////////////////////////////////// /// \brief A thread can create a node, and send and receive messages. -TEST(NodeTest, PubSubSameThread) +TEST_F(NodeTest, PubSubSameThread) { reset(); @@ -646,7 +662,7 @@ TEST(NodeTest, PubSubSameThread) ////////////////////////////////////////////////// /// \brief A thread can create a node, and send and receive messages. -TEST(NodeTest, PubSubSameThreadGenericCb) +TEST_F(NodeTest, PubSubSameThreadGenericCb) { reset(); @@ -690,7 +706,7 @@ TEST(NodeTest, PubSubSameThreadGenericCb) /// \brief A thread can create a node, and send and receive messages. /// This test uses a callback that accepts a parameter with the message /// information. -TEST(NodeTest, PubSubSameThreadMessageInfo) +TEST_F(NodeTest, PubSubSameThreadMessageInfo) { reset(); @@ -730,7 +746,7 @@ TEST(NodeTest, PubSubSameThreadMessageInfo) } ////////////////////////////////////////////////// -TEST(NodeTest, RawPubSubSameThreadMessageInfo) +TEST_F(NodeTest, RawPubSubSameThreadMessageInfo) { reset(); @@ -770,7 +786,7 @@ TEST(NodeTest, RawPubSubSameThreadMessageInfo) } ////////////////////////////////////////////////// -TEST(NodeTest, RawPubRawSubSameThreadMessageInfo) +TEST_F(NodeTest, RawPubRawSubSameThreadMessageInfo) { reset(); @@ -810,7 +826,7 @@ TEST(NodeTest, RawPubRawSubSameThreadMessageInfo) } ////////////////////////////////////////////////// -TEST(NodeTest, PubRawSubSameThreadMessageInfo) +TEST_F(NodeTest, PubRawSubSameThreadMessageInfo) { reset(); @@ -851,7 +867,7 @@ TEST(NodeTest, PubRawSubSameThreadMessageInfo) ////////////////////////////////////////////////// /// \brief Subscribe to a topic using a lambda function. -TEST(NodeTest, PubSubSameThreadLambda) +TEST_F(NodeTest, PubSubSameThreadLambda) { reset(); @@ -898,7 +914,7 @@ TEST(NodeTest, PubSubSameThreadLambda) /// \brief Subscribe to a topic using a lambda function. /// This test uses a callback that accepts a parameter with the message /// information. -TEST(NodeTest, PubSubSameThreadLambdaMessageInfo) +TEST_F(NodeTest, PubSubSameThreadLambdaMessageInfo) { reset(); @@ -944,7 +960,7 @@ TEST(NodeTest, PubSubSameThreadLambdaMessageInfo) ////////////////////////////////////////////////// /// \brief Advertise two topics with the same name. It's not possible to do it /// within the same node but it's valid on separate nodes. -TEST(NodeTest, AdvertiseTwoEqualTopics) +TEST_F(NodeTest, AdvertiseTwoEqualTopics) { transport::Node node1; transport::Node node2; @@ -960,7 +976,7 @@ TEST(NodeTest, AdvertiseTwoEqualTopics) ////////////////////////////////////////////////// /// \brief Use two threads using their own transport nodes. One thread /// will publish a message, whereas the other thread is subscribed to the topic. -TEST(NodeTest, PubSubTwoThreadsSameTopic) +TEST_F(NodeTest, PubSubTwoThreadsSameTopic) { transport::NodeOptions options; CreatePubSubTwoThreads(options); @@ -969,7 +985,7 @@ TEST(NodeTest, PubSubTwoThreadsSameTopic) ////////////////////////////////////////////////// /// \brief Check that two nodes in different threads are able to communicate /// advertising a topic with "Process" scope. -TEST(NodeTest, ScopeProcess) +TEST_F(NodeTest, ScopeProcess) { transport::NodeOptions options; CreatePubSubTwoThreads(options, transport::Scope_t::PROCESS); @@ -978,7 +994,7 @@ TEST(NodeTest, ScopeProcess) ////////////////////////////////////////////////// /// \brief Check that two nodes in different threads are able to communicate /// advertising a topic with "Host" scope. -TEST(NodeTest, ScopeHost) +TEST_F(NodeTest, ScopeHost) { transport::NodeOptions options; CreatePubSubTwoThreads(options, transport::Scope_t::HOST); @@ -987,7 +1003,7 @@ TEST(NodeTest, ScopeHost) ////////////////////////////////////////////////// /// \brief Check that two nodes in different threads are able to communicate /// advertising a topic with "All" scope. -TEST(NodeTest, ScopeAll) +TEST_F(NodeTest, ScopeAll) { transport::NodeOptions options; CreatePubSubTwoThreads(options, transport::Scope_t::ALL); @@ -997,7 +1013,7 @@ TEST(NodeTest, ScopeAll) /// \brief Use two threads using their own transport nodes. One thread /// will publish a message, whereas the other thread is subscribed to the topic. /// Topic remapping is enabled. -TEST(NodeTest, PubSubTwoThreadsSameTopicRemap) +TEST_F(NodeTest, PubSubTwoThreadsSameTopicRemap) { transport::NodeOptions options; options.AddTopicRemap(g_topic, g_topic_remap); @@ -1008,7 +1024,7 @@ TEST(NodeTest, PubSubTwoThreadsSameTopicRemap) /// \brief Check that two nodes in different threads are able to communicate /// advertising a topic with "Process" scope. /// Topic remapping is enabled. -TEST(NodeTest, ScopeProcessRemap) +TEST_F(NodeTest, ScopeProcessRemap) { transport::NodeOptions options; options.AddTopicRemap(g_topic, g_topic_remap); @@ -1019,7 +1035,7 @@ TEST(NodeTest, ScopeProcessRemap) /// \brief Check that two nodes in different threads are able to communicate /// advertising a topic with "Host" scope. /// Topic remapping is enabled. -TEST(NodeTest, ScopeHostRemap) +TEST_F(NodeTest, ScopeHostRemap) { transport::NodeOptions options; options.AddTopicRemap(g_topic, g_topic_remap); @@ -1030,7 +1046,7 @@ TEST(NodeTest, ScopeHostRemap) /// \brief Check that two nodes in different threads are able to communicate /// advertising a topic with "All" scope. /// Topic remapping is enabled. -TEST(NodeTest, ScopeAllRemap) +TEST_F(NodeTest, ScopeAllRemap) { transport::NodeOptions options; options.AddTopicRemap(g_topic, g_topic_remap); @@ -1041,7 +1057,7 @@ TEST(NodeTest, ScopeAllRemap) /// \brief Use two different transport nodes on the same thread. Check that /// both receive the updates when they are subscribed to the same topic. Check /// also that when one of the nodes unsubscribes, no longer receives updates. -TEST(NodeTest, PubSubOneThreadTwoSubs) +TEST_F(NodeTest, PubSubOneThreadTwoSubs) { reset(); @@ -1117,7 +1133,7 @@ TEST(NodeTest, PubSubOneThreadTwoSubs) ////////////////////////////////////////////////// /// \brief Use the transport inside a class and check advertise, subscribe and /// publish. -TEST(NodeTest, ClassMemberCallbackMessage) +TEST_F(NodeTest, ClassMemberCallbackMessage) { MyTestClass client; client.Subscribe(); @@ -1135,7 +1151,7 @@ TEST(NodeTest, ClassMemberCallbackMessage) ////////////////////////////////////////////////// /// \brief Use the transport inside a class and check advertise, subscribe and /// publish. This test uses a callback that accepts message information. -TEST(NodeTest, ClassMemberCallbackMessageInfo) +TEST_F(NodeTest, ClassMemberCallbackMessageInfo) { MyTestClass client; client.SubscribeWithMessageInfo(); @@ -1153,7 +1169,7 @@ TEST(NodeTest, ClassMemberCallbackMessageInfo) ////////////////////////////////////////////////// /// \brief Make an asynchronous and synchronous service calls using member /// function. -TEST(NodeTest, ClassMemberCallbackService) +TEST_F(NodeTest, ClassMemberCallbackService) { MyTestClass client; client.TestServiceCall(); @@ -1162,7 +1178,7 @@ TEST(NodeTest, ClassMemberCallbackService) ////////////////////////////////////////////////// /// \brief Make an asynchronous and synchronous service calls without input /// using member function. -TEST(NodeTest, ClassMemberCallbackServiceWithoutInput) +TEST_F(NodeTest, ClassMemberCallbackServiceWithoutInput) { MyTestClass client; client.TestServiceCallWithoutInput(); @@ -1178,7 +1194,7 @@ TEST(NodeTest, ClassMemberRequestServiceBeforeAdvertise) ////////////////////////////////////////////////// /// \brief Check that the types advertised and published match. -TEST(NodeTest, TypeMismatch) +TEST_F(NodeTest, TypeMismatch) { reset(); @@ -1202,7 +1218,7 @@ TEST(NodeTest, TypeMismatch) ////////////////////////////////////////////////// /// \brief Make an asynchronous service call using free function. -TEST(NodeTest, ServiceCallAsync) +TEST_F(NodeTest, ServiceCallAsync) { reset(); @@ -1266,7 +1282,7 @@ TEST(NodeTest, ServiceCallAsync) ////////////////////////////////////////////////// /// \brief Make an asynchronous service call without input using free function. -TEST(NodeTest, ServiceCallWithoutInputAsync) +TEST_F(NodeTest, ServiceCallWithoutInputAsync) { reset(); @@ -1328,7 +1344,7 @@ TEST(NodeTest, ServiceCallWithoutInputAsync) ////////////////////////////////////////////////// /// \brief Make an asynchronous service call without waiting for a response /// \using free function. -TEST(NodeTest, ServiceWithoutOutputCallAsync) +TEST_F(NodeTest, ServiceWithoutOutputCallAsync) { reset(); @@ -1371,7 +1387,7 @@ TEST(NodeTest, ServiceWithoutOutputCallAsync) ////////////////////////////////////////////////// /// \brief Make an asynchronous service call using lambdas. -TEST(NodeTest, ServiceCallAsyncLambda) +TEST_F(NodeTest, ServiceCallAsyncLambda) { reset(); @@ -1409,7 +1425,7 @@ TEST(NodeTest, ServiceCallAsyncLambda) ////////////////////////////////////////////////// /// \brief Make an asynchronous service call without input using lambdas. -TEST(NodeTest, ServiceCallWithoutInputAsyncLambda) +TEST_F(NodeTest, ServiceCallWithoutInputAsyncLambda) { reset(); @@ -1442,7 +1458,7 @@ TEST(NodeTest, ServiceCallWithoutInputAsyncLambda) ////////////////////////////////////////////////// /// \Make an asynchronous service call without waiting for response using /// \lambdas. -TEST(NodeTest, ServiceCallWithoutOutputAsyncLambda) +TEST_F(NodeTest, ServiceCallWithoutOutputAsyncLambda) { bool executed = false; @@ -1465,7 +1481,7 @@ TEST(NodeTest, ServiceCallWithoutOutputAsyncLambda) ////////////////////////////////////////////////// /// \brief Request multiple service calls at the same time. -TEST(NodeTest, MultipleServiceCallAsync) +TEST_F(NodeTest, MultipleServiceCallAsync) { reset(); @@ -1525,7 +1541,7 @@ TEST(NodeTest, MultipleServiceCallAsync) ////////////////////////////////////////////////// /// \brief Request multiple service calls without input at the same time. -TEST(NodeTest, MultipleServiceCallWithoutInputAsync) +TEST_F(NodeTest, MultipleServiceCallWithoutInputAsync) { reset(); @@ -1582,7 +1598,7 @@ TEST(NodeTest, MultipleServiceCallWithoutInputAsync) /// \brief Request multiple service calls without without waiting for a response /// \ at the same time. -TEST(NodeTest, MultipleServiceWithoutOutputCallAsync) +TEST_F(NodeTest, MultipleServiceWithoutOutputCallAsync) { reset(); @@ -1636,7 +1652,7 @@ TEST(NodeTest, MultipleServiceWithoutOutputCallAsync) ////////////////////////////////////////////////// /// \brief Make a synchronous service call. -TEST(NodeTest, ServiceCallSync) +TEST_F(NodeTest, ServiceCallSync) { reset(); @@ -1664,7 +1680,7 @@ TEST(NodeTest, ServiceCallSync) ////////////////////////////////////////////////// /// \brief Make a synchronous service call without input. -TEST(NodeTest, ServiceCallWithoutInputSync) +TEST_F(NodeTest, ServiceCallWithoutInputSync) { reset(); @@ -1689,7 +1705,7 @@ TEST(NodeTest, ServiceCallWithoutInputSync) ////////////////////////////////////////////////// /// \brief Check a timeout in a synchronous service call. -TEST(NodeTest, ServiceCallSyncTimeout) +TEST_F(NodeTest, ServiceCallSyncTimeout) { reset(); @@ -1722,7 +1738,7 @@ TEST(NodeTest, ServiceCallSyncTimeout) ////////////////////////////////////////////////// /// \brief Check a timeout in a synchronous service call without input. -TEST(NodeTest, ServiceCallWithoutInputSyncTimeout) +TEST_F(NodeTest, ServiceCallWithoutInputSyncTimeout) { reset(); @@ -1798,7 +1814,7 @@ void signal_handler(int _signal) ////////////////////////////////////////////////// /// \brief Check that an external program can capture a SIGINT and terminate /// the program without problems. -TEST(NodeTest, SigIntTermination) +TEST_F(NodeTest, SigIntTermination) { reset(); @@ -1817,7 +1833,7 @@ TEST(NodeTest, SigIntTermination) ////////////////////////////////////////////////// /// \brief Check that an external program can capture a SIGTERM and terminate /// the program without problems. -TEST(NodeTest, SigTermTermination) +TEST_F(NodeTest, SigTermTermination) { reset(); @@ -1836,7 +1852,7 @@ TEST(NodeTest, SigTermTermination) ////////////////////////////////////////////////// /// \brief Check that a message is not published if the type does not match /// the type advertised. -TEST(NodeTest, PubSubWrongTypesOnPublish) +TEST_F(NodeTest, PubSubWrongTypesOnPublish) { reset(); @@ -1880,7 +1896,7 @@ TEST(NodeTest, PubSubWrongTypesOnPublish) ////////////////////////////////////////////////// /// \brief Check that a message is not received if the callback does not use /// the advertised types. -TEST(NodeTest, PubSubWrongTypesOnSubscription) +TEST_F(NodeTest, PubSubWrongTypesOnSubscription) { reset(); @@ -1912,7 +1928,7 @@ TEST(NodeTest, PubSubWrongTypesOnSubscription) /// \brief This test spawns two subscribers on the same topic. One of the /// subscribers has a wrong callback (types in the callback does not match the /// advertised type). Check that only the good callback is executed. -TEST(NodeTest, PubSubWrongTypesTwoSubscribers) +TEST_F(NodeTest, PubSubWrongTypesTwoSubscribers) { reset(); @@ -1951,7 +1967,7 @@ TEST(NodeTest, PubSubWrongTypesTwoSubscribers) ////////////////////////////////////////////////// /// \brief This test creates one publisher and one subscriber. The publisher /// publishes at higher frequency than the rate set by the subscriber. -TEST(NodeTest, SubThrottled) +TEST_F(NodeTest, SubThrottled) { reset(); @@ -1986,7 +2002,7 @@ TEST(NodeTest, SubThrottled) ////////////////////////////////////////////////// /// \brief This test creates one publisher and one subscriber. The publisher /// publishes at a throttled frequency . -TEST(NodeTest, PubThrottled) +TEST_F(NodeTest, PubThrottled) { reset(); @@ -2059,7 +2075,7 @@ TEST(NodeTest, IgnoreLocalMessages) /// \brief This test spawns a service responser and a service requester. The /// requester uses a wrong type for the request argument. The test should verify /// that the service call does not succeed. -TEST(NodeTest, SrvRequestWrongReq) +TEST_F(NodeTest, SrvRequestWrongReq) { reset(); @@ -2090,7 +2106,7 @@ TEST(NodeTest, SrvRequestWrongReq) /// \brief This test spawns a service responser and a service requester. The /// requester uses a wrong type for the response argument. The test should /// verify that the service call does not succeed. -TEST(NodeTest, SrvRequestWrongRep) +TEST_F(NodeTest, SrvRequestWrongRep) { reset(); @@ -2119,7 +2135,7 @@ TEST(NodeTest, SrvRequestWrongRep) /// \brief This test spawns a service that doesn't accept input parameters. The /// service requester uses a wrong type for the response argument. The test /// should verify that the service call does not succeed. -TEST(NodeTest, SrvWithoutInputRequestWrongRep) +TEST_F(NodeTest, SrvWithoutInputRequestWrongRep) { reset(); @@ -2146,7 +2162,7 @@ TEST(NodeTest, SrvWithoutInputRequestWrongRep) /// service requesters use incorrect types in some of the requests. The test /// should verify that a response is received only when the appropriate types /// are used. -TEST(NodeTest, SrvTwoRequestsOneWrong) +TEST_F(NodeTest, SrvTwoRequestsOneWrong) { reset(); @@ -2181,7 +2197,7 @@ TEST(NodeTest, SrvTwoRequestsOneWrong) /// service requesters use incorrect types in some of the requests. The test /// should verify that a response is received only when the appropriate types /// are used. -TEST(NodeTest, SrvWithoutInputTwoRequestsOneWrong) +TEST_F(NodeTest, SrvWithoutInputTwoRequestsOneWrong) { reset(); @@ -2211,7 +2227,7 @@ TEST(NodeTest, SrvWithoutInputTwoRequestsOneWrong) ////////////////////////////////////////////////// /// \brief This test creates two nodes and advertises some topics. The test /// verifies that TopicList() returns the list of all the topics advertised. -TEST(NodeTest, TopicList) +TEST_F(NodeTest, TopicList) { std::vector topics; transport::Node node1; @@ -2241,7 +2257,7 @@ TEST(NodeTest, TopicList) /// \brief This test creates two nodes and advertises some topics. The test /// verifies that TopicList() returns the list of all the topics advertised. /// Topic remapping is enabled. -TEST(NodeTest, TopicListRemap) +TEST_F(NodeTest, TopicListRemap) { std::vector topics; transport::NodeOptions nodeOptions; @@ -2260,7 +2276,7 @@ TEST(NodeTest, TopicListRemap) ////////////////////////////////////////////////// /// \brief This test creates two nodes and advertises some services. The test /// verifies that ServiceList() returns the list of all the services advertised. -TEST(NodeTest, ServiceList) +TEST_F(NodeTest, ServiceList) { std::vector services; transport::Node node; @@ -2288,7 +2304,7 @@ TEST(NodeTest, ServiceList) /// \brief This test creates two nodes and advertises some services. The test /// verifies that ServiceList() returns the list of all the services advertised. /// Topic remapping is enabled. -TEST(NodeTest, ServiceListRemap) +TEST_F(NodeTest, ServiceListRemap) { std::vector services; transport::NodeOptions nodeOptions; @@ -2304,7 +2320,7 @@ TEST(NodeTest, ServiceListRemap) ////////////////////////////////////////////////// /// \brief Check bad topic remap use cases. -TEST(NodeTest, WrongTopicRemap) +TEST_F(NodeTest, WrongTopicRemap) { transport::NodeOptions nodeOptions; @@ -2319,21 +2335,21 @@ TEST(NodeTest, WrongTopicRemap) ///////////////////////////////////////////////// /// \brief Check the high water mark of the receiving message buffer. -TEST(NodeTest, RcvHwm) +TEST_F(NodeTest, RcvHwm) { EXPECT_EQ(transport::kDefaultRcvHwm, transport::rcvHwm()); } ////////////////////////////////////////////////// /// \brief Check the high water mark of the sending message buffer. -TEST(NodeTest, SndHwm) +TEST_F(NodeTest, SndHwm) { EXPECT_EQ(transport::kDefaultSndHwm, transport::sndHwm()); } ////////////////////////////////////////////////// /// \brief Check that we destruct a Node object before a Node::Publisher. -TEST(NodePubTest, DestructionOrder) +TEST_F(NodeTest, DestructionOrder) { transport::Node::Publisher pub; @@ -2347,7 +2363,7 @@ TEST(NodePubTest, DestructionOrder) /// \brief Create a separate thread, block it calling waitForShutdown() and /// emit a SIGINT signal. Check that the transport library captures the signal /// and is able to terminate. -TEST(NodeTest, waitForShutdownSIGINT) +TEST_F(NodeTest, waitForShutdownSIGINT) { std::thread aThread([]{transport::waitForShutdown();}); std::this_thread::sleep_for(std::chrono::milliseconds(50)); @@ -2359,7 +2375,7 @@ TEST(NodeTest, waitForShutdownSIGINT) /// \brief Create a separate thread, block it calling waitForShutdown() and /// emit a SIGTERM signal. Check that the transport library captures the signal /// and is able to terminate. -TEST(NodeTest, waitForShutdownSIGTERM) +TEST_F(NodeTest, waitForShutdownSIGTERM) { std::thread aThread([]{transport::waitForShutdown();}); std::this_thread::sleep_for(std::chrono::milliseconds(50)); @@ -2369,7 +2385,7 @@ TEST(NodeTest, waitForShutdownSIGTERM) ////////////////////////////////////////////////// /// \brief Test topic statistics with no statistics available. -TEST(NodeTest, statistics) +TEST_F(NodeTest, statistics) { transport::Node node; EXPECT_TRUE(node.EnableStats("/test", true)); @@ -2400,20 +2416,3 @@ TEST(NodeTest, relay) { EXPECT_NE(relayIt, relaysAfterAdd.cend()); } } - -////////////////////////////////////////////////// -int main(int argc, char **argv) -{ - // Get a random partition name. - partition = testing::getRandomNumber(); - g_FQNPartition = std::string("/") + partition; - - // Set the partition name for this process. - gz::utils::setenv("GZ_PARTITION", partition); - - // Enable verbose mode. - gz::utils::setenv("GZ_VERBOSE", "1"); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/integration/authPubSub.cc b/test/integration/authPubSub.cc index 1f2d6dcd..7f008d64 100644 --- a/test/integration/authPubSub.cc +++ b/test/integration/authPubSub.cc @@ -31,11 +31,12 @@ using namespace gz; -static std::string partition; // NOLINT(*) +using authPubSub = testing::PartitionedTransportTest; + static std::string g_topic = "/foo"; // NOLINT(*) ////////////////////////////////////////////////// -TEST(authPubSub, InvalidAuth) +TEST_F(authPubSub, InvalidAuth) { // Setup the username and password for this test ASSERT_TRUE(gz::utils::setenv("GZ_TRANSPORT_USERNAME", "admin")); @@ -48,9 +49,10 @@ TEST(authPubSub, InvalidAuth) // No subscribers yet. EXPECT_FALSE(pub.HasConnections()); - auto pi = gz::utils::Subprocess( - {test_executables::kAuthPubSubSubscriberInvalid, - partition, "bad", "invalid"}); + this->SpawnSubprocess({test_executables::kAuthPubSubSubscriberInvalid}, { + {"GZ_TRANSPORT_USERNAME", "bad"}, + {"GZ_TRANSPORT_PASSWORD", "invalid"}, + }); msgs::Int32 msg; msg.set_data(1); @@ -69,16 +71,3 @@ TEST(authPubSub, InvalidAuth) std::this_thread::sleep_for(std::chrono::milliseconds(500)); } } - -////////////////////////////////////////////////// -int main(int argc, char **argv) -{ - // Get a random partition name. - partition = testing::getRandomNumber(); - - // Set the partition name for this process. - gz::utils::setenv("GZ_PARTITION", partition); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/integration/scopedTopic.cc b/test/integration/scopedTopic.cc index de0b3d4d..ba0294e3 100644 --- a/test/integration/scopedTopic.cc +++ b/test/integration/scopedTopic.cc @@ -32,7 +32,8 @@ using namespace gz; -static std::string partition; // NOLINT(*) +using ScopedTopicTest = testing::PartitionedTransportTest; + static std::string g_topic = "/foo"; // NOLINT(*) static int data = 5; @@ -40,10 +41,9 @@ static int data = 5; /// \brief Two different nodes, each one running in a different process. The /// publisher advertises the topic as "process". This test checks that the topic /// is not seen by the other node running in a different process. -TEST(ScopedTopicTest, ProcessTest) +TEST_F(ScopedTopicTest, ProcessTest) { - auto pi = gz::utils::Subprocess( - {test_executables::kScopedTopicSubscriber, partition}); + this->SpawnSubprocess({test_executables::kScopedTopicSubscriber}); msgs::Int32 msg; msg.set_data(data); @@ -59,16 +59,3 @@ TEST(ScopedTopicTest, ProcessTest) std::this_thread::sleep_for(std::chrono::milliseconds(500)); EXPECT_TRUE(pub.Publish(msg)); } - -////////////////////////////////////////////////// -int main(int argc, char **argv) -{ - // Get a random partition name. - partition = testing::getRandomNumber(); - - // Set the partition name for this process. - gz::utils::setenv("GZ_PARTITION", partition); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/integration/statistics.cc b/test/integration/statistics.cc index ae2462a3..56ac5899 100644 --- a/test/integration/statistics.cc +++ b/test/integration/statistics.cc @@ -31,6 +31,8 @@ using namespace gz; +using topicStatistics = testing::PartitionedTransportTest; + static int statisticsCount = 0; void cb(const msgs::StringMsg & /*_msg*/) @@ -43,8 +45,9 @@ void statsCb(const msgs::Metric & /*_msg*/) statisticsCount++; } -TEST(topicStatistics, SingleProcessPublishStatistics) +TEST_F(topicStatistics, SingleProcessPublishStatistics) { + ASSERT_TRUE(gz::utils::setenv("GZ_TRANSPORT_TOPIC_STATISTICS", "1")); statisticsCount = 0; std::string topic = "/foo"; transport::Node node; @@ -74,17 +77,3 @@ TEST(topicStatistics, SingleProcessPublishStatistics) EXPECT_EQ(0, statisticsCount); EXPECT_EQ(std::nullopt, node.TopicStats(topic)); } - -////////////////////////////////////////////////// -int main(int argc, char **argv) -{ - // Get a random partition name. - std::string partition = testing::getRandomNumber(); - - // Set the partition name for this process. - gz::utils::setenv("GZ_PARTITION", partition); - gz::utils::setenv("GZ_TRANSPORT_TOPIC_STATISTICS", "1"); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/integration/test_executables/authPubSubSubscriberInvalid_aux.cc b/test/integration/test_executables/authPubSubSubscriberInvalid_aux.cc index 39035728..266dd87e 100644 --- a/test/integration/test_executables/authPubSubSubscriberInvalid_aux.cc +++ b/test/integration/test_executables/authPubSubSubscriberInvalid_aux.cc @@ -17,24 +17,13 @@ #include #include -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4251) -#endif #include -#ifdef _MSC_VER -#pragma warning(pop) -#endif -#ifdef _WIN32 - #include -#endif #include "gz/transport/Node.hh" #include #include "gtest/gtest.h" -#include "test_config.hh" using namespace gz; @@ -76,22 +65,6 @@ TEST(authProcPubSub, PubSubTwoProcsTwoNodesSubscriber) ////////////////////////////////////////////////// int main(int argc, char **argv) { - if (argc != 4) - { - std::cerr << "Partition name, username, and password have not be passed as " - << "arguments" << std::endl; - return -1; - } - - // Set the partition name for this test. - gz::utils::setenv("GZ_PARTITION", argv[1]); - - // Set the username for this test. - gz::utils::setenv("GZ_TRANSPORT_USERNAME", argv[2]); - - // Set the password for this test. - gz::utils::setenv("GZ_TRANSPORT_PASSWORD", argv[3]); - ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/integration/test_executables/fastPub_aux.cc b/test/integration/test_executables/fastPub_aux.cc index d0df10cf..d0e8fe41 100644 --- a/test/integration/test_executables/fastPub_aux.cc +++ b/test/integration/test_executables/fastPub_aux.cc @@ -16,21 +16,12 @@ */ #include #include -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4251) -#endif #include -#ifdef _MSC_VER -#pragma warning(pop) -#endif #include "gz/transport/Node.hh" #include -#include "test_config.hh" - using namespace gz; static std::string g_topic = "/foo"; // NOLINT(*) @@ -52,16 +43,7 @@ void advertiseAndPublish() } ////////////////////////////////////////////////// -int main(int argc, char **argv) +int main(int, char **) { - if (argc != 2) - { - std::cerr << "Partition name has not be passed as argument" << std::endl; - return -1; - } - - // Set the partition name for this test. - gz::utils::setenv("GZ_PARTITION", argv[1]); - advertiseAndPublish(); } diff --git a/test/integration/test_executables/pub_aux.cc b/test/integration/test_executables/pub_aux.cc index 2737a3b8..d9be03a9 100644 --- a/test/integration/test_executables/pub_aux.cc +++ b/test/integration/test_executables/pub_aux.cc @@ -25,8 +25,6 @@ #include -#include "test_config.hh" - using namespace gz; static std::string g_topic = "/foo"; // NOLINT(*) @@ -53,16 +51,7 @@ void advertiseAndPublish() } ////////////////////////////////////////////////// -int main(int argc, char **argv) +int main(int, char **) { - if (argc < 2) - { - std::cerr << "Partition name has not be passed as argument" << std::endl; - return -1; - } - - // Set the partition name for this test. - gz::utils::setenv("GZ_PARTITION", argv[1]); - advertiseAndPublish(); } diff --git a/test/integration/test_executables/pub_aux_throttled.cc b/test/integration/test_executables/pub_aux_throttled.cc index 0416523c..99489967 100644 --- a/test/integration/test_executables/pub_aux_throttled.cc +++ b/test/integration/test_executables/pub_aux_throttled.cc @@ -25,7 +25,6 @@ #include #include "gtest/gtest.h" -#include "test_config.hh" using namespace gz; @@ -55,16 +54,7 @@ void advertiseAndPublish() } ////////////////////////////////////////////////// -int main(int argc, char **argv) +int main(int, char **) { - if (argc < 2) - { - std::cerr << "Partition name has not be passed as argument" << std::endl; - return -1; - } - - // Set the partition name for this test. - gz::utils::setenv("GZ_PARTITION", argv[1]); - advertiseAndPublish(); } diff --git a/test/integration/test_executables/scopedTopicSubscriber_aux.cc b/test/integration/test_executables/scopedTopicSubscriber_aux.cc index 3bb44f16..d2a5f13d 100644 --- a/test/integration/test_executables/scopedTopicSubscriber_aux.cc +++ b/test/integration/test_executables/scopedTopicSubscriber_aux.cc @@ -69,15 +69,6 @@ TEST(ScopedTopicTest, SubscriberTest) ////////////////////////////////////////////////// int main(int argc, char **argv) { - if (argc != 2) - { - std::cerr << "Partition name has not be passed as argument" << std::endl; - return -1; - } - - // Set the partition name for this test. - gz::utils::setenv("GZ_PARTITION", argv[1]); - ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/integration/test_executables/twoProcsPubSubSubscriber_aux.cc b/test/integration/test_executables/twoProcsPubSubSubscriber_aux.cc index 49a360a0..db19e94f 100644 --- a/test/integration/test_executables/twoProcsPubSubSubscriber_aux.cc +++ b/test/integration/test_executables/twoProcsPubSubSubscriber_aux.cc @@ -25,7 +25,6 @@ #include #include "gtest/gtest.h" -#include "test_config.hh" using namespace gz; @@ -153,16 +152,6 @@ TEST(twoProcPubSub, PubSubTwoProcsTwoNodesSubscriber) ////////////////////////////////////////////////// int main(int argc, char **argv) { - if (argc != 2) - { - std::cerr << "Partition name has not be passed as argument" << std::endl; - return -1; - } - - // Set the partition name for this test. - gz::utils::setenv("GZ_PARTITION", argv[1]); - gz::utils::setenv("GZ_TRANSPORT_TOPIC_STATISTICS", "1"); - ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/integration/test_executables/twoProcsPublisher_aux.cc b/test/integration/test_executables/twoProcsPublisher_aux.cc index ccb49c83..1e516e0c 100644 --- a/test/integration/test_executables/twoProcsPublisher_aux.cc +++ b/test/integration/test_executables/twoProcsPublisher_aux.cc @@ -23,8 +23,6 @@ #include -#include "test_config.hh" - using namespace gz; static std::string g_topic = "/foo"; // NOLINT(*) @@ -49,16 +47,7 @@ void advertiseAndPublish() } ////////////////////////////////////////////////// -int main(int argc, char **argv) +int main(int, char **) { - if (argc != 2) - { - std::cerr << "Partition name has not be passed as argument" << std::endl; - return -1; - } - - // Set the partition name for this test. - gz::utils::setenv("GZ_PARTITION", argv[1]); - advertiseAndPublish(); } diff --git a/test/integration/test_executables/twoProcsSrvCallReplierInc_aux.cc b/test/integration/test_executables/twoProcsSrvCallReplierInc_aux.cc index 1f27e84f..89ac27e3 100644 --- a/test/integration/test_executables/twoProcsSrvCallReplierInc_aux.cc +++ b/test/integration/test_executables/twoProcsSrvCallReplierInc_aux.cc @@ -25,7 +25,6 @@ #include #include "gtest/gtest.h" -#include "test_config.hh" using namespace gz; @@ -59,15 +58,6 @@ TEST(twoProcSrvCallReplierAux, SrvProcReplier) ////////////////////////////////////////////////// int main(int argc, char **argv) { - if (argc != 2) - { - std::cerr << "Partition name has not be passed as argument" << std::endl; - return -1; - } - - // Set the partition name for this test. - gz::utils::setenv("GZ_PARTITION", argv[1]); - ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/integration/test_executables/twoProcsSrvCallReplier_aux.cc b/test/integration/test_executables/twoProcsSrvCallReplier_aux.cc index 5b852359..89f50580 100644 --- a/test/integration/test_executables/twoProcsSrvCallReplier_aux.cc +++ b/test/integration/test_executables/twoProcsSrvCallReplier_aux.cc @@ -24,7 +24,6 @@ #include #include "gtest/gtest.h" -#include "test_config.hh" using namespace gz; @@ -47,16 +46,7 @@ void runReplier() } ////////////////////////////////////////////////// -int main(int argc, char **argv) +int main(int, char **) { - if (argc != 2) - { - std::cerr << "Partition name has not be passed as argument" << std::endl; - return -1; - } - - // Set the partition name for this test. - gz::utils::setenv("GZ_PARTITION", argv[1]); - runReplier(); } diff --git a/test/integration/test_executables/twoProcsSrvCallWithoutInputReplierInc_aux.cc b/test/integration/test_executables/twoProcsSrvCallWithoutInputReplierInc_aux.cc index 1cc15a89..8e9b33e4 100644 --- a/test/integration/test_executables/twoProcsSrvCallWithoutInputReplierInc_aux.cc +++ b/test/integration/test_executables/twoProcsSrvCallWithoutInputReplierInc_aux.cc @@ -25,7 +25,6 @@ #include #include "gtest/gtest.h" -#include "test_config.hh" using namespace gz; @@ -60,15 +59,6 @@ TEST(twoProcSrvCallWithoutInputReplierAux, SrvProcReplier) ////////////////////////////////////////////////// int main(int argc, char **argv) { - if (argc != 2) - { - std::cerr << "Partition name has not be passed as argument" << std::endl; - return -1; - } - - // Set the partition name for this test. - gz::utils::setenv("GZ_PARTITION", argv[1]); - ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/integration/test_executables/twoProcsSrvCallWithoutInputReplier_aux.cc b/test/integration/test_executables/twoProcsSrvCallWithoutInputReplier_aux.cc index 6ab90212..959e2209 100644 --- a/test/integration/test_executables/twoProcsSrvCallWithoutInputReplier_aux.cc +++ b/test/integration/test_executables/twoProcsSrvCallWithoutInputReplier_aux.cc @@ -24,7 +24,6 @@ #include #include "gtest/gtest.h" -#include "test_config.hh" using namespace gz; @@ -48,16 +47,7 @@ void runReplier() } ////////////////////////////////////////////////// -int main(int argc, char **argv) +int main(int, char **) { - if (argc != 2) - { - std::cerr << "Partition name has not be passed as argument" << std::endl; - return -1; - } - - // Set the partition name for this test. - gz::utils::setenv("GZ_PARTITION", argv[1]); - runReplier(); } diff --git a/test/integration/test_executables/twoProcsSrvCallWithoutOutputReplierInc_aux.cc b/test/integration/test_executables/twoProcsSrvCallWithoutOutputReplierInc_aux.cc index 8354ddb4..90a55419 100644 --- a/test/integration/test_executables/twoProcsSrvCallWithoutOutputReplierInc_aux.cc +++ b/test/integration/test_executables/twoProcsSrvCallWithoutOutputReplierInc_aux.cc @@ -25,7 +25,6 @@ #include #include "gtest/gtest.h" -#include "test_config.hh" using namespace gz; @@ -58,15 +57,6 @@ TEST(twoProcSrvCallWithoutOuputReplierAux, SrvProcReplier) ////////////////////////////////////////////////// int main(int argc, char **argv) { - if (argc != 2) - { - std::cerr << "Partition name has not be passed as argument" << std::endl; - return -1; - } - - // Set the partition name for this test. - gz::utils::setenv("GZ_PARTITION", argv[1]); - ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/integration/test_executables/twoProcsSrvCallWithoutOutputReplier_aux.cc b/test/integration/test_executables/twoProcsSrvCallWithoutOutputReplier_aux.cc index 285b06a6..d6f82141 100644 --- a/test/integration/test_executables/twoProcsSrvCallWithoutOutputReplier_aux.cc +++ b/test/integration/test_executables/twoProcsSrvCallWithoutOutputReplier_aux.cc @@ -24,7 +24,6 @@ #include #include "gtest/gtest.h" -#include "test_config.hh" using namespace gz; @@ -43,20 +42,11 @@ void runReplier() { transport::Node node; EXPECT_TRUE(node.Advertise(g_topic, srvWithoutOutput)); - std::this_thread::sleep_for(std::chrono::milliseconds(6000)); + std::this_thread::sleep_for(std::chrono::seconds(30)); } ////////////////////////////////////////////////// -int main(int argc, char **argv) +int main(int, char **) { - if (argc != 2) - { - std::cerr << "Partition name has not be passed as argument" << std::endl; - return -1; - } - - // Set the partition name for this test. - gz::utils::setenv("GZ_PARTITION", argv[1]); - runReplier(); } diff --git a/test/integration/twoProcsPubSub.cc b/test/integration/twoProcsPubSub.cc index 1cf378b2..613548df 100644 --- a/test/integration/twoProcsPubSub.cc +++ b/test/integration/twoProcsPubSub.cc @@ -32,7 +32,16 @@ using namespace gz; -static std::string partition; // NOLINT(*) +class twoProcPubSub: public testing::PartitionedTransportTest, + public testing::WithParamInterface +{ + protected: void SetUp() override { + testing::PartitionedTransportTest::SetUp(); + gz::utils::setenv("GZ_TRANSPORT_TOPIC_STATISTICS", + GetParam() ? "1" : "0"); + } +}; + static std::string g_FQNPartition; // NOLINT(*) static const std::string g_topic = "/foo"; // NOLINT(*) static std::string data = "bar"; // NOLINT(*) @@ -105,7 +114,7 @@ void cbRaw(const char * /*_msgData*/, const size_t /*_size*/, /// subscriber process there are two nodes. Both should receive the message. /// After some time one of them unsubscribe. After that check that only one /// node receives the message. -TEST(twoProcPubSub, PubSubTwoProcsThreeNodes) +TEST_P(twoProcPubSub, PubSubTwoProcsThreeNodes) { transport::Node node; auto pub = node.Advertise(g_topic); @@ -114,8 +123,7 @@ TEST(twoProcPubSub, PubSubTwoProcsThreeNodes) // No subscribers yet. EXPECT_FALSE(pub.HasConnections()); - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsPubSubSubscriber, partition}); + this->SpawnSubprocess({test_executables::kTwoProcsPubSubSubscriber}); msgs::Vector3d msg; msg.set_x(1.0); @@ -138,7 +146,7 @@ TEST(twoProcPubSub, PubSubTwoProcsThreeNodes) ////////////////////////////////////////////////// /// \brief This is the same as the last test, but we use PublishRaw(~) instead /// of Publish(~). -TEST(twoProcPubSub, RawPubSubTwoProcsThreeNodes) +TEST_P(twoProcPubSub, RawPubSubTwoProcsThreeNodes) { transport::Node node; auto pub = node.Advertise(g_topic); @@ -147,8 +155,7 @@ TEST(twoProcPubSub, RawPubSubTwoProcsThreeNodes) // No subscribers yet. EXPECT_FALSE(pub.HasConnections()); - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsPubSubSubscriber, partition}); + this->SpawnSubprocess({test_executables::kTwoProcsPubSubSubscriber}); msgs::Vector3d msg; msg.set_x(1.0); @@ -174,10 +181,9 @@ TEST(twoProcPubSub, RawPubSubTwoProcsThreeNodes) ////////////////////////////////////////////////// /// \brief Check that a message is not received if the callback does not use /// the advertised types. -TEST(twoProcPubSub, PubSubWrongTypesOnSubscription) +TEST_P(twoProcPubSub, PubSubWrongTypesOnSubscription) { - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsPublisher, partition}); + this->SpawnSubprocess({test_executables::kTwoProcsPublisher}); reset(); @@ -195,10 +201,9 @@ TEST(twoProcPubSub, PubSubWrongTypesOnSubscription) ////////////////////////////////////////////////// /// \brief Same as above, but using a raw subscription. -TEST(twoProcPubSub, PubRawSubWrongTypesOnSubscription) +TEST_P(twoProcPubSub, PubRawSubWrongTypesOnSubscription) { - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsPublisher, partition}); + this->SpawnSubprocess({test_executables::kTwoProcsPublisher}); reset(); @@ -221,10 +226,9 @@ TEST(twoProcPubSub, PubRawSubWrongTypesOnSubscription) /// advertised type). The second subscriber uses the correct callback. The third /// uses a generic callback. Check that only two of the callbacks are executed /// (correct and generic). -TEST(twoProcPubSub, PubSubWrongTypesTwoSubscribers) +TEST_P(twoProcPubSub, PubSubWrongTypesTwoSubscribers) { - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsPublisher, partition}); + this->SpawnSubprocess({test_executables::kTwoProcsPublisher}); reset(); @@ -254,10 +258,9 @@ TEST(twoProcPubSub, PubSubWrongTypesTwoSubscribers) /// match the advertised type). The second subscriber requests the correct type. /// The third accepts the generic (default) type. Check that only two of the /// callbacks are executed (correct and generic). -TEST(twoProcPubSub, PubSubWrongTypesTwoRawSubscribers) +TEST_P(twoProcPubSub, PubSubWrongTypesTwoRawSubscribers) { - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsPublisher, partition}); + this->SpawnSubprocess({test_executables::kTwoProcsPublisher}); reset(); @@ -311,10 +314,9 @@ TEST(twoProcPubSub, PubSubWrongTypesTwoRawSubscribers) /// subscribes to a topic and the other advertises, publishes a message and /// terminates. This test checks that the subscriber doesn't get affected by /// the prompt termination of the publisher. -TEST(twoProcPubSub, FastPublisher) +TEST_P(twoProcPubSub, FastPublisher) { - auto pi = gz::utils::Subprocess( - {test_executables::kFastPub, partition}); + this->SpawnSubprocess({test_executables::kFastPub}); reset(); @@ -327,10 +329,9 @@ TEST(twoProcPubSub, FastPublisher) /// \brief This test creates one publisher and one subscriber on different /// processes. The publisher publishes at higher frequency than the rate set /// by the subscriber. -TEST(twoProcPubSub, SubThrottled) +TEST_P(twoProcPubSub, SubThrottled) { - auto pi = gz::utils::Subprocess( - {test_executables::kPub, partition}); + this->SpawnSubprocess({test_executables::kPub}); reset(); @@ -353,10 +354,9 @@ TEST(twoProcPubSub, SubThrottled) ////////////////////////////////////////////////// /// \brief This test creates one publisher and one subscriber on different /// processes. The publisher publishes at a throttled frequency. -TEST(twoProcPubSub, PubThrottled) +TEST_P(twoProcPubSub, PubThrottled) { - auto pi = gz::utils::Subprocess( - {test_executables::kPubThrottled, partition}); + this->SpawnSubprocess({test_executables::kPubThrottled}); reset(); @@ -377,10 +377,9 @@ TEST(twoProcPubSub, PubThrottled) ////////////////////////////////////////////////// /// \brief Check that a message is received after Advertise->Subscribe->Publish /// using a callback that accepts message information. -TEST(twoProcPubSub, PubSubMessageInfo) +TEST_P(twoProcPubSub, PubSubMessageInfo) { - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsPublisher, partition}); + this->SpawnSubprocess({test_executables::kTwoProcsPublisher}); reset(); transport::Node node; @@ -399,10 +398,9 @@ TEST(twoProcPubSub, PubSubMessageInfo) /// \brief This test spawns two nodes on different processes. One of the nodes /// advertises a topic and the other uses TopicList() for getting the list of /// available topics. -TEST(twoProcPubSub, TopicList) +TEST_P(twoProcPubSub, TopicList) { - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsPublisher, partition}); + this->SpawnSubprocess({test_executables::kTwoProcsPublisher}); reset(); @@ -445,10 +443,9 @@ TEST(twoProcPubSub, TopicList) /// \brief This test spawns two nodes on different processes. One of the nodes /// advertises a topic and the other uses TopicInfo() for getting information /// about the topic. -TEST(twoProcPubSub, TopicInfo) +TEST_P(twoProcPubSub, TopicInfo) { - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsPublisher, partition}); + this->SpawnSubprocess({test_executables::kTwoProcsPublisher}); reset(); @@ -472,17 +469,6 @@ TEST(twoProcPubSub, TopicInfo) reset(); } -////////////////////////////////////////////////// -int main(int argc, char **argv) -{ - // Get a random partition name. - partition = testing::getRandomNumber(); - g_FQNPartition = std::string("/") + partition; - - // Set the partition name for this process. - gz::utils::setenv("GZ_PARTITION", partition); - gz::utils::setenv("GZ_TRANSPORT_TOPIC_STATISTICS", "1"); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} +INSTANTIATE_TEST_SUITE_P(TransportStatistics, + twoProcPubSub, + testing::Bool()); diff --git a/test/integration/twoProcsSrvCallStress.cc b/test/integration/twoProcsSrvCallStress.cc index c6f2c9d1..77518b1c 100644 --- a/test/integration/twoProcsSrvCallStress.cc +++ b/test/integration/twoProcsSrvCallStress.cc @@ -32,14 +32,14 @@ using namespace gz; -static std::string partition; // NOLINT(*) +using twoProcSrvCall = testing::PartitionedTransportTest; + static std::string g_topic = "/foo"; // NOLINT(*) ////////////////////////////////////////////////// -TEST(twoProcSrvCall, ThousandCalls) +TEST_F(twoProcSrvCall, ThousandCalls) { - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsSrvCallReplierInc, partition}); + this->SpawnSubprocess({test_executables::kTwoProcsSrvCallReplierInc}); msgs::Int32 req; msgs::Int32 response; @@ -59,16 +59,3 @@ TEST(twoProcSrvCall, ThousandCalls) EXPECT_EQ(i, response.data()); } } - -////////////////////////////////////////////////// -int main(int argc, char **argv) -{ - // Get a random partition name. - partition = testing::getRandomNumber(); - - // Set the partition name for this process. - gz::utils::setenv("GZ_PARTITION", partition); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/integration/twoProcsSrvCallSync1.cc b/test/integration/twoProcsSrvCallSync1.cc index 32b8e9f3..88c79d23 100644 --- a/test/integration/twoProcsSrvCallSync1.cc +++ b/test/integration/twoProcsSrvCallSync1.cc @@ -32,7 +32,8 @@ using namespace gz; -static std::string partition; // NOLINT(*) +using twoProcSrvCallSync1 = testing::PartitionedTransportTest; + static std::string g_topic = "/foo"; // NOLINT(*) static int data = 5; @@ -41,10 +42,9 @@ static int data = 5; /// synchronous requester uses a wrong service's name. The test should verify /// that the service call does not succeed and the elapsed time was close to /// the timeout. -TEST(twoProcSrvCallSync1, SrvTwoProcs) +TEST_F(twoProcSrvCallSync1, SrvTwoProcs) { - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsSrvCallReplier, partition}); + this->SpawnSubprocess({test_executables::kTwoProcsSrvCallReplier}); int64_t timeout = 500; msgs::Int32 req; @@ -74,19 +74,3 @@ TEST(twoProcSrvCallSync1, SrvTwoProcs) auto diff = std::max(elapsed, timeout) - std::min(elapsed, timeout); EXPECT_LT(diff, 200); } - -////////////////////////////////////////////////// -int main(int argc, char **argv) -{ - // Get a random partition name. - partition = testing::getRandomNumber(); - - // Set the partition name for this process. - gz::utils::setenv("GZ_PARTITION", partition); - - // Enable verbose mode. - gz::utils::setenv("GZ_VERBOSE", "1"); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/integration/twoProcsSrvCallWithoutInput.cc b/test/integration/twoProcsSrvCallWithoutInput.cc index 447dd7ca..ce6016d0 100644 --- a/test/integration/twoProcsSrvCallWithoutInput.cc +++ b/test/integration/twoProcsSrvCallWithoutInput.cc @@ -30,50 +30,21 @@ #include #include "gtest/gtest.h" -#include "test_config.hh" + #include "test_utils.hh" +#include "test_config.hh" using namespace gz; +using twoProcSrvCallWithoutInput = testing::PartitionedTransportTest; + static bool g_responseExecuted; static bool g_wrongResponseExecuted; -static std::string g_partition; // NOLINT(*) static std::string g_topic = "/foo"; // NOLINT(*) static int g_data = 5; static int g_counter = 0; -////////////////////////////////////////////////// -class twoProcSrvCallWithoutInput: public testing::Test { - protected: - void SetUp() override { - gz::utils::env("GZ_PARTITION", this->prevPartition); - - // Get a random partition name. - this->partition = testing::getRandomNumber(); - - // Set the partition name for this process. - gz::utils::setenv("GZ_PARTITION", this->partition); - - this->pi = std::make_unique( - std::vector({ - test_executables::kTwoProcsSrvCallWithoutInputReplier, - this->partition})); - } - - void TearDown() override { - gz::utils::setenv("GZ_PARTITION", this->prevPartition); - - this->pi->Terminate(); - this->pi->Join(); - } - - private: - std::string prevPartition; - std::string partition; - std::unique_ptr pi; -}; - ////////////////////////////////////////////////// /// \brief Initialize some global variables. void reset() @@ -107,6 +78,8 @@ void wrongResponse(const msgs::Vector3d &/*_rep*/, bool /*_result*/) /// calls. TEST_F(twoProcSrvCallWithoutInput, SrvTwoProcs) { + this->SpawnSubprocess({ + test_executables::kTwoProcsSrvCallWithoutInputReplier}); reset(); transport::Node node; @@ -148,6 +121,8 @@ TEST_F(twoProcSrvCallWithoutInput, SrvTwoProcs) /// should verify that the service call does not succeed. TEST_F(twoProcSrvCallWithoutInput, SrvRequestWrongRep) { + this->SpawnSubprocess({ + test_executables::kTwoProcsSrvCallWithoutInputReplier}); msgs::Vector3d wrongRep; bool result; unsigned int timeout = 1000; @@ -174,6 +149,8 @@ TEST_F(twoProcSrvCallWithoutInput, SrvRequestWrongRep) /// are used. TEST_F(twoProcSrvCallWithoutInput, SrvTwoRequestsOneWrong) { + this->SpawnSubprocess({ + test_executables::kTwoProcsSrvCallWithoutInputReplier}); msgs::Int32 goodRep; msgs::Vector3d badRep; bool result; @@ -208,6 +185,8 @@ TEST_F(twoProcSrvCallWithoutInput, SrvTwoRequestsOneWrong) /// getting the list of available services. TEST_F(twoProcSrvCallWithoutInput, ServiceList) { + this->SpawnSubprocess({ + test_executables::kTwoProcsSrvCallWithoutInputReplier}); reset(); transport::Node node; @@ -250,6 +229,8 @@ TEST_F(twoProcSrvCallWithoutInput, ServiceList) /// getting information about the service. TEST_F(twoProcSrvCallWithoutInput, ServiceInfo) { + this->SpawnSubprocess({ + test_executables::kTwoProcsSrvCallWithoutInputReplier}); reset(); transport::Node node; diff --git a/test/integration/twoProcsSrvCallWithoutInputStress.cc b/test/integration/twoProcsSrvCallWithoutInputStress.cc index 2acc7b77..27f8e7e7 100644 --- a/test/integration/twoProcsSrvCallWithoutInputStress.cc +++ b/test/integration/twoProcsSrvCallWithoutInputStress.cc @@ -32,14 +32,15 @@ using namespace gz; -static std::string g_partition; // NOLINT(*) +using twoProcSrvCallWithoutInput = testing::PartitionedTransportTest; + static std::string g_topic = "/foo"; // NOLINT(*) ////////////////////////////////////////////////// -TEST(twoProcSrvCallWithoutInput, ThousandCalls) +TEST_F(twoProcSrvCallWithoutInput, ThousandCalls) { - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsSrvCallWithoutInputReplierInc, g_partition}); + this->SpawnSubprocess({ + test_executables::kTwoProcsSrvCallWithoutInputReplierInc}); msgs::Int32 response; bool result; @@ -56,16 +57,3 @@ TEST(twoProcSrvCallWithoutInput, ThousandCalls) ASSERT_TRUE(result); } } - -////////////////////////////////////////////////// -int main(int argc, char **argv) -{ - // Get a random partition name. - g_partition = testing::getRandomNumber(); - - // Set the partition name for this process. - gz::utils::setenv("GZ_PARTITION", g_partition); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/integration/twoProcsSrvCallWithoutInputSync1.cc b/test/integration/twoProcsSrvCallWithoutInputSync1.cc index 118f1eff..9f7651cb 100644 --- a/test/integration/twoProcsSrvCallWithoutInputSync1.cc +++ b/test/integration/twoProcsSrvCallWithoutInputSync1.cc @@ -32,7 +32,8 @@ using namespace gz; -static std::string g_partition; // NOLINT(*) +using twoProcSrvCallWithoutInputSync1 = testing::PartitionedTransportTest; + static std::string g_topic = "/foo"; // NOLINT(*) ////////////////////////////////////////////////// @@ -40,10 +41,10 @@ static std::string g_topic = "/foo"; // NOLINT(*) /// synchronous requester uses a wrong service's name. The test should verify /// that the service call does not succeed and the elapsed time was close to /// the timeout. -TEST(twoProcSrvCallWithoutInputSync1, SrvTwoProcs) +TEST_F(twoProcSrvCallWithoutInputSync1, SrvTwoProcs) { - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsSrvCallWithoutInputReplier, g_partition}); + this->SpawnSubprocess({ + test_executables::kTwoProcsSrvCallWithoutInputReplier}); int64_t timeout = 500; msgs::Int32 rep; @@ -69,19 +70,3 @@ TEST(twoProcSrvCallWithoutInputSync1, SrvTwoProcs) auto diff = std::max(elapsed, timeout) - std::min(elapsed, timeout); EXPECT_LT(diff, 200); } - -////////////////////////////////////////////////// -int main(int argc, char **argv) -{ - // Get a random partition name. - g_partition = testing::getRandomNumber(); - - // Set the partition name for this process. - gz::utils::setenv("GZ_PARTITION", g_partition); - - // Enable verbose mode. - gz::utils::setenv("GZ_VERBOSE", "1"); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/integration/twoProcsSrvCallWithoutOutput.cc b/test/integration/twoProcsSrvCallWithoutOutput.cc index 5e188d83..2f201b8b 100644 --- a/test/integration/twoProcsSrvCallWithoutOutput.cc +++ b/test/integration/twoProcsSrvCallWithoutOutput.cc @@ -35,44 +35,14 @@ using namespace gz; +using twoProcSrvCallWithoutOutput = testing::PartitionedTransportTest; + static bool g_responseExecuted; static bool g_wrongResponseExecuted; -static std::string g_partition; // NOLINT(*) static std::string g_topic = "/foo"; // NOLINT(*) static int g_counter = 0; -////////////////////////////////////////////////// -class twoProcSrvCallWithoutOutput: public testing::Test { - protected: - void SetUp() override { - gz::utils::env("GZ_PARTITION", this->prevPartition); - - // Get a random partition name. - this->partition = testing::getRandomNumber(); - - // Set the partition name for this process. - gz::utils::setenv("GZ_PARTITION", this->partition); - - this->pi = std::make_unique( - std::vector({ - test_executables::kTwoProcsSrvCallWithoutOutputReplier, - this->partition})); - } - - void TearDown() override { - gz::utils::setenv("GZ_PARTITION", this->prevPartition); - - this->pi->Terminate(); - this->pi->Join(); - } - - private: - std::string prevPartition; - std::string partition; - std::unique_ptr pi; -}; - ////////////////////////////////////////////////// /// \brief Initialize some global variables. void reset() @@ -88,6 +58,8 @@ void reset() /// verify that the service call does not succeed. TEST_F(twoProcSrvCallWithoutOutput, SrvRequestWrongReq) { + this->SpawnSubprocess({ + test_executables::kTwoProcsSrvCallWithoutOutputReplier}); msgs::Vector3d wrongReq; wrongReq.set_x(1); @@ -112,6 +84,8 @@ TEST_F(twoProcSrvCallWithoutOutput, SrvRequestWrongReq) /// getting the list of available services. TEST_F(twoProcSrvCallWithoutOutput, ServiceList) { + this->SpawnSubprocess({ + test_executables::kTwoProcsSrvCallWithoutOutputReplier}); reset(); transport::Node node; @@ -154,6 +128,8 @@ TEST_F(twoProcSrvCallWithoutOutput, ServiceList) /// getting information about the service. TEST_F(twoProcSrvCallWithoutOutput, ServiceInfo) { + this->SpawnSubprocess({ + test_executables::kTwoProcsSrvCallWithoutOutputReplier}); reset(); transport::Node node; diff --git a/test/integration/twoProcsSrvCallWithoutOutputStress.cc b/test/integration/twoProcsSrvCallWithoutOutputStress.cc index 3e8d6590..5361ab8d 100644 --- a/test/integration/twoProcsSrvCallWithoutOutputStress.cc +++ b/test/integration/twoProcsSrvCallWithoutOutputStress.cc @@ -32,14 +32,15 @@ using namespace gz; -static std::string g_partition; // NOLINT(*) +using twoProcSrvCallWithoutOuput = testing::PartitionedTransportTest; + static std::string g_topic = "/foo"; // NOLINT(*) ////////////////////////////////////////////////// -TEST(twoProcSrvCallWithoutOuput, ThousandCalls) +TEST_F(twoProcSrvCallWithoutOuput, ThousandCalls) { - auto pi = gz::utils::Subprocess( - {test_executables::kTwoProcsSrvCallWithoutOutputReplierInc, g_partition}); + this->SpawnSubprocess({ + test_executables::kTwoProcsSrvCallWithoutOutputReplierInc}); msgs::Int32 req; transport::Node node; @@ -52,16 +53,3 @@ TEST(twoProcSrvCallWithoutOuput, ThousandCalls) ASSERT_TRUE(node.Request(g_topic, req)); } } - -////////////////////////////////////////////////// -int main(int argc, char **argv) -{ - // Get a random partition name. - g_partition = testing::getRandomNumber(); - - // Set the partition name for this process. - gz::utils::setenv("GZ_PARTITION", g_partition); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/test_config.hh.in b/test/test_config.hh.in index c8c02dbb..7181ebb4 100644 --- a/test/test_config.hh.in +++ b/test/test_config.hh.in @@ -26,7 +26,6 @@ constexpr const char* kTransportBashCompletion = TRANSPORT_BASH_COMPLETION_SH; namespace test_executables { - #ifdef GZ_EXE constexpr const char * kGzExe = GZ_EXE; #endif // GZ_EXE diff --git a/test/test_utils.hh b/test/test_utils.hh index ff611398..43e3c625 100644 --- a/test/test_utils.hh +++ b/test/test_utils.hh @@ -18,9 +18,17 @@ #ifndef GZ_TRANSPORT_TEST_UTILS_HH_ #define GZ_TRANSPORT_TEST_UTILS_HH_ +#include "gtest/gtest.h" + #include +#include +#include #include #include +#include + +#include +#include namespace testing { @@ -37,6 +45,72 @@ namespace testing return std::to_string(d(randGenerator)); } + + /// \brief Test fixture for creating a transport test in a new partition + /// + /// Each unit test instance will create a random partition and set the + /// appropriate environment variables. + /// This fixture will additionally terminate a process spawned with + /// the SpawnSubprocess helper function + class PartitionedTransportTest: public ::testing::Test + { + /// \brief Set up the test fixture + protected: void SetUp() override { + gz::utils::env("GZ_PARTITION", this->prevPartition); + + // Get a random partition name. + this->partition = testing::getRandomNumber(); + + // Set the partition name for this process. + gz::utils::setenv("GZ_PARTITION", this->partition); + } + + /// \brief Clean up the test fixture + protected: void TearDown() override + { + gz::utils::setenv("GZ_PARTITION", this->prevPartition); + + if (this->pi) + { + this->pi->Terminate(); + this->pi->Join(); + } + } + + /// \brief Get the randomly generated partition for this test + /// \return string value of the partition + protected: [[nodiscard]] std::string Partition() const + { + return this->partition; + } + + /// \brief Spawn a subprocess that will be terminated when the test fixture + /// is torn down. By default, the subprocess will inherit the environment + /// of the test fixture. The _overrideEnv argument can be used to replace + /// environment variable values. + /// + /// \param[in] _commandLine command line arguments + /// \param[in] _overrideEnv environment variables to override + protected: void SpawnSubprocess( + const std::vector &_commandLine, + const gz::utils::EnvironmentMap &_overrideEnv={}) + { + auto environment = gz::utils::env(); + for (const auto &[k, v] : _overrideEnv) + environment[k] = v; + this->pi = + std::make_unique(_commandLine, environment); + } + + /// \brief Store the partition when the tests starts to restore at the end + private: std::string prevPartition; + + /// \brief Store the current partition so it may be accessed by tests + private: std::string partition; + + /// \brief The subprocess running concurrently the test interacts with + private: std::unique_ptr pi; + }; } // namespace testing #endif // GZ_TRANSPORT_TEST_UTILS_HH_