From c6be5a21d1e28e60aa676ee9e49af63f002e366a Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Thu, 2 Nov 2023 09:42:00 -0700 Subject: [PATCH 1/3] Remove duplicated functionality from test_config (#457) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michael Carroll Co-authored-by: Alejandro Hernández Cordero --- log/test/integration/playback.cc | 16 ++--- log/test/integration/recorder.cc | 16 ++--- log/test/integration/topicChirp_aux.cc | 4 +- src/CIface_TEST.cc | 9 ++- src/Discovery_TEST.cc | 34 +++-------- src/Helpers_TEST.cc | 5 +- src/NodeOptions_TEST.cc | 7 ++- src/Node_TEST.cc | 9 ++- src/cmd/gz_TEST.cc | 6 +- src/cmd/gz_src_TEST.cc | 7 ++- test/integration/authPubSub.cc | 9 ++- .../authPubSubSubscriberInvalid_aux.cc | 9 ++- test/integration/fastPub_aux.cc | 5 +- test/integration/pub_aux.cc | 5 +- test/integration/pub_aux_throttled.cc | 7 ++- test/integration/scopedTopic.cc | 5 +- test/integration/scopedTopicSubscriber_aux.cc | 5 +- test/integration/statistics.cc | 7 ++- test/integration/twoProcsPubSub.cc | 9 ++- .../twoProcsPubSubSubscriber_aux.cc | 7 ++- test/integration/twoProcsPublisher_aux.cc | 5 +- test/integration/twoProcsSrvCall.cc | 7 ++- .../twoProcsSrvCallReplierInc_aux.cc | 5 +- .../integration/twoProcsSrvCallReplier_aux.cc | 5 +- test/integration/twoProcsSrvCallStress.cc | 5 +- test/integration/twoProcsSrvCallSync1.cc | 7 ++- .../twoProcsSrvCallWithoutInput.cc | 7 ++- ...oProcsSrvCallWithoutInputReplierInc_aux.cc | 5 +- .../twoProcsSrvCallWithoutInputReplier_aux.cc | 5 +- .../twoProcsSrvCallWithoutInputStress.cc | 5 +- .../twoProcsSrvCallWithoutInputSync1.cc | 7 ++- .../twoProcsSrvCallWithoutOutput.cc | 7 ++- ...ProcsSrvCallWithoutOutputReplierInc_aux.cc | 5 +- ...twoProcsSrvCallWithoutOutputReplier_aux.cc | 5 +- .../twoProcsSrvCallWithoutOutputStress.cc | 5 +- test/test_config.hh.in | 60 +------------------ 36 files changed, 177 insertions(+), 149 deletions(-) diff --git a/log/test/integration/playback.cc b/log/test/integration/playback.cc index 7ad283fa5..dd2166670 100644 --- a/log/test/integration/playback.cc +++ b/log/test/integration/playback.cc @@ -21,6 +21,8 @@ #include #include #include + +#include #include #include "ChirpParams.hh" @@ -800,17 +802,17 @@ int main(int argc, char **argv) partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", partition.c_str(), 1); + gz::utils::setenv("GZ_PARTITION", partition); - setenv("GZ_TRANSPORT_LOG_SQL_PATH", - GZ_TRANSPORT_LOG_SQL_PATH, 1); + gz::utils::setenv("GZ_TRANSPORT_LOG_SQL_PATH", + GZ_TRANSPORT_LOG_SQL_PATH); // TODO(CH3): Deprecated. Remove this on tick-tock. - setenv("IGN_TRANSPORT_LOG_SQL_PATH", - GZ_TRANSPORT_LOG_SQL_PATH, 1); + gz::utils::setenv("IGN_TRANSPORT_LOG_SQL_PATH", + GZ_TRANSPORT_LOG_SQL_PATH); - setenv(gz::transport::log::SchemaLocationEnvVar.c_str(), - GZ_TRANSPORT_LOG_SQL_PATH, 1); + gz::utils::setenv(gz::transport::log::SchemaLocationEnvVar, + GZ_TRANSPORT_LOG_SQL_PATH); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/log/test/integration/recorder.cc b/log/test/integration/recorder.cc index 333d111a2..a78617155 100644 --- a/log/test/integration/recorder.cc +++ b/log/test/integration/recorder.cc @@ -24,6 +24,8 @@ #include #include #include + +#include #include #include "ChirpParams.hh" @@ -538,17 +540,17 @@ int main(int argc, char **argv) partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", partition.c_str(), 1); + gz::utils::setenv("GZ_PARTITION", partition); - setenv("GZ_TRANSPORT_LOG_SQL_PATH", - GZ_TRANSPORT_LOG_SQL_PATH, 1); + gz::utils::setenv("GZ_TRANSPORT_LOG_SQL_PATH", + GZ_TRANSPORT_LOG_SQL_PATH); // TODO(CH3): Deprecated. Remove this on tick-tock. - setenv("IGN_TRANSPORT_LOG_SQL_PATH", - GZ_TRANSPORT_LOG_SQL_PATH, 1); + gz::utils::setenv("IGN_TRANSPORT_LOG_SQL_PATH", + GZ_TRANSPORT_LOG_SQL_PATH); - setenv(gz::transport::log::SchemaLocationEnvVar.c_str(), - GZ_TRANSPORT_LOG_SQL_PATH, 1); + gz::utils::setenv(gz::transport::log::SchemaLocationEnvVar, + GZ_TRANSPORT_LOG_SQL_PATH); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/log/test/integration/topicChirp_aux.cc b/log/test/integration/topicChirp_aux.cc index ae67e26ec..94f2942b3 100644 --- a/log/test/integration/topicChirp_aux.cc +++ b/log/test/integration/topicChirp_aux.cc @@ -22,6 +22,8 @@ #include +#include + #include "ChirpParams.hh" ////////////////////////////////////////////////// @@ -90,7 +92,7 @@ int main(int argc, char **argv) return -2; } - setenv("GZ_PARTITION", argv[1], 1); + gz::utils::setenv("GZ_PARTITION", argv[1]); const int chirps = atoi(argv[2]); diff --git a/src/CIface_TEST.cc b/src/CIface_TEST.cc index a3dc0e765..1f1b70c57 100644 --- a/src/CIface_TEST.cc +++ b/src/CIface_TEST.cc @@ -16,8 +16,11 @@ */ #include -#include "gtest/gtest.h" #include "gz/transport/CIface.h" + +#include + +#include "gtest/gtest.h" #include "test_config.hh" static int count; @@ -180,10 +183,10 @@ int main(int argc, char **argv) std::string partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", partition.c_str(), 1); + gz::utils::setenv("GZ_PARTITION", partition); // Enable verbose mode. - // setenv("GZ_VERBOSE", "1", 1); + // gz::utils::setenv("GZ_VERBOSE", "1"); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/src/Discovery_TEST.cc b/src/Discovery_TEST.cc index b113ccbff..24d1882ff 100644 --- a/src/Discovery_TEST.cc +++ b/src/Discovery_TEST.cc @@ -27,20 +27,11 @@ #include "gz/transport/Publisher.hh" #include "gz/transport/TransportTypes.hh" #include "gz/transport/Uuid.hh" -#include "test_config.hh" -// Temporarily introduce a "DISABLED_ON_LINUX" macro. -// It currently does not exist upstream. -// This can be removed when it is in upstream gz-utils -// or the discovery WrongGzIp test passes on linux -#include -#if defined __linux__ - #define GZ_UTILS_TEST_DISABLED_ON_LINUX(TestName) \ - DETAIL_GZ_UTILS_ADD_DISABLED_PREFIX(TestName) -#else - #define GZ_UTILS_TEST_DISABLED_ON_LINUX(TestName) \ - TestName -#endif // defined __linux__ +#include "gz/utils/Environment.hh" +#include "gz/utils/ExtraTestMacros.hh" + +#include "test_config.hh" using namespace gz; using namespace transport; @@ -540,31 +531,24 @@ TEST(DiscoveryTest, TestActivity) discovery1.TestActivity(proc2Uuid, false); } -/// Logic to disable the following test via Linux -#if defined __linux__ - #define TEST_NAME DISABLED_WrongIgnIp -#else - #define TEST_NAME WrongIgnIp -#endif // defined __linux__ - ////////////////////////////////////////////////// /// \brief Check that a wrong GZ_IP value makes HostAddr() to return 127.0.0.1 -TEST(DiscoveryTest, TEST_NAME) +TEST(DiscoveryTest, GZ_UTILS_TEST_DISABLED_ON_LINUX(WrongGzIp)) { // Save the current value of GZ_IP environment variable. std::string gzIp; - env("GZ_IP", gzIp); + gz::utils::env("GZ_IP", gzIp); // Incorrect value for GZ_IP - setenv("GZ_IP", "127.0.0.0", 1); + ASSERT_TRUE(gz::utils::setenv("GZ_IP", "127.0.0.0")); transport::Discovery discovery1(pUuid1, g_ip, g_msgPort); EXPECT_EQ(discovery1.HostAddr(), "127.0.0.1"); // Unset GZ_IP. - unsetenv("GZ_IP"); + ASSERT_TRUE(gz::utils::unsetenv("GZ_IP")); // Restore GZ_IP. if (!gzIp.empty()) - setenv("GZ_IP", gzIp.c_str(), 1); + gz::utils::setenv("GZ_IP", gzIp); } diff --git a/src/Helpers_TEST.cc b/src/Helpers_TEST.cc index c7f79c167..518090e11 100644 --- a/src/Helpers_TEST.cc +++ b/src/Helpers_TEST.cc @@ -16,6 +16,9 @@ */ #include "gz/transport/Helpers.hh" + +#include + #include "test_config.hh" #include "gtest/gtest.h" @@ -33,7 +36,7 @@ TEST(HelpersTest, env) EXPECT_FALSE(transport::env(name, value)); // Create a random environment variable and give it its name as value. - setenv(name.c_str(), name.c_str(), 1); + ASSERT_TRUE(gz::utils::setenv(name, name)); // Check that we find the environment variable and the value is correct. EXPECT_TRUE(transport::env(name, value)); diff --git a/src/NodeOptions_TEST.cc b/src/NodeOptions_TEST.cc index b8a78c2fc..d28a40e5a 100644 --- a/src/NodeOptions_TEST.cc +++ b/src/NodeOptions_TEST.cc @@ -19,6 +19,9 @@ #include "gz/transport/NetUtils.hh" #include "gz/transport/NodeOptions.hh" + +#include + #include "test_config.hh" #include "gtest/gtest.h" @@ -30,7 +33,7 @@ TEST(NodeOptionsTest, ignPartition) { // Set GZ_PARTITION std::string aPartition = "customPartition"; - setenv("GZ_PARTITION", aPartition.c_str(), 1); + ASSERT_TRUE(gz::utils::setenv("GZ_PARTITION", aPartition)); transport::NodeOptions opts; EXPECT_EQ(opts.Partition(), aPartition); @@ -53,7 +56,7 @@ TEST(NodeOptionsTest, ignPartition) TEST(NodeOptionsTest, accessors) { // Check the default values. - unsetenv("GZ_PARTITION"); + gz::utils::unsetenv("GZ_PARTITION"); transport::NodeOptions opts; EXPECT_TRUE(opts.NameSpace().empty()); auto defaultPartition = transport::hostname() + ":" + transport::username(); diff --git a/src/Node_TEST.cc b/src/Node_TEST.cc index 4e2b69716..80427368e 100644 --- a/src/Node_TEST.cc +++ b/src/Node_TEST.cc @@ -26,7 +26,6 @@ #include #include -#include "gtest/gtest.h" #include "gz/transport/AdvertiseOptions.hh" #include "gz/transport/MessageInfo.hh" #include "gz/transport/Node.hh" @@ -34,6 +33,10 @@ #include "gz/transport/TopicStatistics.hh" #include "gz/transport/TopicUtils.hh" #include "gz/transport/TransportTypes.hh" + +#include + +#include "gtest/gtest.h" #include "test_config.hh" using namespace gz; @@ -2324,10 +2327,10 @@ int main(int argc, char **argv) g_FQNPartition = std::string("/") + partition; // Set the partition name for this process. - setenv("GZ_PARTITION", partition.c_str(), 1); + gz::utils::setenv("GZ_PARTITION", partition); // Enable verbose mode. - setenv("GZ_VERBOSE", "1", 1); + gz::utils::setenv("GZ_VERBOSE", "1"); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/src/cmd/gz_TEST.cc b/src/cmd/gz_TEST.cc index 4babd53e0..ff5dcb7ff 100644 --- a/src/cmd/gz_TEST.cc +++ b/src/cmd/gz_TEST.cc @@ -22,6 +22,8 @@ #include #include #include + +#include #include #include "gtest/gtest.h" @@ -536,7 +538,7 @@ int main(int argc, char **argv) g_partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", g_partition.c_str(), 1); + gz::utils::setenv("GZ_PARTITION", g_partition); // Make sure that we load the library recently built and not the one installed // in your system. @@ -545,7 +547,7 @@ int main(int argc, char **argv) transport::env("LD_LIBRARY_PATH", value); // Add the directory where Gazebo Transport has been built. value = std::string(GZ_TEST_LIBRARY_PATH) + ":" + value; - setenv("LD_LIBRARY_PATH", value.c_str(), 1); + gz::utils::setenv("LD_LIBRARY_PATH", value); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/src/cmd/gz_src_TEST.cc b/src/cmd/gz_src_TEST.cc index 57ef9661c..9e6deed45 100644 --- a/src/cmd/gz_src_TEST.cc +++ b/src/cmd/gz_src_TEST.cc @@ -28,10 +28,13 @@ #pragma warning(pop) #endif -#include "gtest/gtest.h" #include "gz.hh" #include "gz/transport/Node.hh" + +#include + #include "test_config.hh" +#include "gtest/gtest.h" using namespace gz; @@ -296,7 +299,7 @@ int main(int argc, char **argv) g_partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", g_partition.c_str(), 1); + gz::utils::setenv("GZ_PARTITION", g_partition); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/integration/authPubSub.cc b/test/integration/authPubSub.cc index f0fd6eaf5..9da50e44b 100644 --- a/test/integration/authPubSub.cc +++ b/test/integration/authPubSub.cc @@ -29,6 +29,9 @@ #include "gtest/gtest.h" #include "gz/transport/Node.hh" #include "gz/transport/TransportTypes.hh" + +#include + #include "test_config.hh" using namespace gz; @@ -40,8 +43,8 @@ static std::string g_topic = "/foo"; // NOLINT(*) TEST(authPubSub, InvalidAuth) { // Setup the username and password for this test - setenv("GZ_TRANSPORT_USERNAME", "admin", 1); - setenv("GZ_TRANSPORT_PASSWORD", "test", 1); + ASSERT_TRUE(gz::utils::setenv("GZ_TRANSPORT_USERNAME", "admin")); + ASSERT_TRUE(gz::utils::setenv("GZ_TRANSPORT_PASSWORD", "test")); transport::Node node; auto pub = node.Advertise(g_topic); @@ -86,7 +89,7 @@ int main(int argc, char **argv) partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", partition.c_str(), 1); + gz::utils::setenv("GZ_PARTITION", partition); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/integration/authPubSubSubscriberInvalid_aux.cc b/test/integration/authPubSubSubscriberInvalid_aux.cc index 9b8d2d4dd..39035728e 100644 --- a/test/integration/authPubSubSubscriberInvalid_aux.cc +++ b/test/integration/authPubSubSubscriberInvalid_aux.cc @@ -30,6 +30,9 @@ #endif #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -81,13 +84,13 @@ int main(int argc, char **argv) } // Set the partition name for this test. - setenv("GZ_PARTITION", argv[1], 1); + gz::utils::setenv("GZ_PARTITION", argv[1]); // Set the username for this test. - setenv("GZ_TRANSPORT_USERNAME", argv[2], 1); + gz::utils::setenv("GZ_TRANSPORT_USERNAME", argv[2]); // Set the password for this test. - setenv("GZ_TRANSPORT_PASSWORD", argv[3], 1); + gz::utils::setenv("GZ_TRANSPORT_PASSWORD", argv[3]); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/integration/fastPub_aux.cc b/test/integration/fastPub_aux.cc index bd04c41e7..d0df10cf0 100644 --- a/test/integration/fastPub_aux.cc +++ b/test/integration/fastPub_aux.cc @@ -26,6 +26,9 @@ #endif #include "gz/transport/Node.hh" + +#include + #include "test_config.hh" using namespace gz; @@ -58,7 +61,7 @@ int main(int argc, char **argv) } // Set the partition name for this test. - setenv("GZ_PARTITION", argv[1], 1); + gz::utils::setenv("GZ_PARTITION", argv[1]); advertiseAndPublish(); } diff --git a/test/integration/pub_aux.cc b/test/integration/pub_aux.cc index c9ebebfb9..2737a3b84 100644 --- a/test/integration/pub_aux.cc +++ b/test/integration/pub_aux.cc @@ -22,6 +22,9 @@ #include "gtest/gtest.h" #include "gz/transport/Node.hh" + +#include + #include "test_config.hh" using namespace gz; @@ -59,7 +62,7 @@ int main(int argc, char **argv) } // Set the partition name for this test. - setenv("GZ_PARTITION", argv[1], 1); + gz::utils::setenv("GZ_PARTITION", argv[1]); advertiseAndPublish(); } diff --git a/test/integration/pub_aux_throttled.cc b/test/integration/pub_aux_throttled.cc index e2040c4f2..0416523ca 100644 --- a/test/integration/pub_aux_throttled.cc +++ b/test/integration/pub_aux_throttled.cc @@ -20,8 +20,11 @@ #include #include -#include "gtest/gtest.h" #include "gz/transport/Node.hh" + +#include + +#include "gtest/gtest.h" #include "test_config.hh" using namespace gz; @@ -61,7 +64,7 @@ int main(int argc, char **argv) } // Set the partition name for this test. - setenv("GZ_PARTITION", argv[1], 1); + gz::utils::setenv("GZ_PARTITION", argv[1]); advertiseAndPublish(); } diff --git a/test/integration/scopedTopic.cc b/test/integration/scopedTopic.cc index 9c36a935f..9be96a64c 100644 --- a/test/integration/scopedTopic.cc +++ b/test/integration/scopedTopic.cc @@ -21,6 +21,9 @@ #include "gz/transport/AdvertiseOptions.hh" #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -67,7 +70,7 @@ int main(int argc, char **argv) partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", partition.c_str(), 1); + gz::utils::setenv("GZ_PARTITION", partition); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/integration/scopedTopicSubscriber_aux.cc b/test/integration/scopedTopicSubscriber_aux.cc index 76c17d508..3bb44f16a 100644 --- a/test/integration/scopedTopicSubscriber_aux.cc +++ b/test/integration/scopedTopicSubscriber_aux.cc @@ -20,6 +20,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -73,7 +76,7 @@ int main(int argc, char **argv) } // Set the partition name for this test. - setenv("GZ_PARTITION", argv[1], 1); + gz::utils::setenv("GZ_PARTITION", argv[1]); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/integration/statistics.cc b/test/integration/statistics.cc index 771d054a3..628d248bf 100644 --- a/test/integration/statistics.cc +++ b/test/integration/statistics.cc @@ -23,6 +23,9 @@ #include "gtest/gtest.h" #include "gz/transport/Node.hh" #include "gz/transport/TransportTypes.hh" + +#include + #include "test_config.hh" using namespace gz; @@ -78,8 +81,8 @@ int main(int argc, char **argv) std::string partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", partition.c_str(), 1); - setenv("GZ_TRANSPORT_TOPIC_STATISTICS", "1", 1); + 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/twoProcsPubSub.cc b/test/integration/twoProcsPubSub.cc index a5a82f20f..e87dc7289 100644 --- a/test/integration/twoProcsPubSub.cc +++ b/test/integration/twoProcsPubSub.cc @@ -20,9 +20,12 @@ #include #include -#include "gtest/gtest.h" #include "gz/transport/Node.hh" #include "gz/transport/TransportTypes.hh" + +#include + +#include "gtest/gtest.h" #include "test_config.hh" using namespace gz; @@ -541,8 +544,8 @@ int main(int argc, char **argv) g_FQNPartition = std::string("/") + partition; // Set the partition name for this process. - setenv("GZ_PARTITION", partition.c_str(), 1); - setenv("GZ_TRANSPORT_TOPIC_STATISTICS", "1", 1); + 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/twoProcsPubSubSubscriber_aux.cc b/test/integration/twoProcsPubSubSubscriber_aux.cc index ccd0f4ccd..49a360a02 100644 --- a/test/integration/twoProcsPubSubSubscriber_aux.cc +++ b/test/integration/twoProcsPubSubSubscriber_aux.cc @@ -21,6 +21,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -157,8 +160,8 @@ int main(int argc, char **argv) } // Set the partition name for this test. - setenv("GZ_PARTITION", argv[1], 1); - setenv("GZ_TRANSPORT_TOPIC_STATISTICS", "1", 1); + 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/twoProcsPublisher_aux.cc b/test/integration/twoProcsPublisher_aux.cc index ee49964bd..ccb49c83f 100644 --- a/test/integration/twoProcsPublisher_aux.cc +++ b/test/integration/twoProcsPublisher_aux.cc @@ -20,6 +20,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "test_config.hh" using namespace gz; @@ -55,7 +58,7 @@ int main(int argc, char **argv) } // Set the partition name for this test. - setenv("GZ_PARTITION", argv[1], 1); + gz::utils::setenv("GZ_PARTITION", argv[1]); advertiseAndPublish(); } diff --git a/test/integration/twoProcsSrvCall.cc b/test/integration/twoProcsSrvCall.cc index 059d3ab00..9ccd9abdc 100644 --- a/test/integration/twoProcsSrvCall.cc +++ b/test/integration/twoProcsSrvCall.cc @@ -23,6 +23,9 @@ #include "gz/transport/Node.hh" #include "gz/transport/TopicUtils.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -339,10 +342,10 @@ int main(int argc, char **argv) partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", partition.c_str(), 1); + gz::utils::setenv("GZ_PARTITION", partition); // Enable verbose mode. - // setenv("GZ_VERBOSE", "1", 1); + // gz::utils::setenv("GZ_VERBOSE", "1"); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/integration/twoProcsSrvCallReplierInc_aux.cc b/test/integration/twoProcsSrvCallReplierInc_aux.cc index 8ef1c4b49..1f27e84fb 100644 --- a/test/integration/twoProcsSrvCallReplierInc_aux.cc +++ b/test/integration/twoProcsSrvCallReplierInc_aux.cc @@ -21,6 +21,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -63,7 +66,7 @@ int main(int argc, char **argv) } // Set the partition name for this test. - setenv("GZ_PARTITION", argv[1], 1); + gz::utils::setenv("GZ_PARTITION", argv[1]); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/integration/twoProcsSrvCallReplier_aux.cc b/test/integration/twoProcsSrvCallReplier_aux.cc index 6dacc1cb9..5b8523590 100644 --- a/test/integration/twoProcsSrvCallReplier_aux.cc +++ b/test/integration/twoProcsSrvCallReplier_aux.cc @@ -20,6 +20,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -53,7 +56,7 @@ int main(int argc, char **argv) } // Set the partition name for this test. - setenv("GZ_PARTITION", argv[1], 1); + gz::utils::setenv("GZ_PARTITION", argv[1]); runReplier(); } diff --git a/test/integration/twoProcsSrvCallStress.cc b/test/integration/twoProcsSrvCallStress.cc index 2f9d71265..f08357928 100644 --- a/test/integration/twoProcsSrvCallStress.cc +++ b/test/integration/twoProcsSrvCallStress.cc @@ -21,6 +21,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -68,7 +71,7 @@ int main(int argc, char **argv) partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", partition.c_str(), 1); + 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 ef93771da..27087049e 100644 --- a/test/integration/twoProcsSrvCallSync1.cc +++ b/test/integration/twoProcsSrvCallSync1.cc @@ -21,6 +21,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -83,10 +86,10 @@ int main(int argc, char **argv) partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", partition.c_str(), 1); + gz::utils::setenv("GZ_PARTITION", partition); // Enable verbose mode. - setenv("GZ_VERBOSE", "1", 1); + 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 d98c112a0..cefa1ef7b 100644 --- a/test/integration/twoProcsSrvCallWithoutInput.cc +++ b/test/integration/twoProcsSrvCallWithoutInput.cc @@ -23,6 +23,9 @@ #include "gz/transport/Node.hh" #include "gz/transport/TopicUtils.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -289,10 +292,10 @@ int main(int argc, char **argv) g_partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", g_partition.c_str(), 1); + gz::utils::setenv("GZ_PARTITION", g_partition); // Enable verbose mode. - // setenv("GZ_VERBOSE", "1", 1); + // gz::utils::setenv("GZ_VERBOSE", "1"); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/integration/twoProcsSrvCallWithoutInputReplierInc_aux.cc b/test/integration/twoProcsSrvCallWithoutInputReplierInc_aux.cc index 195de0791..1cc15a893 100644 --- a/test/integration/twoProcsSrvCallWithoutInputReplierInc_aux.cc +++ b/test/integration/twoProcsSrvCallWithoutInputReplierInc_aux.cc @@ -21,6 +21,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -64,7 +67,7 @@ int main(int argc, char **argv) } // Set the partition name for this test. - setenv("GZ_PARTITION", argv[1], 1); + gz::utils::setenv("GZ_PARTITION", argv[1]); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/integration/twoProcsSrvCallWithoutInputReplier_aux.cc b/test/integration/twoProcsSrvCallWithoutInputReplier_aux.cc index 31eb1c13c..6ab90212d 100644 --- a/test/integration/twoProcsSrvCallWithoutInputReplier_aux.cc +++ b/test/integration/twoProcsSrvCallWithoutInputReplier_aux.cc @@ -20,6 +20,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -54,7 +57,7 @@ int main(int argc, char **argv) } // Set the partition name for this test. - setenv("GZ_PARTITION", argv[1], 1); + gz::utils::setenv("GZ_PARTITION", argv[1]); runReplier(); } diff --git a/test/integration/twoProcsSrvCallWithoutInputStress.cc b/test/integration/twoProcsSrvCallWithoutInputStress.cc index 972cce3a5..7d2fc7c4b 100644 --- a/test/integration/twoProcsSrvCallWithoutInputStress.cc +++ b/test/integration/twoProcsSrvCallWithoutInputStress.cc @@ -21,6 +21,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -65,7 +68,7 @@ int main(int argc, char **argv) g_partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", g_partition.c_str(), 1); + 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 d2177b375..230a96f88 100644 --- a/test/integration/twoProcsSrvCallWithoutInputSync1.cc +++ b/test/integration/twoProcsSrvCallWithoutInputSync1.cc @@ -21,6 +21,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -78,10 +81,10 @@ int main(int argc, char **argv) g_partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", g_partition.c_str(), 1); + gz::utils::setenv("GZ_PARTITION", g_partition); // Enable verbose mode. - setenv("GZ_VERBOSE", "1", 1); + 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 526e2283e..1d365a0be 100644 --- a/test/integration/twoProcsSrvCallWithoutOutput.cc +++ b/test/integration/twoProcsSrvCallWithoutOutput.cc @@ -22,6 +22,9 @@ #include "gz/transport/Node.hh" #include "gz/transport/TopicUtils.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -171,10 +174,10 @@ int main(int argc, char **argv) g_partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", g_partition.c_str(), 1); + gz::utils::setenv("GZ_PARTITION", g_partition); // Enable verbose mode. - // setenv("GZ_VERBOSE", "1", 1); + // gz::utils::setenv("GZ_VERBOSE", "1"); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/integration/twoProcsSrvCallWithoutOutputReplierInc_aux.cc b/test/integration/twoProcsSrvCallWithoutOutputReplierInc_aux.cc index 25dd7216e..8354ddb48 100644 --- a/test/integration/twoProcsSrvCallWithoutOutputReplierInc_aux.cc +++ b/test/integration/twoProcsSrvCallWithoutOutputReplierInc_aux.cc @@ -21,6 +21,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -62,7 +65,7 @@ int main(int argc, char **argv) } // Set the partition name for this test. - setenv("GZ_PARTITION", argv[1], 1); + gz::utils::setenv("GZ_PARTITION", argv[1]); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/integration/twoProcsSrvCallWithoutOutputReplier_aux.cc b/test/integration/twoProcsSrvCallWithoutOutputReplier_aux.cc index 8eff1867f..285b06a60 100644 --- a/test/integration/twoProcsSrvCallWithoutOutputReplier_aux.cc +++ b/test/integration/twoProcsSrvCallWithoutOutputReplier_aux.cc @@ -20,6 +20,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -53,7 +56,7 @@ int main(int argc, char **argv) } // Set the partition name for this test. - setenv("GZ_PARTITION", argv[1], 1); + gz::utils::setenv("GZ_PARTITION", argv[1]); runReplier(); } diff --git a/test/integration/twoProcsSrvCallWithoutOutputStress.cc b/test/integration/twoProcsSrvCallWithoutOutputStress.cc index 3d76b95ec..c32a7e636 100644 --- a/test/integration/twoProcsSrvCallWithoutOutputStress.cc +++ b/test/integration/twoProcsSrvCallWithoutOutputStress.cc @@ -21,6 +21,9 @@ #include #include "gz/transport/Node.hh" + +#include + #include "gtest/gtest.h" #include "test_config.hh" @@ -61,7 +64,7 @@ int main(int argc, char **argv) g_partition = testing::getRandomNumber(); // Set the partition name for this process. - setenv("GZ_PARTITION", g_partition.c_str(), 1); + 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 bc7ea350a..481d35a18 100644 --- a/test/test_config.hh.in +++ b/test/test_config.hh.in @@ -30,21 +30,8 @@ DETAIL_GZ_TRANSPORT_TEST_DIR #endif -#ifndef __APPLE__ - #if (!(defined(__clang__) || __unix__) || \ - (defined(__clang__) && __cplusplus >= 201703L) || \ - (__unix__ && __GNUC__ >= 8)) - #define GZ_HAVE_FILESYSTEM - #endif - - #ifdef GZ_HAVE_FILESYSTEM - #include - #else - #include - #endif -#endif - #include +#include #include #include #include @@ -60,37 +47,6 @@ #include "gz/transport/Helpers.hh" -#if (_MSC_VER >= 1400) // Visual Studio 2005 - #include - - /// \brief setenv/unstenv are not present in Windows. Define them to make - /// the code portable. - /// \param[in] _name Variable name. - /// \param[in] _value Value. - /// \param[in] _rewrite If 'name' does exist in the environment, then its - /// value is changed to 'value' if 'rewrite' is nonzero. If overwrite is - /// zero, then the value of 'name' is not changed. - /// /return 0 on success or -1 on error. - int setenv(const char *_name, const char *_value, int /*_rewrite*/) - { - std::stringstream sstr; - std::string name = _name; - std::string value = _value; - sstr << name << '=' << value; - return _putenv(sstr.str().c_str()); - } - - /// \brief Deletes an environment variable. - /// \param[in] _name Variable name. - void unsetenv(const char *_name) - { - std::stringstream sstr; - std::string name = _name; - sstr << name << '='; - _putenv(sstr.str().c_str()); - } -#endif - namespace testing { /// \brief Join _str1 and _str2 considering both as storing system paths. @@ -100,17 +56,7 @@ namespace testing std::string portablePathUnion(const std::string &_str1, const std::string &_str2) { -#ifdef __APPLE__ - // Ugly as hell but trying to avoid boost::filesystem - return _str1 + "/" + _str2; -#else - #ifdef GZ_HAVE_FILESYSTEM - using namespace std::filesystem; - #else - using namespace std::experimental::filesystem; - #endif - return (path(_str1) / path(_str2)).string(); -#endif + return (std::filesystem::path(_str1) / std::filesystem::path(_str2)).string(); } #ifdef _WIN32 @@ -248,6 +194,6 @@ namespace testing return std::to_string(d(randGenerator)); } -} +} // namespace testing #endif // header guard From 290055f0309ad2be0d20ca58fc8c11d05304104f Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Tue, 28 Nov 2023 16:39:04 -0600 Subject: [PATCH 2/3] Use subprocess rather than custom code (#429) This reworks all of the gz-transport tests to use Subprocess from gz-utils. Signed-off-by: Michael Carroll --- log/src/CMakeLists.txt | 9 +- log/src/Log_TEST.cc | 10 +- log/test/CMakeLists.txt | 4 - log/test/integration/CMakeLists.txt | 46 +- log/test/integration/ChirpParams.cc | 48 ++ log/test/integration/ChirpParams.hh | 185 ++----- log/test/integration/playback.cc | 30 +- log/test/integration/recorder.cc | 14 +- log/test/integration/topicChirp_aux.cc | 7 +- log/test/test_config.hh.in | 24 - src/CMakeLists.txt | 5 +- src/cmd/CMakeLists.txt | 13 +- src/cmd/gz_TEST.cc | 460 ++++++------------ test/integration/CMakeLists.txt | 39 +- test/integration/authPubSub.cc | 16 +- test/integration/scopedTopic.cc | 13 +- test/integration/twoProcsPubSub.cc | 113 +---- test/integration/twoProcsSrvCall.cc | 124 ++--- test/integration/twoProcsSrvCallStress.cc | 14 +- test/integration/twoProcsSrvCallSync1.cc | 14 +- .../twoProcsSrvCallWithoutInput.cc | 110 ++--- .../twoProcsSrvCallWithoutInputStress.cc | 15 +- .../twoProcsSrvCallWithoutInputSync1.cc | 15 +- .../twoProcsSrvCallWithoutOutput.cc | 86 ++-- .../twoProcsSrvCallWithoutOutputStress.cc | 15 +- test/test_config.hh.in | 151 ------ 26 files changed, 490 insertions(+), 1090 deletions(-) create mode 100644 log/test/integration/ChirpParams.cc delete mode 100644 log/test/test_config.hh.in diff --git a/log/src/CMakeLists.txt b/log/src/CMakeLists.txt index 4a9398da4..c285c0efb 100644 --- a/log/src/CMakeLists.txt +++ b/log/src/CMakeLists.txt @@ -24,9 +24,11 @@ gz_build_tests( ) foreach(test_target ${logging_tests}) - - set_tests_properties(${logging_tests} PROPERTIES + set_tests_properties(${test_target} PROPERTIES ENVIRONMENT GZ_TRANSPORT_LOG_SQL_PATH=${PROJECT_SOURCE_DIR}/log/sql) + target_compile_definitions(${test_target} PRIVATE + "CORRUPT_DB_TEST_PATH=\"${CMAKE_SOURCE_DIR}/log/test/data/state.tlog\"" + ) endforeach() @@ -46,9 +48,6 @@ install(DIRECTORY ../sql DESTINATION ${SCHEMA_INSTALL_BASE}) set(SCHEMA_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/${SCHEMA_INSTALL_BASE}/sql) configure_file(build_config.hh.in build_config.hh @ONLY) - -message(STATUS "CMAKE_CURRENT_SOURCE_DIR:${CMAKE_CURRENT_SOURCE_DIR}") - target_include_directories(${log_lib_target} PUBLIC # Add this component's include directory to the build interface include diff --git a/log/src/Log_TEST.cc b/log/src/Log_TEST.cc index f1d683cf8..4ac008344 100644 --- a/log/src/Log_TEST.cc +++ b/log/src/Log_TEST.cc @@ -22,13 +22,16 @@ #include "gz/transport/log/Log.hh" #include "test_config.hh" -#include "log/test_config.hh" #include "gtest/gtest.h" using namespace gz; using namespace gz::transport; using namespace std::chrono_literals; +namespace { +constexpr const char * kCorruptDbTestPath = CORRUPT_DB_TEST_PATH; +} + ////////////////////////////////////////////////// TEST(Log, OpenMemoryDatabase) { @@ -251,10 +254,7 @@ TEST(Log, NullDescriptorUnopenedLog) TEST(Log, OpenCorruptDatabase) { log::Log logFile; - std::string path = - testing::portablePathUnion(GZ_TRANSPORT_LOG_TEST_PATH, "data"); - path = testing::portablePathUnion(path, "state.tlog"); - logFile.Open(path); + logFile.Open(kCorruptDbTestPath); EXPECT_GT(logFile.EndTime(), 0ns) << "logFile.EndTime() == " << logFile.EndTime().count() << "ns";; } diff --git a/log/test/CMakeLists.txt b/log/test/CMakeLists.txt index c11c67f90..26e40e61e 100644 --- a/log/test/CMakeLists.txt +++ b/log/test/CMakeLists.txt @@ -1,5 +1 @@ -configure_file (test_config.hh.in - ${PROJECT_BINARY_DIR}/include/log/test_config.hh -) - add_subdirectory(integration) diff --git a/log/test/integration/CMakeLists.txt b/log/test/integration/CMakeLists.txt index 3459c8aa9..5537f4511 100644 --- a/log/test/integration/CMakeLists.txt +++ b/log/test/integration/CMakeLists.txt @@ -1,5 +1,14 @@ # Integration tests + +add_library(ChirpParams STATIC ./ChirpParams.cc) +target_link_libraries(ChirpParams PUBLIC ${PROJECT_LIBRARY_TARGET_NAME}-log ${EXTRA_TEST_LIB_DEPS}) +target_compile_definitions(ChirpParams + PRIVATE TOPIC_CHIRP_EXE="$") + +gz_add_executable(topicChirp_aux topicChirp_aux.cc) +target_link_libraries(topicChirp_aux ChirpParams) + gz_build_tests( TYPE "INTEGRATION" TEST_LIST logging_tests @@ -8,6 +17,7 @@ gz_build_tests( playback.cc query.cc LIB_DEPS + ChirpParams ${PROJECT_LIBRARY_TARGET_NAME}-log ${EXTRA_TEST_LIB_DEPS} INCLUDE_DIRS @@ -21,48 +31,12 @@ if (UNIX AND NOT APPLE) endif() foreach(test_target ${logging_tests}) - set_tests_properties(${test_target} PROPERTIES ENVIRONMENT GZ_TRANSPORT_LOG_SQL_PATH=${PROJECT_SOURCE_DIR}/log/sql) target_compile_definitions(${test_target} PRIVATE GZ_TRANSPORT_LOG_SQL_PATH="${PROJECT_SOURCE_DIR}/log/sql") - target_compile_definitions(${test_target} - PRIVATE GZ_TRANSPORT_LOG_BUILD_PATH="$") - endforeach() -set (aux - topicChirp_aux.cc -) - -foreach(source_file ${aux}) - string(REGEX REPLACE ".cc" "" AUX_EXECUTABLE ${source_file}) - set(BINARY_NAME ${TEST_TYPE}_${AUX_EXECUTABLE}) - - gz_add_executable(${BINARY_NAME} ${AUX_EXECUTABLE}.cc) - - # Include the interface directories that we always need. - gz_target_interface_include_directories(${BINARY_NAME} - ${PROJECT_LIBRARY_TARGET_NAME}) - - # Link the libraries that we always need. - target_link_libraries(${BINARY_NAME} - PRIVATE - ${PROJECT_LIBRARY_TARGET_NAME} - ${log_lib_target} - gtest - ${EXTRA_TEST_LIB_DEPS} - ) - - if(UNIX) - # pthread is only available on Unix machines - target_link_libraries(${BINARY_NAME} - PRIVATE pthread) - endif() - - target_compile_definitions(${BINARY_NAME} - PRIVATE GZ_TRANSPORT_LOG_BUILD_PATH="$") -endforeach() # gz log CLI test if (HAVE_GZ_TOOLS) diff --git a/log/test/integration/ChirpParams.cc b/log/test/integration/ChirpParams.cc new file mode 100644 index 000000000..ba0a517d5 --- /dev/null +++ b/log/test/integration/ChirpParams.cc @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +#include "ChirpParams.hh" + +#include +#include + +static constexpr const char* kTopicChirpExe = TOPIC_CHIRP_EXE; + +namespace gz::transport::log::test +{ + gz::utils::Subprocess BeginChirps( + const std::vector &_topics, + const int _chirps, + const std::string &_partitionName) + { + // Argument list: + // [0]: Executable name + // [1]: Partition name + // [2]: Number of chirps + // [3]-[N]: Each topic name + // [N+1]: Null terminator, required by execv + const std::size_t numArgs = 3 + _topics.size() + 1; + + std::vector strArgs; + strArgs.reserve(numArgs-1); + strArgs.push_back(kTopicChirpExe); + strArgs.push_back(_partitionName); + strArgs.push_back(std::to_string(_chirps)); + strArgs.insert(strArgs.end(), _topics.begin(), _topics.end()); + return gz::utils::Subprocess(strArgs); + } +} // namespace gz::transport::log::test diff --git a/log/test/integration/ChirpParams.hh b/log/test/integration/ChirpParams.hh index 5a4ddaec4..5331df5ab 100644 --- a/log/test/integration/ChirpParams.hh +++ b/log/test/integration/ChirpParams.hh @@ -18,162 +18,45 @@ #ifndef GZ_TRANSPORT_LOG_TEST_INTEGRATION_CHIRPPARAMS_HH_ #define GZ_TRANSPORT_LOG_TEST_INTEGRATION_CHIRPPARAMS_HH_ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4251) -#endif -#include -#ifdef _MSC_VER -#pragma warning(pop) -#endif -#include - #include #include +#include #include +#include - -namespace gz +namespace gz::transport::log::test { - namespace transport - { - namespace log - { - namespace test - { - /// \brief Parameter used to determine how long the topicChirp_aux - /// program will wait between emitting message chirps from its topic. - /// Value is in milliseconds. - const int DelayBetweenChirps_ms = 1; - - /// \brief Parameter used to determine how long the topicChirp_aux - /// program will wait (after it advertises) before it begins publishing - /// its message chirps. Value is in milliseconds. - const int DelayBeforePublishing_ms = 1000; - - /// \brief This is the message type that will be used by the chirping - /// topics. - using ChirpMsgType = gz::msgs::Int32; - - - ////////////////////////////////////////////////// - /// \brief Similar to testing::forkAndRun(), except this function - /// specifically calls the INTEGRATION_topicChirp_aux process and passes - /// it arguments to determine how it should chirp out messages over its - /// topics. - /// \param _topics A list of topic names to chirp on - /// \param _chirps The number of messages to chirp out. Each message - /// will count up starting from the value 1 and ending with the value - /// _chirps. - /// \return A handle to the process. This can be used with - /// testing::waitAndCleanupFork(). - testing::forkHandlerType BeginChirps( - const std::vector &_topics, - const int _chirps, - const std::string &_partitionName) - { - // Set the chirping process name - const std::string process = - GZ_TRANSPORT_LOG_BUILD_PATH"/INTEGRATION_topicChirp_aux"; - - // Argument list: - // [0]: Executable name - // [1]: Partition name - // [2]: Number of chirps - // [3]-[N]: Each topic name - // [N+1]: Null terminator, required by execv - const std::size_t numArgs = 3 + _topics.size() + 1; - - std::vector strArgs; - strArgs.reserve(numArgs-1); - strArgs.push_back(process); - strArgs.push_back(_partitionName); - strArgs.push_back(std::to_string(_chirps)); - strArgs.insert(strArgs.end(), _topics.begin(), _topics.end()); - - #ifdef _MSC_VER - std::string fullArgs; - for (std::size_t i = 0; i < strArgs.size(); ++i) - { - if (i == 0) - { - // Windows prefers quotes around the process name - fullArgs += "\""; - } - else - { - fullArgs += " "; - } - - fullArgs += strArgs[i]; - - if (i == 0) - { - fullArgs += "\""; - } - } - - char * args = new char[fullArgs.size()+1]; - std::snprintf(args, fullArgs.size()+1, "%s", fullArgs.c_str()); - - STARTUPINFO info = {sizeof(info)}; - PROCESS_INFORMATION processInfo; - - if (!CreateProcess(nullptr, args, nullptr, nullptr, - TRUE, 0, nullptr, nullptr, &info, &processInfo)) - { - std::cerr << "Error running the chirp process [" - << args << "]\n"; - } - - delete[] args; - - return processInfo; - #else - // Create a raw char* array to pass to execv - char * * args = new char*[numArgs]; - - // Allocate a char array for each argument and copy the data to it - for (std::size_t i = 0; i < strArgs.size(); ++i) - { - const std::string &arg = strArgs[i]; - args[i] = new char[arg.size()+1]; - std::snprintf(args[i], arg.size()+1, "%s", arg.c_str()); - } - - // The last item in the char array must be a nullptr, according to the - // documentation of execv - args[numArgs-1] = nullptr; - - testing::forkHandlerType pid = fork(); - - if (pid == 0) - { - if (execv(process.c_str(), args) == -1) - { - int err = errno; - std::cerr << "Error running the chirp process [" << err << "]: " - << strerror(err) << "\n"; - } - } - - // Clean up the array of arguments - for (std::size_t i = 0; i < numArgs; ++i) - { - char *arg = args[i]; - delete[] arg; - arg = nullptr; - } - delete[] args; - args = nullptr; - - return pid; - #endif - } - } - } - } -} + /// \brief Parameter used to determine how long the topicChirp_aux + /// program will wait between emitting message chirps from its topic. + /// Value is in milliseconds. + const int DelayBetweenChirps_ms = 1; + + /// \brief Parameter used to determine how long the topicChirp_aux + /// program will wait (after it advertises) before it begins publishing + /// its message chirps. Value is in milliseconds. + const int DelayBeforePublishing_ms = 1000; + + /// \brief This is the message type that will be used by the chirping + /// topics. + using ChirpMsgType = gz::msgs::Int32; + + ////////////////////////////////////////////////// + /// \brief Similar to testing::forkAndRun(), except this function + /// specifically calls the INTEGRATION_topicChirp_aux process and passes + /// it arguments to determine how it should chirp out messages over its + /// topics. + /// \param[in] _topics A list of topic names to chirp on + /// \param[in] _chirps The number of messages to chirp out. Each message + /// will count up starting from the value 1 and ending with the value + /// _chirps. + /// \param[in] _paritionName Gz transport partition to use for the test + /// \return A handle to the process. This can be used with + /// testing::waitAndCleanupFork(). + gz::utils::Subprocess BeginChirps( + const std::vector &_topics, + const int _chirps, + const std::string &_partitionName); +} // namespace gz::transport::log::test #endif diff --git a/log/test/integration/playback.cc b/log/test/integration/playback.cc index dd2166670..df892ec05 100644 --- a/log/test/integration/playback.cc +++ b/log/test/integration/playback.cc @@ -24,8 +24,10 @@ #include #include +#include #include "ChirpParams.hh" +#include "test_config.hh" static std::string partition; @@ -125,11 +127,11 @@ TEST(playback, GZ_UTILS_TEST_DISABLED_ON_MAC(ReplayLog)) recorder.Start(logName)); const int numChirps = 100; - testing::forkHandlerType chirper = + auto chirper = gz::transport::log::test::BeginChirps(topics, numChirps, partition); // Wait for the chirping to finish - testing::waitAndCleanupFork(chirper); + chirper.Join(); // Wait to make sure our callbacks are done processing the incoming messages std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -226,11 +228,11 @@ TEST(playback, GZ_UTILS_TEST_DISABLED_ON_MAC(ReplayLogRegex)) recorder.Start(logName)); const int numChirps = 100; - testing::forkHandlerType chirper = + auto chirper = gz::transport::log::test::BeginChirps(topics, numChirps, partition); // Wait for the chirping to finish - testing::waitAndCleanupFork(chirper); + chirper.Join(); // Wait to make sure our callbacks are done processing the incoming messages std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -293,11 +295,11 @@ TEST(playback, GZ_UTILS_TEST_DISABLED_ON_MAC(RemoveTopic)) recorder.Start(logName)); const int numChirps = 100; - testing::forkHandlerType chirper = + auto chirper = gz::transport::log::test::BeginChirps(topics, numChirps, partition); // Wait for the chirping to finish - testing::waitAndCleanupFork(chirper); + chirper.Join(); // Wait to make sure our callbacks are done processing the incoming messages std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -404,11 +406,11 @@ TEST(playback, GZ_UTILS_TEST_DISABLED_ON_MAC(ReplayLogMoveInstances)) recorder.Start(logName)); const int numChirps = 100; - testing::forkHandlerType chirper = + auto chirper = gz::transport::log::test::BeginChirps(topics, numChirps, partition); // Wait for the chirping to finish - testing::waitAndCleanupFork(chirper); + chirper.Join(); // Wait to make sure our callbacks are done processing the incoming messages std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -471,11 +473,11 @@ TEST(playback, GZ_UTILS_TEST_DISABLED_ON_MAC(ReplayPauseResume)) recorder.Start(logName)); const int numChirps = 100; - testing::forkHandlerType chirper = + auto chirper = gz::transport::log::test::BeginChirps(topics, numChirps, partition); // Wait for the chirping to finish - testing::waitAndCleanupFork(chirper); + chirper.Join(); // Wait to make sure our callbacks are done processing the incoming messages std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -593,11 +595,11 @@ TEST(playback, GZ_UTILS_TEST_DISABLED_ON_MAC(ReplayStep)) recorder.Start(logName)); const int numChirps = 100; - testing::forkHandlerType chirper = + auto chirper = gz::transport::log::test::BeginChirps(topics, numChirps, partition); // Wait for the chirping to finish - testing::waitAndCleanupFork(chirper); + chirper.Join(); // Wait to make sure our callbacks are done processing the incoming messages std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -709,11 +711,11 @@ TEST(playback, GZ_UTILS_TEST_DISABLED_ON_MAC(ReplaySeek)) recorder.Start(logName)); const int numChirps = 100; - testing::forkHandlerType chirper = + auto chirper = gz::transport::log::test::BeginChirps(topics, numChirps, partition); // Wait for the chirping to finish - testing::waitAndCleanupFork(chirper); + chirper.Join(); // Wait to make sure our callbacks are done processing the incoming messages std::this_thread::sleep_for(std::chrono::seconds(1)); diff --git a/log/test/integration/recorder.cc b/log/test/integration/recorder.cc index a78617155..ff6eade39 100644 --- a/log/test/integration/recorder.cc +++ b/log/test/integration/recorder.cc @@ -28,6 +28,8 @@ #include #include +#include "test_config.hh" + #include "ChirpParams.hh" static std::string partition; @@ -96,11 +98,11 @@ TEST(recorder, EXPECT_EQ(logName, recorder.Filename()); const int numChirps = 100; - testing::forkHandlerType chirper = + auto chirper = gz::transport::log::test::BeginChirps(topics, numChirps, partition); // Wait for the chirping to finish - testing::waitAndCleanupFork(chirper); + chirper.Join(); // Wait to make sure our callbacks are done processing the incoming messages std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -160,7 +162,7 @@ TEST(recorder, BeginRecordingTopicsAfterAdvertisement) const int numChirps = static_cast( std::ceil(secondsToChirpFor * 1000.0/static_cast(delay_ms))); - testing::forkHandlerType chirper = + auto chirper = gz::transport::log::test::BeginChirps(topics, numChirps, partition); const int waitBeforeSubscribing_ms = @@ -182,7 +184,7 @@ TEST(recorder, BeginRecordingTopicsAfterAdvertisement) gz::transport::log::RecorderError::SUCCESS); // Wait for the chirping to finish - testing::waitAndCleanupFork(chirper); + chirper.Join(); // Wait to make sure our callbacks are done processing the incoming messages std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -233,11 +235,11 @@ void RecordPatternBeforeAdvertisement(const std::regex &_pattern) gz::transport::log::RecorderError::SUCCESS); const int numChirps = 100; - testing::forkHandlerType chirper = + auto chirper = gz::transport::log::test::BeginChirps(topics, numChirps, partition); // Wait for the chirping to finish - testing::waitAndCleanupFork(chirper); + chirper.Join(); // Wait to make sure our callbacks are done processing the incoming messages std::this_thread::sleep_for(std::chrono::seconds(1)); diff --git a/log/test/integration/topicChirp_aux.cc b/log/test/integration/topicChirp_aux.cc index 94f2942b3..aa9a18b11 100644 --- a/log/test/integration/topicChirp_aux.cc +++ b/log/test/integration/topicChirp_aux.cc @@ -15,11 +15,10 @@ * */ -#include - #include #include +#include #include #include @@ -40,13 +39,11 @@ void chirp(const std::vector &_topicNames, gz::transport::Node node; - using MsgType = gz::transport::log::test::ChirpMsgType; - std::vector publishers; for (const std::string &topic : _topicNames) { - publishers.push_back(node.Advertise(topic)); + publishers.push_back(node.Advertise(topic)); } std::this_thread::sleep_for( diff --git a/log/test/test_config.hh.in b/log/test/test_config.hh.in deleted file mode 100644 index 9c354ae0b..000000000 --- a/log/test/test_config.hh.in +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2019 Open Source Robotics Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - -#ifndef GZ_TRANSPORT_LOG_TEST_CONFIG_HH_ -#define GZ_TRANSPORT_LOG_TEST_CONFIG_HH_ - - -#define GZ_TRANSPORT_LOG_TEST_PATH "@CMAKE_SOURCE_DIR@/log/test" - -#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cfb71dd55..bed76c64d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,7 +16,7 @@ target_link_libraries(${PROJECT_LIBRARY_TARGET_NAME} ) target_include_directories(${PROJECT_LIBRARY_TARGET_NAME} - SYSTEM PUBLIC + SYSTEM PUBLIC $ $) @@ -39,9 +39,10 @@ foreach(test ${test_list}) # auxiliary files from. Using a generator expression here is useful for # multi-configuration generators, like Visual Studio. target_compile_definitions(${test} PRIVATE - "DETAIL_GZ_TRANSPORT_TEST_DIR=\"$\"" "GZ_TEST_LIBRARY_PATH=\"$\"") + set_property(TEST ${test} PROPERTY ENVIRONMENT "GZ_VERBOSE=1") + endforeach() if(MSVC) diff --git a/src/cmd/CMakeLists.txt b/src/cmd/CMakeLists.txt index 269d66f38..9a559f1d7 100644 --- a/src/cmd/CMakeLists.txt +++ b/src/cmd/CMakeLists.txt @@ -8,6 +8,10 @@ if (MSVC) list(REMOVE_ITEM gtest_sources gz_TEST.cc) endif() +if (NOT HAVE_GZ_TOOLS) + list(REMOVE_ITEM gtest_sources gz_TEST.cc) +endif() + # Make a small static lib of command line functions add_library(gz STATIC gz.cc) target_link_libraries(gz @@ -40,15 +44,18 @@ gz_build_tests(TYPE UNIT SOURCES ${gtest_sources} LIB_DEPS ${EXTRA_TEST_LIB_DEPS}) foreach(test ${test_list}) - target_link_libraries(${test} gz) + target_link_libraries(${test} gz gz-utils${GZ_UTILS_VER}::gz-utils${GZ_UTILS_VER}) # Inform each test of its output directory so it knows where to call the # auxiliary files from. Using a generator expression here is useful for # multi-configuration generators, like Visual Studio. target_compile_definitions(${test} PRIVATE - "DETAIL_GZ_TRANSPORT_TEST_DIR=\"$\"" "GZ_TEST_LIBRARY_PATH=\"$\"" - "PROJECT_SOURCE_DIR=\"${PROJECT_SOURCE_DIR}\"") + "PROJECT_SOURCE_DIR=\"${PROJECT_SOURCE_DIR}\"" + "TWO_PROCS_PUBLISHER_EXE=\"$\"" + "TWO_PROCS_SRV_CALL_REPLIER_EXE=\"$\"" + "GZ_EXE=\"${HAVE_GZ_TOOLS}\"" + ) endforeach() diff --git a/src/cmd/gz_TEST.cc b/src/cmd/gz_TEST.cc index ff5dcb7ff..5a6158e72 100644 --- a/src/cmd/gz_TEST.cc +++ b/src/cmd/gz_TEST.cc @@ -25,44 +25,25 @@ #include #include +#include #include "gtest/gtest.h" #include "gz/transport/Node.hh" #include "test_config.hh" -#ifdef _MSC_VER -# define popen _popen -# define pclose _pclose -#endif - using namespace gz; static std::string g_partition; // NOLINT(*) static std::string g_topicCBStr; // NOLINT(*) -static const std::string g_gzVersion("--force-version " + // NOLINT(*) - std::string(GZ_VERSION_FULL)); -///////////////////////////////////////////////// -std::string custom_exec_str(std::string _cmd) +namespace { - _cmd += " 2>&1"; - FILE *pipe = popen(_cmd.c_str(), "r"); - - if (!pipe) - return "ERROR"; - - char buffer[128]; - std::string result = ""; - - while (!feof(pipe)) - { - if (fgets(buffer, 128, pipe) != NULL) - result += buffer; - } - - pclose(pipe); - return result; -} +constexpr const char * kGzExe = GZ_EXE; +constexpr const char * kTwoProcsPublisherExe = TWO_PROCS_PUBLISHER_EXE; +constexpr const char * kTwoProcsSrvCallReplierExe = + TWO_PROCS_SRV_CALL_REPLIER_EXE; +constexpr const char * kGzVersion = GZ_VERSION_FULL; +} // namespace ////////////////////////////////////////////////// /// \brief Provide a service. @@ -80,34 +61,56 @@ void topicCB(const msgs::StringMsg &_msg) } ////////////////////////////////////////////////// -/// \brief Check 'gz topic -l' running the advertiser on a different process. -TEST(gzTest, GZ_UTILS_TEST_DISABLED_ON_MAC(TopicList)) +struct ProcessOutput { - // Launch a new publisher process that advertises a topic. - std::string publisher_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsPublisher_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisher_path.c_str(), - g_partition.c_str()); + int code {-1}; + std::string cout; + std::string cerr; +}; - // Check the 'gz topic -l' command. - std::string gz = std::string(GZ_PATH); +////////////////////////////////////////////////// +ProcessOutput custom_exec_str(const std::vector &_args) +{ + auto fullArgs = std::vector{kGzExe}; + std::copy(std::begin(_args), std::end(_args), std::back_inserter(fullArgs)); + fullArgs.emplace_back("--force-version"); + fullArgs.emplace_back(kGzVersion); + auto proc = gz::utils::Subprocess(fullArgs); + auto return_code = proc.Join(); + return {return_code, proc.Stdout(), proc.Stderr()}; +} - unsigned int retries = 0u; - bool topicFound = false; +////////////////////////////////////////////////// +std::optional +exec_with_retry(const std::vector &_args, + const std::function &_condition) +{ + bool success = false; + int retries = 0; - while (!topicFound && retries++ < 10u) + while (!success && retries++ < 10) { - std::string output = custom_exec_str(gz + " topic -l " + g_gzVersion); - topicFound = output == "/foo\n"; + auto output = custom_exec_str(_args); + success = _condition(output); + if (success) + return output; std::this_thread::sleep_for(std::chrono::milliseconds(300)); } + return {}; +} - EXPECT_TRUE(topicFound); +////////////////////////////////////////////////// +/// \brief Check 'gz topic -l' running the advertiser on a different process. +TEST(gzTest, GZ_UTILS_TEST_DISABLED_ON_MAC(TopicList)) +{ + auto proc = gz::utils::Subprocess({kTwoProcsPublisherExe, g_partition}); + + auto output = exec_with_retry({"topic", "-l"}, + [](auto procOut){ + return procOut.cout == "/foo\n"; + }); - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); + EXPECT_TRUE(output); } ////////////////////////////////////////////////// @@ -115,34 +118,18 @@ TEST(gzTest, GZ_UTILS_TEST_DISABLED_ON_MAC(TopicList)) TEST(gzTest, TopicInfo) { // Launch a new publisher process that advertises a topic. - std::string publisher_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsPublisher_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisher_path.c_str(), - g_partition.c_str()); + auto proc = gz::utils::Subprocess({kTwoProcsPublisherExe, g_partition}); - // Check the 'gz topic -i' command. - std::string gz = std::string(GZ_PATH); + auto output = exec_with_retry({"topic", "-t", "/foo", "-i"}, + [](auto procOut){ + return procOut.cout.size() > 50u; + }); - unsigned int retries = 0u; - bool infoFound = false; - std::string output; - while (!infoFound && retries++ < 10u) - { - output = custom_exec_str(gz + " topic -t /foo -i " + g_gzVersion); - infoFound = output.size() > 50u; - std::this_thread::sleep_for(std::chrono::milliseconds(300)); - } - - EXPECT_TRUE(infoFound) << "OUTPUT[" - << output << "] Size[" << output.size() + ASSERT_TRUE(output) << "OUTPUT[" + << output->cout << "] Size[" << output->cout.size() << "]. Expected Size=50" << std::endl; - EXPECT_TRUE(output.find("gz.msgs.Vector3d") != std::string::npos); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); + EXPECT_TRUE(output->cout.find("gz.msgs.Vector3d") != std::string::npos); } ////////////////////////////////////////////////// @@ -151,63 +138,30 @@ TEST(gzTest, TopicInfo) TEST(gzTest, ServiceList) { // Launch a new responser process that advertises a service. - std::string replier_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(replier_path.c_str(), - g_partition.c_str()); - - // Check the 'gz service -l' command. - std::string gz = std::string(GZ_PATH); - - unsigned int retries = 0u; - bool serviceFound = false; - - while (!serviceFound && retries++ < 10u) - { - std::string output = custom_exec_str(gz + " service -l " + g_gzVersion); - serviceFound = output == "/foo\n"; - std::this_thread::sleep_for(std::chrono::milliseconds(300)); - } + auto proc = gz::utils::Subprocess({kTwoProcsSrvCallReplierExe, g_partition}); - EXPECT_TRUE(serviceFound); + auto output = exec_with_retry({"service", "-l"}, + [](auto procOut){ + return procOut.cout == "/foo\n"; + }); - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); + EXPECT_TRUE(output); } ////////////////////////////////////////////////// /// \brief Check 'gz service -i' running the advertiser on a different process. TEST(gzTest, ServiceInfo) { - // Launch a new publisher process that advertises a topic. - std::string replier_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(replier_path.c_str(), - g_partition.c_str()); - - // Check the 'gz service -i' command. - std::string gz = std::string(GZ_PATH); - - unsigned int retries = 0u; - bool infoFound = false; - std::string output; - - while (!infoFound && retries++ < 10u) - { - output = custom_exec_str(gz + " service -s /foo -i " + g_gzVersion); - infoFound = output.size() > 50u; - std::this_thread::sleep_for(std::chrono::milliseconds(300)); - } + // Launch a new responser process that advertises a service. + auto proc = gz::utils::Subprocess({kTwoProcsSrvCallReplierExe, g_partition}); - EXPECT_TRUE(infoFound); - EXPECT_TRUE(output.find("gz.msgs.Int32") != std::string::npos); + auto output = exec_with_retry({"service", "-s", "/foo", "-i"}, + [](auto procOut){ + return procOut.cout.size() > 50u; + }); - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); + ASSERT_TRUE(output); + EXPECT_TRUE(output->cout.find("gz.msgs.Int32") != std::string::npos); } ////////////////////////////////////////////////// @@ -225,20 +179,12 @@ TEST(gzTest, TopicListSameProc) EXPECT_TRUE(pub); EXPECT_TRUE(pub.Publish(msg)); - // Check the 'gz topic -l' command. - std::string gz = std::string(GZ_PATH); - - unsigned int retries = 0u; - bool topicFound = false; - - while (!topicFound && retries++ < 10u) - { - std::string output = custom_exec_str(gz + " topic -l " + g_gzVersion); - topicFound = output == "/foo\n"; - std::this_thread::sleep_for(std::chrono::milliseconds(300)); - } + auto output = exec_with_retry({"topic", "-l"}, + [](auto procOut){ + return procOut.cout == "/foo\n"; + }); - EXPECT_TRUE(topicFound); + EXPECT_TRUE(output); } ////////////////////////////////////////////////// @@ -256,22 +202,13 @@ TEST(gzTest, TopicInfoSameProc) EXPECT_TRUE(pub); EXPECT_TRUE(pub.Publish(msg)); - // Check the 'gz topic -i' command. - std::string gz = std::string(GZ_PATH); - - unsigned int retries = 0u; - bool infoFound = false; - std::string output; - - while (!infoFound && retries++ < 10u) - { - output = custom_exec_str(gz + " topic -t /foo -i " + g_gzVersion); - infoFound = output.size() > 50u; - std::this_thread::sleep_for(std::chrono::milliseconds(300)); - } + auto output = exec_with_retry({"topic", "-t", "/foo", "-i"}, + [](auto procOut){ + return procOut.cout.size() > 50u; + }); - EXPECT_TRUE(infoFound); - EXPECT_TRUE(output.find("gz.msgs.Vector3d") != std::string::npos); + ASSERT_TRUE(output); + EXPECT_TRUE(output->cout.find("gz.msgs.Vector3d") != std::string::npos); } ////////////////////////////////////////////////// @@ -281,20 +218,12 @@ TEST(gzTest, ServiceListSameProc) transport::Node node; EXPECT_TRUE(node.Advertise("/foo", srvEcho)); - // Check the 'gz service -l' command. - std::string gz = std::string(GZ_PATH); - - unsigned int retries = 0u; - bool serviceFound = false; - - while (!serviceFound && retries++ < 10u) - { - std::string output = custom_exec_str(gz + " service -l " + g_gzVersion); - serviceFound = output == "/foo\n"; - std::this_thread::sleep_for(std::chrono::milliseconds(300)); - } + auto output = exec_with_retry({"service", "-l"}, + [](auto procOut){ + return procOut.cout == "/foo\n"; + }); - EXPECT_TRUE(serviceFound); + EXPECT_TRUE(output); } ////////////////////////////////////////////////// @@ -304,25 +233,15 @@ TEST(gzTest, ServiceInfoSameProc) transport::Node node; EXPECT_TRUE(node.Advertise("/foo", srvEcho)); - // Check the 'gz service -i' command. - std::string gz = std::string(GZ_PATH); - - unsigned int retries = 0u; - bool infoFound = false; - std::string output; - - while (!infoFound && retries++ < 10u) - { - output = custom_exec_str(gz + " service -s /foo -i " + g_gzVersion); - infoFound = output.size() > 50u; - std::this_thread::sleep_for(std::chrono::milliseconds(300)); - } + auto output = exec_with_retry({"service", "-s", "/foo", "-i"}, + [](auto procOut){ + return procOut.cout.size() > 50u; + }); - EXPECT_TRUE(infoFound); - EXPECT_TRUE(output.find("gz.msgs.Int32") != std::string::npos); + ASSERT_TRUE(output); + EXPECT_TRUE(output->cout.find("gz.msgs.Int32") != std::string::npos); } - ////////////////////////////////////////////////// /// \brief Check 'gz topic -p' to send a message. TEST(gzTest, TopicPublish) @@ -331,45 +250,45 @@ TEST(gzTest, TopicPublish) g_topicCBStr = "bad_value"; EXPECT_TRUE(node.Subscribe("/bar", topicCB)); - // Check the 'gz topic -p' command. - std::string gz = std::string(GZ_PATH); - std::string output; - unsigned int retries = 0; - while (g_topicCBStr != "good_value" && retries++ < 200u) + while (retries++ < 100u) { - // Send on alternating retries - if (retries % 2) - { - output = custom_exec_str(gz + - " topic -t /bar -m gz_msgs.StringMsg -p 'data:\"good_value\"' " + - g_gzVersion); - EXPECT_TRUE(output.empty()) << output; - } - std::this_thread::sleep_for(std::chrono::milliseconds(30)); + auto output = custom_exec_str({"topic", + "-t", "/bar", + "-m", "gz.msgs.StringMsg", + "-p", "data: \"good_value\""}); + + EXPECT_TRUE(output.cout.empty()); + EXPECT_TRUE(output.cerr.empty()); + if (g_topicCBStr == "good_value") + break; + std::this_thread::sleep_for(std::chrono::milliseconds(60)); } EXPECT_EQ(g_topicCBStr, "good_value"); // Try to publish a message not included in Gazebo Messages. std::string error = "Unable to create message of type"; - output = custom_exec_str(gz + - " topic -t /bar -m gz_msgs.__bad_msg_type -p 'data:\"good_value\"' " + - g_gzVersion); - EXPECT_EQ(output.compare(0, error.size(), error), 0); + auto output = custom_exec_str({"topic", + "-t", "/bar", + "-m", "gz.msgs.__bad_msg_type", + "-p", R"(data: "good_value")"}); + EXPECT_EQ(output.cerr.compare(0, error.size(), error), 0); // Try to publish using an incorrect topic name. error = "Topic [/] is not valid"; - output = custom_exec_str(gz + - " topic -t / -m gz_msgs.StringMsg -p 'data:\"good_value\"' "+ - g_gzVersion); - EXPECT_EQ(output.compare(0, error.size(), error), 0) << output; + output = custom_exec_str({"topic", + "-t", "/", + "-m", "gz.msgs.StringMsg", + "-p", R"(data: "good_value")"}); + EXPECT_EQ(output.cerr.compare(0, error.size(), error), 0); // Try to publish using an incorrect number of arguments. error = "The following argument was not expected: wrong_topic"; - output = custom_exec_str(gz + - " topic -t / wrong_topic -m gz_msgs.StringMsg -p 'data:\"good_value\"' "+ - g_gzVersion); - EXPECT_EQ(output.compare(0, error.size(), error), 0) << output; + output = custom_exec_str({"topic", + "-t", "/", "wrong_topic", + "-m", "gz.msgs.StringMsg", + "-p", R"(data: "good_value")"}); + EXPECT_EQ(output.cerr.compare(0, error.size(), error), 0); } ////////////////////////////////////////////////// @@ -387,13 +306,13 @@ TEST(gzTest, ServiceRequest) msg.set_data(10); // Check the 'gz service -r' command. - std::string gz = std::string(GZ_PATH); - std::string output = custom_exec_str(gz + - " service -s " + service + " --reqtype gz_msgs.Int32 " + - "--reptype gz_msgs.Int32 --timeout 1000 " + - "--req 'data: " + value + "' " + g_gzVersion); - - ASSERT_EQ(output, "data: " + value + "\n\n"); + auto output = custom_exec_str({"service", + "-s", service, + "--reqtype", "gz_msgs.Int32", + "--reptype", "gz_msgs.Int32", + "--timeout", "1000", + "--req", "data: " + value}); + ASSERT_EQ(output.cout, "data: " + value + "\n\n"); } ////////////////////////////////////////////////// @@ -401,24 +320,14 @@ TEST(gzTest, ServiceRequest) TEST(gzTest, TopicEcho) { // Launch a new publisher process that advertises a topic. - std::string publisher_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsPublisher_aux"); + auto proc = gz::utils::Subprocess({kTwoProcsPublisherExe, g_partition}); - testing::forkHandlerType pi = testing::forkAndRun(publisher_path.c_str(), - g_partition.c_str()); + auto output = custom_exec_str( + {"topic", "-e", "-t", "/foo", "-d", "1.5"}); - // Check the 'gz topic -e' command. - std::string gz = std::string(GZ_PATH); - std::string output = custom_exec_str( - gz + " topic -e -t /foo -d 1.5 " + g_gzVersion); - - EXPECT_TRUE(output.find("x: 1") != std::string::npos); - EXPECT_TRUE(output.find("y: 2") != std::string::npos); - EXPECT_TRUE(output.find("z: 3") != std::string::npos); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); + EXPECT_TRUE(output.cout.find("x: 1") != std::string::npos); + EXPECT_TRUE(output.cout.find("y: 2") != std::string::npos); + EXPECT_TRUE(output.cout.find("z: 3") != std::string::npos); } ////////////////////////////////////////////////// @@ -427,110 +336,33 @@ TEST(gzTest, TopicEcho) TEST(gzTest, TopicEchoNum) { // Launch a new publisher process that advertises a topic. - std::string publisher_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsPublisher_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisher_path.c_str(), - g_partition.c_str()); + auto proc = gz::utils::Subprocess({kTwoProcsPublisherExe, g_partition}); - // Check the 'gz topic -e -n' command. - std::string gz = std::string(GZ_PATH); - std::string output = custom_exec_str( - gz + " topic -e -t /foo -n 2 " + g_gzVersion); + auto output = custom_exec_str( + {"topic", "-e", "-t", "/foo", "-n", "2"}); - size_t pos = output.find("x: 1"); + size_t pos = output.cout.find("x: 1"); EXPECT_TRUE(pos != std::string::npos); - pos = output.find("x: 1", pos + 4); + pos = output.cout.find("x: 1", pos + 4); EXPECT_TRUE(pos != std::string::npos); - pos = output.find("x: 1", pos + 4); + pos = output.cout.find("x: 1", pos + 4); EXPECT_TRUE(pos == std::string::npos); - pos = output.find("y: 2"); + pos = output.cout.find("y: 2"); EXPECT_TRUE(pos != std::string::npos); - pos = output.find("y: 2", pos + 4); + pos = output.cout.find("y: 2", pos + 4); EXPECT_TRUE(pos != std::string::npos); - pos = output.find("y: 2", pos + 4); + pos = output.cout.find("y: 2", pos + 4); EXPECT_TRUE(pos == std::string::npos); - pos = output.find("z: 3"); + pos = output.cout.find("z: 3"); EXPECT_TRUE(pos != std::string::npos); - pos = output.find("z: 3", pos + 4); + pos = output.cout.find("z: 3", pos + 4); EXPECT_TRUE(pos != std::string::npos); - pos = output.find("z: 3", pos + 4); + pos = output.cout.find("z: 3", pos + 4); EXPECT_TRUE(pos == std::string::npos); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); -} - -////////////////////////////////////////////////// -/// \brief Check 'gz service --help' message and bash completion script for -/// consistent flags -TEST(gzTest, ServiceHelpVsCompletionFlags) -{ - // Flags in help message - std::string helpOutput = custom_exec_str("gz service --help"); - - // Call the output function in the bash completion script - std::filesystem::path scriptPath = PROJECT_SOURCE_DIR; - scriptPath = scriptPath / "src" / "cmd" / "transport.bash_completion.sh"; - - // Equivalent to: - // sh -c "bash -c \". /path/to/transport.bash_completion.sh; - // _gz_service_flags\"" - std::string cmd = "bash -c \". " + scriptPath.string() + - "; _gz_service_flags\""; - std::string scriptOutput = custom_exec_str(cmd); - - // Tokenize script output - std::istringstream iss(scriptOutput); - std::vector flags((std::istream_iterator(iss)), - std::istream_iterator()); - - EXPECT_GT(flags.size(), 0u); - - // Match each flag in script output with help message - for (const auto &flag : flags) - { - EXPECT_NE(std::string::npos, helpOutput.find(flag)) << helpOutput; - } -} - -////////////////////////////////////////////////// -/// \brief Check 'gz topic --help' message and bash completion script for -/// consistent flags -TEST(gzTest, TopicHelpVsCompletionFlags) -{ - // Flags in help message - std::string helpOutput = custom_exec_str("gz topic --help"); - - // Call the output function in the bash completion script - std::filesystem::path scriptPath = PROJECT_SOURCE_DIR; - scriptPath = scriptPath / "src" / "cmd" / "transport.bash_completion.sh"; - - // Equivalent to: - // sh -c "bash -c \". /path/to/transport.bash_completion.sh; - // _gz_topic_flags\"" - std::string cmd = "bash -c \". " + scriptPath.string() + - "; _gz_topic_flags\""; - std::string scriptOutput = custom_exec_str(cmd); - - // Tokenize script output - std::istringstream iss(scriptOutput); - std::vector flags((std::istream_iterator(iss)), - std::istream_iterator()); - - EXPECT_GT(flags.size(), 0u); - - // Match each flag in script output with help message - for (const auto &flag : flags) - { - EXPECT_NE(std::string::npos, helpOutput.find(flag)) << helpOutput; - } } -///////////////////////////////////////////////// /// Main int main(int argc, char **argv) { @@ -543,8 +375,8 @@ int main(int argc, char **argv) // Make sure that we load the library recently built and not the one installed // in your system. // Save the current value of LD_LIBRARY_PATH. - std::string value = ""; - transport::env("LD_LIBRARY_PATH", value); + std::string value; + gz::utils::env("LD_LIBRARY_PATH", value); // Add the directory where Gazebo Transport has been built. value = std::string(GZ_TEST_LIBRARY_PATH) + ":" + value; gz::utils::setenv("LD_LIBRARY_PATH", value); diff --git a/test/integration/CMakeLists.txt b/test/integration/CMakeLists.txt index 858962a0e..a60793e91 100644 --- a/test/integration/CMakeLists.txt +++ b/test/integration/CMakeLists.txt @@ -28,16 +28,6 @@ gz_build_tests(TYPE INTEGRATION SOURCES ${tests} TEST_LIST test_list LIB_DEPS ${EXTRA_TEST_LIB_DEPS}) -foreach(test ${test_list}) - - # Inform each test of its output directory so it knows where to call the - # auxiliary files from. Using a generator expression here is useful for - # multi-configuration generators, like Visual Studio. - target_compile_definitions(${test} PRIVATE - "DETAIL_GZ_TRANSPORT_TEST_DIR=\"$\"") - -endforeach() - set(auxiliary_files authPubSubSubscriberInvalid_aux fastPub_aux @@ -56,20 +46,33 @@ set(auxiliary_files # Build the auxiliary files. foreach(AUX_EXECUTABLE ${auxiliary_files}) - gz_add_executable(INTEGRATION_${AUX_EXECUTABLE} ${AUX_EXECUTABLE}.cc) + gz_add_executable(${AUX_EXECUTABLE} ${AUX_EXECUTABLE}.cc) # Link the libraries that we always need. - target_link_libraries(INTEGRATION_${AUX_EXECUTABLE} + target_link_libraries(${AUX_EXECUTABLE} PRIVATE ${PROJECT_LIBRARY_TARGET_NAME} gtest ${EXTRA_TEST_LIB_DEPS} ) +endforeach(AUX_EXECUTABLE) - if(UNIX) - # pthread is only available on Unix machines - target_link_libraries(INTEGRATION_${AUX_EXECUTABLE} - PRIVATE pthread) - endif() -endforeach(AUX_EXECUTABLE) +foreach(test ${test_list}) + target_compile_definitions(${test} PRIVATE + "AUTH_PUB_SUB_SUBSCRIBER_INVALID_EXE=\"$\"" + "FAST_PUB_EXE=\"$\"" + "PUB_EXE=\"$\"" + "PUB_THROTTLED_EXE=\"$\"" + "SCOPED_TOPIC_SUBSCRIBER_EXE=\"$\"" + + "TWO_PROCS_PUBLISHER_EXE=\"$\"" + "TWO_PROCS_PUB_SUB_SUBSCRIBER_EXE=\"$\"" + + "TWO_PROCS_SRV_CALL_REPLIER_EXE=\"$\"" + "TWO_PROCS_SRV_CALL_REPLIER_INC_EXE=\"$\"" + "TWO_PROCS_SRV_CALL_WITHOUT_INPUT_REPLIER_EXE=\"$\"" + "TWO_PROCS_SRV_CALL_WITHOUT_INPUT_REPLIER_INC_EXE=\"$\"" + "TWO_PROCS_SRV_CALL_WITHOUT_OUTPUT_REPLIER_EXE=\"$\"" + "TWO_PROCS_SRV_CALL_WITHOUT_OUTPUT_REPLIER_INC_EXE=\"$\"") +endforeach() diff --git a/test/integration/authPubSub.cc b/test/integration/authPubSub.cc index 9da50e44b..4b99d1a71 100644 --- a/test/integration/authPubSub.cc +++ b/test/integration/authPubSub.cc @@ -31,6 +31,7 @@ #include "gz/transport/TransportTypes.hh" #include +#include #include "test_config.hh" @@ -39,6 +40,9 @@ using namespace gz; static std::string partition; // NOLINT(*) static std::string g_topic = "/foo"; // NOLINT(*) +static constexpr const char * kAuthPubSubSubscriberInvalid = + AUTH_PUB_SUB_SUBSCRIBER_INVALID_EXE; + ////////////////////////////////////////////////// TEST(authPubSub, InvalidAuth) { @@ -53,13 +57,8 @@ TEST(authPubSub, InvalidAuth) // No subscribers yet. EXPECT_FALSE(pub.HasConnections()); - std::string subscriberPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_authPubSubSubscriberInvalid_aux"); - - // Start the subscriber in another process with incorrect credentials. - testing::forkHandlerType pi = testing::forkAndRun(subscriberPath.c_str(), - partition.c_str(), "bad", "invalid"); + auto pi = gz::utils::Subprocess( + {kAuthPubSubSubscriberInvalid, partition, "bad", "invalid"}); msgs::Int32 msg; msg.set_data(1); @@ -77,9 +76,6 @@ TEST(authPubSub, InvalidAuth) EXPECT_TRUE(pub.Publish(msg)); std::this_thread::sleep_for(std::chrono::milliseconds(500)); } - - // The other process should exit without receiving any of the messages. - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// diff --git a/test/integration/scopedTopic.cc b/test/integration/scopedTopic.cc index 9be96a64c..77294c158 100644 --- a/test/integration/scopedTopic.cc +++ b/test/integration/scopedTopic.cc @@ -23,6 +23,7 @@ #include "gz/transport/Node.hh" #include +#include #include "gtest/gtest.h" #include "test_config.hh" @@ -33,18 +34,16 @@ static std::string partition; // NOLINT(*) static std::string g_topic = "/foo"; // NOLINT(*) static int data = 5; +static constexpr const char* kScopedTopicSubscriberExe = + SCOPED_TOPIC_SUBSCRIBER_EXE; + ////////////////////////////////////////////////// /// \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) { - std::string subscriber_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_scopedTopicSubscriber_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(subscriber_path.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kScopedTopicSubscriberExe, partition}); msgs::Int32 msg; msg.set_data(data); @@ -59,8 +58,6 @@ TEST(ScopedTopicTest, ProcessTest) EXPECT_TRUE(pub.Publish(msg)); std::this_thread::sleep_for(std::chrono::milliseconds(500)); EXPECT_TRUE(pub.Publish(msg)); - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// diff --git a/test/integration/twoProcsPubSub.cc b/test/integration/twoProcsPubSub.cc index e87dc7289..2a508b888 100644 --- a/test/integration/twoProcsPubSub.cc +++ b/test/integration/twoProcsPubSub.cc @@ -24,6 +24,7 @@ #include "gz/transport/TransportTypes.hh" #include +#include #include "gtest/gtest.h" #include "test_config.hh" @@ -41,6 +42,15 @@ static bool cbVectorExecuted = false; static bool cbRawExecuted = false; static int counter = 0; +namespace { +constexpr const char* kFastPubExe = FAST_PUB_EXE; +constexpr const char* kPubExe = PUB_EXE; +constexpr const char* kPubThrottledExe = PUB_THROTTLED_EXE; +constexpr const char* kTwoProcsPublisherExe = TWO_PROCS_PUBLISHER_EXE; +constexpr const char* kTwoProcsPubSubSubscriberExe = + TWO_PROCS_PUB_SUB_SUBSCRIBER_EXE; +} // namespace + ////////////////////////////////////////////////// /// \brief Initialize some global variables. void reset() @@ -112,12 +122,7 @@ TEST(twoProcPubSub, PubSubTwoProcsThreeNodes) // No subscribers yet. EXPECT_FALSE(pub.HasConnections()); - std::string subscriberPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsPubSubSubscriber_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(subscriberPath.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kTwoProcsPubSubSubscriberExe, partition}); msgs::Vector3d msg; msg.set_x(1.0); @@ -135,8 +140,6 @@ TEST(twoProcPubSub, PubSubTwoProcsThreeNodes) EXPECT_TRUE(pub.Publish(msg)); std::this_thread::sleep_for(std::chrono::milliseconds(500)); } - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// @@ -151,12 +154,7 @@ TEST(twoProcPubSub, RawPubSubTwoProcsThreeNodes) // No subscribers yet. EXPECT_FALSE(pub.HasConnections()); - std::string subscriberPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsPubSubSubscriber_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(subscriberPath.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kTwoProcsPubSubSubscriberExe, partition}); msgs::Vector3d msg; msg.set_x(1.0); @@ -177,8 +175,6 @@ TEST(twoProcPubSub, RawPubSubTwoProcsThreeNodes) EXPECT_TRUE(pub.PublishRaw(msg.SerializeAsString(), msg.GetTypeName())); std::this_thread::sleep_for(std::chrono::milliseconds(500)); } - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// @@ -186,12 +182,7 @@ TEST(twoProcPubSub, RawPubSubTwoProcsThreeNodes) /// the advertised types. TEST(twoProcPubSub, PubSubWrongTypesOnSubscription) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsPublisher_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kTwoProcsPublisherExe, partition}); reset(); @@ -205,20 +196,13 @@ TEST(twoProcPubSub, PubSubWrongTypesOnSubscription) EXPECT_FALSE(cbExecuted); reset(); - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// /// \brief Same as above, but using a raw subscription. TEST(twoProcPubSub, PubRawSubWrongTypesOnSubscription) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsPublisher_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kTwoProcsPublisherExe, partition}); reset(); @@ -233,8 +217,6 @@ TEST(twoProcPubSub, PubRawSubWrongTypesOnSubscription) EXPECT_FALSE(cbRawExecuted); reset(); - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// @@ -245,12 +227,7 @@ TEST(twoProcPubSub, PubRawSubWrongTypesOnSubscription) /// (correct and generic). TEST(twoProcPubSub, PubSubWrongTypesTwoSubscribers) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsPublisher_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kTwoProcsPublisherExe, partition}); reset(); @@ -266,15 +243,12 @@ TEST(twoProcPubSub, PubSubWrongTypesTwoSubscribers) // Wait some time before publishing. std::this_thread::sleep_for(std::chrono::milliseconds(2500)); - // Check that the message was not received. EXPECT_FALSE(cbExecuted); EXPECT_TRUE(cbVectorExecuted); EXPECT_TRUE(genericCbExecuted); reset(); - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// @@ -285,12 +259,7 @@ TEST(twoProcPubSub, PubSubWrongTypesTwoSubscribers) /// callbacks are executed (correct and generic). TEST(twoProcPubSub, PubSubWrongTypesTwoRawSubscribers) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsPublisher_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kTwoProcsPublisherExe, partition}); reset(); @@ -337,8 +306,6 @@ TEST(twoProcPubSub, PubSubWrongTypesTwoRawSubscribers) EXPECT_TRUE(genericRawCbExecuted); reset(); - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// @@ -348,18 +315,13 @@ TEST(twoProcPubSub, PubSubWrongTypesTwoRawSubscribers) /// the prompt termination of the publisher. TEST(twoProcPubSub, FastPublisher) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, "INTEGRATION_fastPub_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kFastPubExe, partition}); reset(); transport::Node node; EXPECT_TRUE(node.Subscribe(g_topic, cbVector)); - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// @@ -368,11 +330,7 @@ TEST(twoProcPubSub, FastPublisher) /// by the subscriber. TEST(twoProcPubSub, SubThrottled) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, "INTEGRATION_pub_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kPubExe, partition}); reset(); @@ -390,8 +348,6 @@ TEST(twoProcPubSub, SubThrottled) EXPECT_LT(counter, 5); reset(); - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// @@ -399,11 +355,7 @@ TEST(twoProcPubSub, SubThrottled) /// processes. The publisher publishes at a throttled frequency. TEST(twoProcPubSub, PubThrottled) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, "INTEGRATION_pub_aux_throttled"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kPubThrottledExe, partition}); reset(); @@ -419,8 +371,6 @@ TEST(twoProcPubSub, PubThrottled) EXPECT_LT(counter, 5); reset(); - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// @@ -428,12 +378,7 @@ TEST(twoProcPubSub, PubThrottled) /// using a callback that accepts message information. TEST(twoProcPubSub, PubSubMessageInfo) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, "INTEGRATION_twoProcsPublisher_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - partition.c_str()); - + auto pi = gz::utils::Subprocess({kTwoProcsPublisherExe, partition}); reset(); transport::Node node; @@ -446,8 +391,6 @@ TEST(twoProcPubSub, PubSubMessageInfo) EXPECT_FALSE(cbInfoExecuted); reset(); - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// @@ -456,11 +399,7 @@ TEST(twoProcPubSub, PubSubMessageInfo) /// available topics. TEST(twoProcPubSub, TopicList) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, "INTEGRATION_twoProcsPublisher_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kTwoProcsPublisherExe, partition}); reset(); @@ -497,8 +436,6 @@ TEST(twoProcPubSub, TopicList) EXPECT_LT(elapsed2, 2); reset(); - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// @@ -507,11 +444,7 @@ TEST(twoProcPubSub, TopicList) /// about the topic. TEST(twoProcPubSub, TopicInfo) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, "INTEGRATION_twoProcsPublisher_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kTwoProcsPublisherExe, partition}); reset(); @@ -532,8 +465,6 @@ TEST(twoProcPubSub, TopicInfo) EXPECT_EQ(publishers.front().MsgTypeName(), "gz.msgs.Vector3d"); reset(); - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// diff --git a/test/integration/twoProcsSrvCall.cc b/test/integration/twoProcsSrvCall.cc index 9ccd9abdc..e22b3d4bd 100644 --- a/test/integration/twoProcsSrvCall.cc +++ b/test/integration/twoProcsSrvCall.cc @@ -19,12 +19,15 @@ #include #include +#include #include +#include #include "gz/transport/Node.hh" #include "gz/transport/TopicUtils.hh" #include +#include "gz/utils/Subprocess.hh" #include "gtest/gtest.h" #include "test_config.hh" @@ -34,11 +37,43 @@ using namespace gz; static bool responseExecuted; static bool wrongResponseExecuted; -static std::string partition; // NOLINT(*) static std::string g_topic = "/foo"; // NOLINT(*) static int data = 5; static int counter = 0; +static constexpr const char *kTwoProcsSrvCallReplierExe = + TWO_PROCS_SRV_CALL_REPLIER_EXE; + +////////////////////////////////////////////////// +class twoProcSrvCall: 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({ + kTwoProcsSrvCallReplierExe, 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() @@ -69,15 +104,8 @@ void wrongResponse(const msgs::Vector3d &/*_rep*/, bool /*_result*/) ////////////////////////////////////////////////// /// \brief Two different nodes running in two different processes. One node /// advertises a service and the other requests a few service calls. -TEST(twoProcSrvCall, SrvTwoProcs) +TEST_F(twoProcSrvCall, SrvTwoProcs) { - std::string responser_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(responser_path.c_str(), - partition.c_str()); - reset(); msgs::Int32 req; @@ -114,29 +142,19 @@ TEST(twoProcSrvCall, SrvTwoProcs) EXPECT_EQ(counter, 1); reset(); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// /// \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(twoProcSrvCall, SrvRequestWrongReq) +TEST_F(twoProcSrvCall, SrvRequestWrongReq) { msgs::Vector3d wrongReq; msgs::Int32 rep; bool result; unsigned int timeout = 1000; - std::string responser_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(responser_path.c_str(), - partition.c_str()); - wrongReq.set_x(1); wrongReq.set_y(2); wrongReq.set_z(3); @@ -154,30 +172,19 @@ TEST(twoProcSrvCall, SrvRequestWrongReq) EXPECT_FALSE(node.Request(g_topic, wrongReq, timeout, rep, result)); reset(); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// /// \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(twoProcSrvCall, SrvRequestWrongRep) +TEST_F(twoProcSrvCall, SrvRequestWrongRep) { msgs::Int32 req; msgs::Vector3d wrongRep; bool result; unsigned int timeout = 1000; - std::string responser_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallReplier_aux"); - - - testing::forkHandlerType pi = testing::forkAndRun(responser_path.c_str(), - partition.c_str()); - req.set_data(data); reset(); @@ -193,9 +200,6 @@ TEST(twoProcSrvCall, SrvRequestWrongRep) EXPECT_FALSE(node.Request(g_topic, req, timeout, wrongRep, result)); reset(); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// @@ -203,7 +207,7 @@ TEST(twoProcSrvCall, SrvRequestWrongRep) /// 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(twoProcSrvCall, SrvTwoRequestsOneWrong) +TEST_F(twoProcSrvCall, SrvTwoRequestsOneWrong) { msgs::Int32 req; msgs::Int32 goodRep; @@ -211,13 +215,6 @@ TEST(twoProcSrvCall, SrvTwoRequestsOneWrong) bool result; unsigned int timeout = 2000; - std::string responser_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(responser_path.c_str(), - partition.c_str()); - req.set_data(data); reset(); @@ -241,24 +238,14 @@ TEST(twoProcSrvCall, SrvTwoRequestsOneWrong) EXPECT_TRUE(responseExecuted); reset(); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// /// \brief This test spawns two nodes on different processes. One of the nodes /// advertises a service and the other uses ServiceList() for getting the list /// of available services. -TEST(twoProcSrvCall, ServiceList) +TEST_F(twoProcSrvCall, ServiceList) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - partition.c_str()); - reset(); transport::Node node; @@ -294,23 +281,14 @@ TEST(twoProcSrvCall, ServiceList) << "] Elapsed1[" << elapsed1.count() << "]"; reset(); - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// /// \brief This test spawns two nodes on different processes. One of the nodes /// advertises a service and the other uses ServiceInfo() for getting /// information about the service. -TEST(twoProcSrvCall, ServiceInfo) +TEST_F(twoProcSrvCall, ServiceInfo) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - partition.c_str()); - reset(); transport::Node node; @@ -331,22 +309,4 @@ TEST(twoProcSrvCall, ServiceInfo) EXPECT_EQ(publishers.front().RepTypeName(), "gz.msgs.Int32"); reset(); - - testing::waitAndCleanupFork(pi); -} - -////////////////////////////////////////////////// -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/twoProcsSrvCallStress.cc b/test/integration/twoProcsSrvCallStress.cc index f08357928..b231f2a01 100644 --- a/test/integration/twoProcsSrvCallStress.cc +++ b/test/integration/twoProcsSrvCallStress.cc @@ -23,6 +23,7 @@ #include "gz/transport/Node.hh" #include +#include #include "gtest/gtest.h" #include "test_config.hh" @@ -32,15 +33,13 @@ using namespace gz; static std::string partition; // NOLINT(*) static std::string g_topic = "/foo"; // NOLINT(*) +static constexpr const char * kTwoProcsSrvReplierIncExe = + TWO_PROCS_SRV_CALL_REPLIER_INC_EXE; + ////////////////////////////////////////////////// TEST(twoProcSrvCall, ThousandCalls) { - std::string responser_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallReplierInc_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(responser_path.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kTwoProcsSrvReplierIncExe, partition}); msgs::Int32 req; msgs::Int32 response; @@ -59,9 +58,6 @@ TEST(twoProcSrvCall, ThousandCalls) ASSERT_TRUE(result); EXPECT_EQ(i, response.data()); } - - // Need to kill the responser node running on an external process. - testing::killFork(pi); } ////////////////////////////////////////////////// diff --git a/test/integration/twoProcsSrvCallSync1.cc b/test/integration/twoProcsSrvCallSync1.cc index 27087049e..edd69760f 100644 --- a/test/integration/twoProcsSrvCallSync1.cc +++ b/test/integration/twoProcsSrvCallSync1.cc @@ -23,6 +23,7 @@ #include "gz/transport/Node.hh" #include +#include #include "gtest/gtest.h" #include "test_config.hh" @@ -33,6 +34,9 @@ static std::string partition; // NOLINT(*) static std::string g_topic = "/foo"; // NOLINT(*) static int data = 5; +static constexpr const char * kTwoProcsSrvCallReplierExe = + TWO_PROCS_SRV_CALL_REPLIER_EXE; + ////////////////////////////////////////////////// /// \brief This test spawns a service responser and a service requester. The /// synchronous requester uses a wrong service's name. The test should verify @@ -40,12 +44,7 @@ static int data = 5; /// the timeout. TEST(twoProcSrvCallSync1, SrvTwoProcs) { - std::string responser_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(responser_path.c_str(), - partition.c_str()); + auto pi = gz::utils::Subprocess({kTwoProcsSrvCallReplierExe, partition}); int64_t timeout = 500; msgs::Int32 req; @@ -74,9 +73,6 @@ TEST(twoProcSrvCallSync1, SrvTwoProcs) // Check if the elapsed time was close to the timeout. auto diff = std::max(elapsed, timeout) - std::min(elapsed, timeout); EXPECT_LT(diff, 200); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// diff --git a/test/integration/twoProcsSrvCallWithoutInput.cc b/test/integration/twoProcsSrvCallWithoutInput.cc index cefa1ef7b..072df68b2 100644 --- a/test/integration/twoProcsSrvCallWithoutInput.cc +++ b/test/integration/twoProcsSrvCallWithoutInput.cc @@ -19,12 +19,15 @@ #include #include +#include #include +#include #include "gz/transport/Node.hh" #include "gz/transport/TopicUtils.hh" #include +#include #include "gtest/gtest.h" #include "test_config.hh" @@ -39,6 +42,39 @@ static std::string g_topic = "/foo"; // NOLINT(*) static int g_data = 5; static int g_counter = 0; +static constexpr const char * kTwoProcsSrvCallWithoutInputReplierExe = + TWO_PROCS_SRV_CALL_WITHOUT_INPUT_REPLIER_EXE; + +////////////////////////////////////////////////// +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({ + kTwoProcsSrvCallWithoutInputReplierExe, 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() @@ -70,15 +106,8 @@ void wrongResponse(const msgs::Vector3d &/*_rep*/, bool /*_result*/) /// \brief Two different nodes running in two different processes. One node /// advertises a service without input and the other requests a few service /// calls. -TEST(twoProcSrvCallWithoutInput, SrvTwoProcs) +TEST_F(twoProcSrvCallWithoutInput, SrvTwoProcs) { - std::string responser_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallWithoutInputReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(responser_path.c_str(), - g_partition.c_str()); - reset(); transport::Node node; @@ -112,28 +141,18 @@ TEST(twoProcSrvCallWithoutInput, SrvTwoProcs) EXPECT_EQ(g_counter, 1); reset(); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// /// \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(twoProcSrvCallWithoutInput, SrvRequestWrongRep) +TEST_F(twoProcSrvCallWithoutInput, SrvRequestWrongRep) { msgs::Vector3d wrongRep; bool result; unsigned int timeout = 1000; - std::string responser_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallWithoutInputReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(responser_path.c_str(), - g_partition.c_str()); - reset(); transport::Node node; @@ -147,9 +166,6 @@ TEST(twoProcSrvCallWithoutInput, SrvRequestWrongRep) EXPECT_FALSE(node.Request(g_topic, timeout, wrongRep, result)); reset(); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// @@ -157,20 +173,13 @@ TEST(twoProcSrvCallWithoutInput, SrvRequestWrongRep) /// 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(twoProcSrvCallWithoutInput, SrvTwoRequestsOneWrong) +TEST_F(twoProcSrvCallWithoutInput, SrvTwoRequestsOneWrong) { msgs::Int32 goodRep; msgs::Vector3d badRep; bool result; unsigned int timeout = 2000; - std::string responser_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallWithoutInputReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(responser_path.c_str(), - g_partition.c_str()); - reset(); std::this_thread::sleep_for(std::chrono::milliseconds(500)); @@ -192,24 +201,14 @@ TEST(twoProcSrvCallWithoutInput, SrvTwoRequestsOneWrong) EXPECT_TRUE(g_responseExecuted); reset(); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// /// \brief This test spawns two nodes on different processes. One of the nodes /// advertises a service without input and the other uses ServiceList() for /// getting the list of available services. -TEST(twoProcSrvCallWithoutInput, ServiceList) +TEST_F(twoProcSrvCallWithoutInput, ServiceList) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallWithoutInputReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - g_partition.c_str()); - reset(); transport::Node node; @@ -244,23 +243,14 @@ TEST(twoProcSrvCallWithoutInput, ServiceList) EXPECT_LE(elapsed2, elapsed1); reset(); - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// /// \brief This test spawns two nodes on different processes. One of the nodes /// advertises a service without input and the other uses ServiceInfo() for /// getting information about the service. -TEST(twoProcSrvCallWithoutInput, ServiceInfo) +TEST_F(twoProcSrvCallWithoutInput, ServiceInfo) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallWithoutInputReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - g_partition.c_str()); - reset(); transport::Node node; @@ -281,22 +271,4 @@ TEST(twoProcSrvCallWithoutInput, ServiceInfo) EXPECT_EQ(publishers.front().RepTypeName(), "gz.msgs.Int32"); reset(); - - testing::waitAndCleanupFork(pi); -} - -////////////////////////////////////////////////// -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/twoProcsSrvCallWithoutInputStress.cc b/test/integration/twoProcsSrvCallWithoutInputStress.cc index 7d2fc7c4b..5d89bd716 100644 --- a/test/integration/twoProcsSrvCallWithoutInputStress.cc +++ b/test/integration/twoProcsSrvCallWithoutInputStress.cc @@ -23,6 +23,7 @@ #include "gz/transport/Node.hh" #include +#include #include "gtest/gtest.h" #include "test_config.hh" @@ -32,15 +33,14 @@ using namespace gz; static std::string g_partition; // NOLINT(*) static std::string g_topic = "/foo"; // NOLINT(*) +static constexpr const char * kTwoProcsSrvCallWithoutInputReplierIncExe = + TWO_PROCS_SRV_CALL_WITHOUT_INPUT_REPLIER_INC_EXE; + ////////////////////////////////////////////////// TEST(twoProcSrvCallWithoutInput, ThousandCalls) { - std::string responser_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallWithoutInputReplierInc_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(responser_path.c_str(), - g_partition.c_str()); + auto pi = gz::utils::Subprocess( + {kTwoProcsSrvCallWithoutInputReplierIncExe, g_partition}); msgs::Int32 response; bool result; @@ -56,9 +56,6 @@ TEST(twoProcSrvCallWithoutInput, ThousandCalls) // Check the service response. ASSERT_TRUE(result); } - - // Need to kill the responser node running on an external process. - testing::killFork(pi); } ////////////////////////////////////////////////// diff --git a/test/integration/twoProcsSrvCallWithoutInputSync1.cc b/test/integration/twoProcsSrvCallWithoutInputSync1.cc index 230a96f88..d01a734db 100644 --- a/test/integration/twoProcsSrvCallWithoutInputSync1.cc +++ b/test/integration/twoProcsSrvCallWithoutInputSync1.cc @@ -23,6 +23,7 @@ #include "gz/transport/Node.hh" #include +#include #include "gtest/gtest.h" #include "test_config.hh" @@ -32,6 +33,9 @@ using namespace gz; static std::string g_partition; // NOLINT(*) static std::string g_topic = "/foo"; // NOLINT(*) +static constexpr const char * kTwoProcsSrvCallWithoutInputReplierExe = + TWO_PROCS_SRV_CALL_WITHOUT_INPUT_REPLIER_EXE; + ////////////////////////////////////////////////// /// \brief This test spawns a service that doesn't accept input parameters. The /// synchronous requester uses a wrong service's name. The test should verify @@ -39,12 +43,8 @@ static std::string g_topic = "/foo"; // NOLINT(*) /// the timeout. TEST(twoProcSrvCallWithoutInputSync1, SrvTwoProcs) { - std::string responser_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallWithoutInputReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(responser_path.c_str(), - g_partition.c_str()); + auto pi = gz::utils::Subprocess( + {kTwoProcsSrvCallWithoutInputReplierExe, g_partition}); int64_t timeout = 500; msgs::Int32 rep; @@ -69,9 +69,6 @@ TEST(twoProcSrvCallWithoutInputSync1, SrvTwoProcs) // Check if the elapsed time was close to the timeout. auto diff = std::max(elapsed, timeout) - std::min(elapsed, timeout); EXPECT_LT(diff, 200); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// diff --git a/test/integration/twoProcsSrvCallWithoutOutput.cc b/test/integration/twoProcsSrvCallWithoutOutput.cc index 1d365a0be..72995f35d 100644 --- a/test/integration/twoProcsSrvCallWithoutOutput.cc +++ b/test/integration/twoProcsSrvCallWithoutOutput.cc @@ -18,12 +18,15 @@ #include #include +#include #include +#include #include "gz/transport/Node.hh" #include "gz/transport/TopicUtils.hh" #include +#include #include "gtest/gtest.h" #include "test_config.hh" @@ -37,6 +40,39 @@ static std::string g_partition; // NOLINT(*) static std::string g_topic = "/foo"; // NOLINT(*) static int g_counter = 0; +static constexpr const char * kTwoProcsSrvCallWithoutOutputReplierExe = + TWO_PROCS_SRV_CALL_WITHOUT_OUTPUT_REPLIER_EXE; + +////////////////////////////////////////////////// +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({ + kTwoProcsSrvCallWithoutOutputReplierExe, 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() @@ -50,17 +86,10 @@ void reset() /// \brief This test spawns a service that doesn't wait for ouput parameters. /// The requester uses a wrong type for the request argument. The test should /// verify that the service call does not succeed. -TEST(twoProcSrvCallWithoutOutput, SrvRequestWrongReq) +TEST_F(twoProcSrvCallWithoutOutput, SrvRequestWrongReq) { msgs::Vector3d wrongReq; - std::string responser_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallWithoutOutputReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(responser_path.c_str(), - g_partition.c_str()); - wrongReq.set_x(1); wrongReq.set_y(2); wrongReq.set_z(3); @@ -75,24 +104,14 @@ TEST(twoProcSrvCallWithoutOutput, SrvRequestWrongReq) EXPECT_FALSE(g_responseExecuted); reset(); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// /// \brief This test spawns two nodes on different processes. One of the nodes /// advertises a service without output and the other uses ServiceList() for /// getting the list of available services. -TEST(twoProcSrvCallWithoutOutput, ServiceList) +TEST_F(twoProcSrvCallWithoutOutput, ServiceList) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallWithoutOutputReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - g_partition.c_str()); - reset(); transport::Node node; @@ -127,23 +146,14 @@ TEST(twoProcSrvCallWithoutOutput, ServiceList) EXPECT_LE(elapsed2, elapsed1); reset(); - - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// /// \brief This test spawns two nodes on different processes. One of the nodes /// advertises a service without output and the other uses ServiceInfo() for /// getting information about the service. -TEST(twoProcSrvCallWithoutOutput, ServiceInfo) +TEST_F(twoProcSrvCallWithoutOutput, ServiceInfo) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallWithoutOutputReplier_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(publisherPath.c_str(), - g_partition.c_str()); - reset(); transport::Node node; @@ -163,22 +173,4 @@ TEST(twoProcSrvCallWithoutOutput, ServiceInfo) EXPECT_EQ(publishers.front().ReqTypeName(), "gz.msgs.Int32"); reset(); - - testing::waitAndCleanupFork(pi); -} - -////////////////////////////////////////////////// -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/twoProcsSrvCallWithoutOutputStress.cc b/test/integration/twoProcsSrvCallWithoutOutputStress.cc index c32a7e636..dc4a7e595 100644 --- a/test/integration/twoProcsSrvCallWithoutOutputStress.cc +++ b/test/integration/twoProcsSrvCallWithoutOutputStress.cc @@ -23,6 +23,7 @@ #include "gz/transport/Node.hh" #include +#include #include "gtest/gtest.h" #include "test_config.hh" @@ -32,15 +33,14 @@ using namespace gz; static std::string g_partition; // NOLINT(*) static std::string g_topic = "/foo"; // NOLINT(*) +static constexpr const char* kTwoProcsSrvCallWithoutOutputReplierInc = + TWO_PROCS_SRV_CALL_WITHOUT_OUTPUT_REPLIER_INC_EXE; + ////////////////////////////////////////////////// TEST(twoProcSrvCallWithoutOuput, ThousandCalls) { - std::string responser_path = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallWithoutOutputReplierInc_aux"); - - testing::forkHandlerType pi = testing::forkAndRun(responser_path.c_str(), - g_partition.c_str()); + auto pi = gz::utils::Subprocess( + {kTwoProcsSrvCallWithoutOutputReplierInc, g_partition}); msgs::Int32 req; transport::Node node; @@ -52,9 +52,6 @@ TEST(twoProcSrvCallWithoutOuput, ThousandCalls) req.set_data(i); ASSERT_TRUE(node.Request(g_topic, req)); } - - // Need to kill the responser node running on an external process. - testing::killFork(pi); } ////////////////////////////////////////////////// diff --git a/test/test_config.hh.in b/test/test_config.hh.in index 481d35a18..e71841b68 100644 --- a/test/test_config.hh.in +++ b/test/test_config.hh.in @@ -22,165 +22,14 @@ #define GZ_CONFIG_PATH "@CMAKE_BINARY_DIR@/test/conf" #define GZ_VERSION_FULL "@PROJECT_VERSION_FULL@" -#ifdef DETAIL_GZ_TRANSPORT_TEST_DIR -// The DETAIL_GZ_TRANSPORT_TEST_DIR macro is defined using generator -// expressions in CMakeLists.txt files. See test/integration/CMakeLists.txt for -// an example. -#define GZ_TRANSPORT_TEST_DIR \ - DETAIL_GZ_TRANSPORT_TEST_DIR -#endif - #include #include #include #include #include -#ifdef _WIN32 - #include -#else - #include - #include - #include - #include -#endif - -#include "gz/transport/Helpers.hh" - namespace testing { - /// \brief Join _str1 and _str2 considering both as storing system paths. - /// \param[in] _str1 string containing a path. - /// \param[in] _str2 string containing a path. - /// \return The string representation of the union of two paths. - std::string portablePathUnion(const std::string &_str1, - const std::string &_str2) - { - return (std::filesystem::path(_str1) / std::filesystem::path(_str2)).string(); - } - -#ifdef _WIN32 - using forkHandlerType = PROCESS_INFORMATION; -#else - using forkHandlerType = pid_t; -#endif - - /// \brief create a new process and run command on it. This function is - /// implementing the creation of a new process on both Linux (fork) and - /// Windows (CreateProcess) and the execution of the command provided. - /// \param[in] _command The full system path to the binary to run into the - /// new process. - /// \param[in] _partition Name of the Gazebo partition (GZ_PARTITION) - /// \param[in] _username Username for authentication - /// (GZ_TRANSPORT_USERNAME) - /// \param[in] _password Password for authentication - /// (GZ_TRANSPORT_PASSWORD) - /// \return On success, the PID of the child process is returned in the - /// parent, an 0 is returned in the child. On failure, -1 is returned in the - /// parent and no child process is created. - forkHandlerType forkAndRun(const char *_command, const char *_partition, - const char *_username = nullptr, const char *_password = nullptr) - { -#ifdef _WIN32 - STARTUPINFO info= {sizeof(info)}; - PROCESS_INFORMATION processInfo; - - char cmd[500]; - // We should put quotes around the _command string to make sure we are - // robust to file paths that contain spaces. - gz_strcpy(cmd, "\""); - gz_strcat(cmd, _command); - gz_strcat(cmd, "\""); - gz_strcat(cmd, " "); - gz_strcat(cmd, _partition); - - if (_username && _password) - { - gz_strcat(cmd, " "); - gz_strcat(cmd, _username); - gz_strcat(cmd, " "); - gz_strcat(cmd, _password); - } - - // We set the first argument to NULL, because we want the behavior that - // CreateProcess exhibits when the first argument is NULL: i.e. Windows will - // automatically add the .exe extension onto the filename. When the first - // argument is non-NULL, it will not automatically add the extension, which - // makes more work for us. - // - // It should also be noted that the lookup behavior for the application is - // different when the first argument is non-NULL, so we should take that - // into consideration when determining what to put into the first and second - // arguments of CreateProcess. - if (!CreateProcess(NULL, const_cast(cmd), NULL, NULL, - TRUE, 0, NULL, NULL, &info, &processInfo)) - { - std::cerr << "CreateProcess call failed: " << cmd << std::endl; - } - - return processInfo; -#else - pid_t pid = fork(); - - if (pid == 0) - { - if (_username && _password) - { - if (execl(_command, _command, _partition, _username, _password, - reinterpret_cast(0)) == -1) - { - std::cerr << "Error running execl call: " << _command << std::endl; - } - } - else - { - if (execl(_command, _command, _partition, - reinterpret_cast(0)) == -1) - { - std::cerr << "Error running execl call: " << _command << std::endl; - } - } - } - - return pid; -#endif - } - - /// \brief Wait for the end of a process and handle the termination - /// \param[in] pi Process handler of the process to wait for - /// (PROCESS_INFORMATION in windows or forkHandlerType in UNIX). - void waitAndCleanupFork(const forkHandlerType pi) - { -#ifdef _WIN32 - // Wait until child process exits. - WaitForSingleObject(pi.hProcess, INFINITE); - - // Close process and thread handler. - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); -#else - // Wait for the child process to return. - int status; - waitpid(pi, &status, 0); - if (status == -1) - std::cerr << "Error while running waitpid" << std::endl; -#endif - } - - /// \brief Send a termination signal to the process handled by pi. - /// \param[in] pi Process handler of the process to stop - /// (PROCESS_INFORMATION in windows or forkHandlerType in UNIX). - void killFork(const forkHandlerType pi) - { -#ifdef _WIN32 - // TerminateProcess return 0 on error - if (TerminateProcess(pi.hProcess, 0) == 0) - std::cerr << "Error running TerminateProcess: " << GetLastError(); -#else - kill(pi, SIGTERM); -#endif - } - /// \brief Get a random number based on an integer converted to string. /// \return A random integer converted to string. std::string getRandomNumber() From 1db0afe6cf36b7a19881fbc868859841d1359d19 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Fri, 8 Dec 2023 17:14:59 -0600 Subject: [PATCH 3/3] Support for bazel on garden (#399) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michael Carroll Signed-off-by: Carlos Agüero Co-authored-by: Carlos Agüero --- BUILD.bazel | 131 ++++++++++++++++++++++++++++ log/BUILD.bazel | 91 +++++++++++++++++++ log/src/CMakeLists.txt | 2 +- log/src/Log_TEST.cc | 5 +- log/test/integration/CMakeLists.txt | 1 + parameters/BUILD.bazel | 72 +++++++++++++++ src/CIface_TEST.cc | 6 +- src/CMakeLists.txt | 2 +- src/Clock_TEST.cc | 1 - src/Discovery_TEST.cc | 4 +- src/Helpers_TEST.cc | 5 +- src/NodeOptions_TEST.cc | 5 +- src/Node_TEST.cc | 9 +- src/SubscribeOptions_TEST.cc | 1 - src/cmd/CMakeLists.txt | 7 +- src/cmd/gz_TEST.cc | 1 + src/cmd/gz_src_TEST.cc | 14 +-- test/BUILD.bazel | 15 ++++ test/CMakeLists.txt | 12 +-- test/integration/CMakeLists.txt | 3 +- test/test_config.hh.in | 25 +----- test/test_utils.hh | 43 +++++++++ 22 files changed, 390 insertions(+), 65 deletions(-) create mode 100644 BUILD.bazel create mode 100644 log/BUILD.bazel create mode 100644 parameters/BUILD.bazel create mode 100644 test/BUILD.bazel create mode 100644 test/test_utils.hh diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 000000000..aa3447b4d --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,131 @@ +load( + "@gz//bazel/skylark:build_defs.bzl", + "GZ_FEATURES", + "GZ_ROOT", + "GZ_VISIBILITY", + "gz_configure_header", + "gz_export_header", + "gz_include_header", +) +load( + "@gz//bazel/lint:lint.bzl", + "add_lint_tests", +) + +package( + default_visibility = GZ_VISIBILITY, + features = GZ_FEATURES, +) + +licenses(["notice"]) # Apache-2.0 + +exports_files(["LICENSE"]) + +gz_configure_header( + name = "transport_config_hh", + src = "include/gz/transport/config.hh.in", + cmakelists = ["CMakeLists.txt"], + package = "transport", +) + +gz_export_header( + name = "include/gz/transport/Export.hh", + export_base = "GZ_TRANSPORT", + lib_name = "gz-transport", + visibility = ["//visibility:private"], +) + +public_headers_no_gen = glob([ + "include/gz/transport/*.h", + "include/gz/transport/*.hh", + "include/gz/transport/detail/*.hh", +]) + +private_headers = glob(["src/*.hh"]) + +sources = glob( + ["src/*.cc"], + exclude = [ + "src/*_TEST.cc", + ], +) + +gz_include_header( + name = "transport_hh_genrule", + out = "include/gz/transport.hh", + hdrs = public_headers_no_gen + [ + "include/gz/transport/config.hh", + "include/gz/transport/Export.hh", + ], +) + +public_headers = public_headers_no_gen + [ + "include/gz/transport/config.hh", + "include/gz/transport/Export.hh", + "include/gz/transport.hh", +] + +cc_library( + name = "transport", + srcs = sources + private_headers, + hdrs = public_headers, + copts = [ + "-Wno-deprecated-declarations", + ], + includes = ["include"], + deps = [ + GZ_ROOT + "msgs", + "@uuid", + "@zmq", + ], +) + +cc_binary( + name = "topic", + srcs = [ + "src/cmd/gz.cc", + "src/cmd/gz.hh", + "src/cmd/topic_main.cc", + ], + includes = ["src/cmd"], + deps = [ + ":transport", + GZ_ROOT + "utils/cli", + ], +) + +cc_binary( + name = "service", + srcs = [ + "src/cmd/gz.cc", + "src/cmd/gz.hh", + "src/cmd/service_main.cc", + ], + includes = ["src/cmd"], + deps = [ + ":transport", + GZ_ROOT + "utils/cli", + ], +) + +test_sources = glob( + include = ["src/*_TEST.cc"], +) + +[cc_test( + name = src.replace("/", "_").replace(".cc", "").replace("src_", ""), + srcs = [src], + env = { + "GZ_BAZEL": "1", + "GZ_BAZEL_PATH": "transport", + }, + deps = [ + ":transport", + GZ_ROOT + "common/testing", + GZ_ROOT + "transport/test:utils", + "@gtest", + "@gtest//:gtest_main", + ], +) for src in test_sources] + +add_lint_tests() diff --git a/log/BUILD.bazel b/log/BUILD.bazel new file mode 100644 index 000000000..2dd8b6109 --- /dev/null +++ b/log/BUILD.bazel @@ -0,0 +1,91 @@ +load( + "@gz//bazel/skylark:build_defs.bzl", + "GZ_FEATURES", + "GZ_ROOT", + "GZ_VISIBILITY", + "cmake_configure_file", + "gz_configure_header", + "gz_export_header", + "gz_include_header", +) +load( + "@gz//bazel/lint:lint.bzl", + "add_lint_tests", +) + +cmake_configure_file( + name = "build_config", + src = "src/build_config.hh.in", + out = "include/build_config.hh", + cmakelists = ["src/CMakeLists.txt"], + defines = [ + "SCHEMA_INSTALL_PATH=transport/log/sql", + ], +) + +gz_export_header( + name = "include/gz/transport/log/Export.hh", + export_base = "GZ_TRANSPORT_LOG", + lib_name = "gz-transport-log", + visibility = ["//visibility:private"], +) + +public_headers_no_gen = glob([ + "include/gz/transport/log/*.hh", + "include/gz/transport/log/detail/*.hh", +]) + +private_headers = glob(["src/*.hh"]) + +sources = glob( + ["src/*.cc"], + exclude = [ + "src/*_TEST.cc", + ], +) + +public_headers = public_headers_no_gen + [ + "include/gz/transport/log/Export.hh", +] + +cc_library( + name = "log", + srcs = sources + private_headers + ["include/build_config.hh"], + hdrs = public_headers, + data = ["sql/0.1.0.sql"], + includes = ["include"], + deps = [ + GZ_ROOT + "transport", + "@sqlite3", + ], +) + +test_sources = glob( + include = ["src/*_TEST.cc"], + exclude = ["src/LogCommandAPI_TEST.cc"], +) + +[cc_test( + name = src.replace("/", "_").replace(".cc", "").replace("src_", ""), + srcs = [src], + data = [ + "test/data/state.tlog", + ], + defines = [ + 'GZ_TRANSPORT_LOG_TEST_PATH=\\"transport/log/test\\"', + 'CORRUPT_DB_TEST_PATH=\\"transport/log/test/data/state.tlog\\"', + ], + env = { + "GZ_BAZEL": "1", + "GZ_BAZEL_PATH": "transport", + }, + deps = [ + ":log", + GZ_ROOT + "common/testing", + GZ_ROOT + "transport/test:utils", + "@gtest", + "@gtest//:gtest_main", + ], +) for src in test_sources] + +add_lint_tests() diff --git a/log/src/CMakeLists.txt b/log/src/CMakeLists.txt index c285c0efb..aab305fbd 100644 --- a/log/src/CMakeLists.txt +++ b/log/src/CMakeLists.txt @@ -19,7 +19,7 @@ endif() gz_build_tests( TYPE "UNIT" SOURCES ${gtest_sources} - LIB_DEPS ${log_lib_target} ${EXTRA_TEST_LIB_DEPS} + LIB_DEPS ${log_lib_target} ${EXTRA_TEST_LIB_DEPS} test_config TEST_LIST logging_tests ) diff --git a/log/src/Log_TEST.cc b/log/src/Log_TEST.cc index 4ac008344..1faadb310 100644 --- a/log/src/Log_TEST.cc +++ b/log/src/Log_TEST.cc @@ -14,6 +14,7 @@ * limitations under the License. * */ +#include "gtest/gtest.h" #include #include @@ -21,8 +22,8 @@ #include #include "gz/transport/log/Log.hh" -#include "test_config.hh" -#include "gtest/gtest.h" + +#include "test_utils.hh" using namespace gz; using namespace gz::transport; diff --git a/log/test/integration/CMakeLists.txt b/log/test/integration/CMakeLists.txt index 5537f4511..900575125 100644 --- a/log/test/integration/CMakeLists.txt +++ b/log/test/integration/CMakeLists.txt @@ -20,6 +20,7 @@ gz_build_tests( ChirpParams ${PROJECT_LIBRARY_TARGET_NAME}-log ${EXTRA_TEST_LIB_DEPS} + test_config INCLUDE_DIRS ${CMAKE_BINARY_DIR}/test/ ) diff --git a/parameters/BUILD.bazel b/parameters/BUILD.bazel new file mode 100644 index 000000000..8a1842d0c --- /dev/null +++ b/parameters/BUILD.bazel @@ -0,0 +1,72 @@ +load( + "@gz//bazel/skylark:build_defs.bzl", + "GZ_FEATURES", + "GZ_ROOT", + "GZ_VISIBILITY", + "cmake_configure_file", + "gz_configure_header", + "gz_export_header", + "gz_include_header", +) +load( + "@gz//bazel/lint:lint.bzl", + "add_lint_tests", +) + +gz_export_header( + name = "include/gz/transport/parameters/Export.hh", + export_base = "GZ_TRANSPORT_PARAMETERS", + lib_name = "gz-transport-parameters", + visibility = ["//visibility:private"], +) + +public_headers_no_gen = glob([ + "include/gz/transport/parameters/*.hh", + "include/gz/transport/parameters/detail/*.hh", +]) + +private_headers = glob(["src/*.hh"]) + +sources = glob( + ["src/*.cc"], + exclude = [ + "src/*_TEST.cc", + ], +) + +public_headers = public_headers_no_gen + [ + "include/gz/transport/parameters/Export.hh", +] + +cc_library( + name = "parameters", + srcs = sources + private_headers, + hdrs = public_headers, + includes = ["include"], + visibility = GZ_VISIBILITY, + deps = [ + GZ_ROOT + "transport", + "@sqlite3", + ], +) + +test_sources = glob( + include = ["src/*_TEST.cc"], +) + +[cc_test( + name = src.replace("/", "_").replace(".cc", "").replace("src_", ""), + srcs = [src], + env = { + "GZ_BAZEL": "1", + "GZ_BAZEL_PATH": "transport", + }, + deps = [ + ":parameters", + GZ_ROOT + "transport/test:utils", + "@gtest", + "@gtest//:gtest_main", + ], +) for src in test_sources] + +add_lint_tests() diff --git a/src/CIface_TEST.cc b/src/CIface_TEST.cc index 1f1b70c57..b67f3c979 100644 --- a/src/CIface_TEST.cc +++ b/src/CIface_TEST.cc @@ -14,15 +14,15 @@ * limitations under the License. * */ +#include "gtest/gtest.h" + #include #include "gz/transport/CIface.h" +#include "test_utils.hh" #include -#include "gtest/gtest.h" -#include "test_config.hh" - static int count; ////////////////////////////////////////////////// diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bed76c64d..863e676d0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,7 +31,7 @@ endif() # Build the unit tests. gz_build_tests(TYPE UNIT SOURCES ${gtest_sources} TEST_LIST test_list - LIB_DEPS ${EXTRA_TEST_LIB_DEPS}) + LIB_DEPS ${EXTRA_TEST_LIB_DEPS} test_config) foreach(test ${test_list}) diff --git a/src/Clock_TEST.cc b/src/Clock_TEST.cc index 0c80cc487..22547b2cd 100644 --- a/src/Clock_TEST.cc +++ b/src/Clock_TEST.cc @@ -24,7 +24,6 @@ #include "gz/transport/Clock.hh" #include "gz/transport/Node.hh" #include "gz/transport/TransportTypes.hh" -#include "test_config.hh" #include "gtest/gtest.h" using namespace gz; diff --git a/src/Discovery_TEST.cc b/src/Discovery_TEST.cc index 24d1882ff..26f1b6a26 100644 --- a/src/Discovery_TEST.cc +++ b/src/Discovery_TEST.cc @@ -14,6 +14,7 @@ * limitations under the License. * */ +#include "gtest/gtest.h" #include #include @@ -21,17 +22,16 @@ #include #include -#include "gtest/gtest.h" #include "gz/transport/AdvertiseOptions.hh" #include "gz/transport/Discovery.hh" #include "gz/transport/Publisher.hh" #include "gz/transport/TransportTypes.hh" #include "gz/transport/Uuid.hh" +#include "test_utils.hh" #include "gz/utils/Environment.hh" #include "gz/utils/ExtraTestMacros.hh" -#include "test_config.hh" using namespace gz; using namespace transport; diff --git a/src/Helpers_TEST.cc b/src/Helpers_TEST.cc index 518090e11..c5674f325 100644 --- a/src/Helpers_TEST.cc +++ b/src/Helpers_TEST.cc @@ -14,14 +14,13 @@ * limitations under the License. * */ +#include "gtest/gtest.h" #include "gz/transport/Helpers.hh" +#include "test_utils.hh" #include -#include "test_config.hh" -#include "gtest/gtest.h" - using namespace gz; ////////////////////////////////////////////////// diff --git a/src/NodeOptions_TEST.cc b/src/NodeOptions_TEST.cc index d28a40e5a..96a870e60 100644 --- a/src/NodeOptions_TEST.cc +++ b/src/NodeOptions_TEST.cc @@ -15,6 +15,8 @@ * */ +#include "gtest/gtest.h" + #include #include "gz/transport/NetUtils.hh" @@ -22,9 +24,6 @@ #include -#include "test_config.hh" -#include "gtest/gtest.h" - using namespace gz; ////////////////////////////////////////////////// diff --git a/src/Node_TEST.cc b/src/Node_TEST.cc index 80427368e..cb0d31772 100644 --- a/src/Node_TEST.cc +++ b/src/Node_TEST.cc @@ -14,6 +14,8 @@ * limitations under the License. * */ +#include "gtest/gtest.h" + #include #include #include @@ -26,18 +28,13 @@ #include #include -#include "gz/transport/AdvertiseOptions.hh" #include "gz/transport/MessageInfo.hh" #include "gz/transport/Node.hh" -#include "gz/transport/NodeOptions.hh" -#include "gz/transport/TopicStatistics.hh" -#include "gz/transport/TopicUtils.hh" #include "gz/transport/TransportTypes.hh" #include -#include "gtest/gtest.h" -#include "test_config.hh" +#include "test_utils.hh" using namespace gz; diff --git a/src/SubscribeOptions_TEST.cc b/src/SubscribeOptions_TEST.cc index 8e7ccb780..d6bb9666f 100644 --- a/src/SubscribeOptions_TEST.cc +++ b/src/SubscribeOptions_TEST.cc @@ -17,7 +17,6 @@ #include "gz/transport/Helpers.hh" #include "gz/transport/SubscribeOptions.hh" -#include "test_config.hh" #include "gtest/gtest.h" using namespace gz; diff --git a/src/cmd/CMakeLists.txt b/src/cmd/CMakeLists.txt index 9a559f1d7..ed165dbd8 100644 --- a/src/cmd/CMakeLists.txt +++ b/src/cmd/CMakeLists.txt @@ -41,11 +41,12 @@ install(TARGETS ${service_executable} DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/gz # Build the unit tests. gz_build_tests(TYPE UNIT SOURCES ${gtest_sources} TEST_LIST test_list - LIB_DEPS ${EXTRA_TEST_LIB_DEPS}) + LIB_DEPS + gz + gz-utils${GZ_UTILS_VER}::gz-utils${GZ_UTILS_VER} + ${EXTRA_TEST_LIB_DEPS} test_config) foreach(test ${test_list}) - target_link_libraries(${test} gz gz-utils${GZ_UTILS_VER}::gz-utils${GZ_UTILS_VER}) - # Inform each test of its output directory so it knows where to call the # auxiliary files from. Using a generator expression here is useful for # multi-configuration generators, like Visual Studio. diff --git a/src/cmd/gz_TEST.cc b/src/cmd/gz_TEST.cc index 5a6158e72..5dd861177 100644 --- a/src/cmd/gz_TEST.cc +++ b/src/cmd/gz_TEST.cc @@ -29,6 +29,7 @@ #include "gtest/gtest.h" #include "gz/transport/Node.hh" + #include "test_config.hh" using namespace gz; diff --git a/src/cmd/gz_src_TEST.cc b/src/cmd/gz_src_TEST.cc index 9e6deed45..04be10d0d 100644 --- a/src/cmd/gz_src_TEST.cc +++ b/src/cmd/gz_src_TEST.cc @@ -14,27 +14,21 @@ * limitations under the License. * */ +#include "gtest/gtest.h" + +#include #include #include #include #include -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4251) -#endif -#include -#ifdef _MSC_VER -#pragma warning(pop) -#endif #include "gz.hh" #include "gz/transport/Node.hh" #include -#include "test_config.hh" -#include "gtest/gtest.h" +#include "test_utils.hh" using namespace gz; diff --git a/test/BUILD.bazel b/test/BUILD.bazel new file mode 100644 index 000000000..8700063d5 --- /dev/null +++ b/test/BUILD.bazel @@ -0,0 +1,15 @@ +load( + "@gz//bazel/skylark:build_defs.bzl", + "GZ_ROOT", + "GZ_VISIBILITY", +) + +cc_library( + name = "utils", + hdrs = ["test_utils.hh"], + includes = ["."], + visibility = GZ_VISIBILITY, + deps = [ + GZ_ROOT + "utils", + ], +) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4166255fa..a260fe231 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,9 +1,11 @@ -configure_file (test_config.hh.in ${PROJECT_BINARY_DIR}/include/test_config.hh) -include_directories ( - ${PROJECT_BINARY_DIR}/include -) - add_subdirectory(gtest_vendor) add_subdirectory(integration) add_subdirectory(performance) add_subdirectory(regression) + +configure_file (test_config.hh.in ${PROJECT_BINARY_DIR}/include/test_config.hh) +add_library(test_config INTERFACE) +target_include_directories(test_config INTERFACE + ${PROJECT_BINARY_DIR}/include + ${PROJECT_SOURCE_DIR}/test +) diff --git a/test/integration/CMakeLists.txt b/test/integration/CMakeLists.txt index a60793e91..3fcbf15ce 100644 --- a/test/integration/CMakeLists.txt +++ b/test/integration/CMakeLists.txt @@ -26,7 +26,7 @@ endif() gz_build_tests(TYPE INTEGRATION SOURCES ${tests} TEST_LIST test_list - LIB_DEPS ${EXTRA_TEST_LIB_DEPS}) + LIB_DEPS ${EXTRA_TEST_LIB_DEPS} test_config) set(auxiliary_files authPubSubSubscriberInvalid_aux @@ -54,6 +54,7 @@ foreach(AUX_EXECUTABLE ${auxiliary_files}) ${PROJECT_LIBRARY_TARGET_NAME} gtest ${EXTRA_TEST_LIB_DEPS} + test_config ) endforeach(AUX_EXECUTABLE) diff --git a/test/test_config.hh.in b/test/test_config.hh.in index e71841b68..48e0dab43 100644 --- a/test/test_config.hh.in +++ b/test/test_config.hh.in @@ -22,27 +22,6 @@ #define GZ_CONFIG_PATH "@CMAKE_BINARY_DIR@/test/conf" #define GZ_VERSION_FULL "@PROJECT_VERSION_FULL@" -#include -#include -#include -#include -#include +#include "test_utils.hh" -namespace testing -{ - /// \brief Get a random number based on an integer converted to string. - /// \return A random integer converted to string. - std::string getRandomNumber() - { - // Initialize random number generator. - uint32_t seed = std::random_device {}(); - std::mt19937 randGenerator(seed); - - // Create a random number based on an integer converted to string. - std::uniform_int_distribution d(0, INT_MAX); - - return std::to_string(d(randGenerator)); - } -} // namespace testing - -#endif // header guard +#endif // GZ_TRANSPORT_TEST_CONFIG_HH_ diff --git a/test/test_utils.hh b/test/test_utils.hh new file mode 100644 index 000000000..2199a1a4c --- /dev/null +++ b/test/test_utils.hh @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +#ifndef GZ_TRANSPORT_TEST_UTILS_HH_ +#define GZ_TRANSPORT_TEST_UTILS_HH_ + +#include +#include +#include + +namespace testing +{ + /// \brief Get a random number based on an integer converted to string. + /// \return A random integer converted to string. + inline std::string getRandomNumber() + { + // Initialize random number generator. + uint32_t seed = std::random_device {}(); + std::mt19937 randGenerator(seed); + + // Create a random number based on an integer converted to string. + std::uniform_int_distribution d(0, INT_MAX); + + return std::to_string(d(randGenerator)); + } +} // namespace testing + +#endif // GZ_TRANSPORT_TEST_UTILS_HH_ +