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/src/cmd/CMakeLists.txt b/src/cmd/CMakeLists.txt index 7f5935985..f077906dc 100644 --- a/src/cmd/CMakeLists.txt +++ b/src/cmd/CMakeLists.txt @@ -49,6 +49,8 @@ foreach(test ${test_list}) "GZ_TEST_LIBRARY_PATH=\"$\"" "PROJECT_SOURCE_DIR=\"${PROJECT_SOURCE_DIR}\"" "TWO_PROCS_PUBLISHER_EXE=\"$\"" + "TWO_PROCS_SRV_CALL_REPLIER_EXE=\"$\"" + "DETAIL_GZ_TRANSPORT_TEST_DIR=\"$\"" "GZ_EXE=\"${HAVE_GZ_TOOLS}\"" ) diff --git a/src/cmd/cmdtransport.rb.in b/src/cmd/cmdtransport.rb.in index 74d96000b..9e1385381 100644 --- a/src/cmd/cmdtransport.rb.in +++ b/src/cmd/cmdtransport.rb.in @@ -40,7 +40,7 @@ class Cmd exe_name = File.expand_path(File.join(File.dirname(__FILE__), exe_name)) end conf_version = LIBRARY_VERSION - exe_version = `#{exe_name} --version`.strip + exe_version = `#{exe_name} --version 2>&1` # Sanity check: Verify that the version of the yaml file matches the version # of the library that we are using. diff --git a/src/cmd/gz_TEST.cc b/src/cmd/gz_TEST.cc index 0a76e91c3..d948c20a2 100644 --- a/src/cmd/gz_TEST.cc +++ b/src/cmd/gz_TEST.cc @@ -35,11 +35,14 @@ 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)); -static constexpr const char * kGzExe = GZ_EXE; -static constexpr const char * kTwoProcsPublisherExe = TWO_PROCS_PUBLISHER_EXE; +namespace +{ +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. @@ -56,6 +59,18 @@ void topicCB(const msgs::StringMsg &_msg) g_topicCBStr = _msg.data(); } +////////////////////////////////////////////////// +std::string 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.push_back("--force-version"); + fullArgs.push_back(kGzVersion); + auto proc = gz::utils::Subprocess(fullArgs); + proc.Join(); + return proc.Stdout(); +} + ////////////////////////////////////////////////// /// \brief Check 'gz topic -l' running the advertiser on a different process. TEST(gzTest, GZ_UTILS_TEST_DISABLED_ON_MAC(TopicList)) @@ -64,17 +79,15 @@ TEST(gzTest, GZ_UTILS_TEST_DISABLED_ON_MAC(TopicList)) unsigned int retries = 0u; bool topicFound = false; + std::string output; while (!topicFound && retries++ < 10u) { - auto gz = gz::utils::Subprocess({kGzExe, "topic", "-l", g_gzVersion}); - auto output = gz.Stdout(); - - std::cout << "Output: " << std::endl; + output = custom_exec_str({"topic", "-l"}); std::cout << output << std::endl; - topicFound = output == "/foo\n"; std::this_thread::sleep_for(std::chrono::milliseconds(300)); + break; } EXPECT_TRUE(topicFound); @@ -85,15 +98,7 @@ 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()); - - // Check the 'gz topic -i' command. - std::string gz = std::string(GZ_PATH); + auto proc = gz::utils::Subprocess({kTwoProcsPublisherExe, g_partition}); unsigned int retries = 0u; bool infoFound = false; @@ -101,7 +106,7 @@ TEST(gzTest, TopicInfo) while (!infoFound && retries++ < 10u) { - output = custom_exec_str(gz + " topic -t /foo -i " + g_gzVersion); + output = custom_exec_str({"topic", "-t", "/foo", "-i"}); infoFound = output.size() > 50u; std::this_thread::sleep_for(std::chrono::milliseconds(300)); } @@ -110,9 +115,6 @@ TEST(gzTest, TopicInfo) << output << "] Size[" << output.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); } ////////////////////////////////////////////////// @@ -121,46 +123,27 @@ 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); + auto proc = gz::utils::Subprocess({kTwoProcsSrvCallReplierExe, g_partition}); unsigned int retries = 0u; bool serviceFound = false; while (!serviceFound && retries++ < 10u) { - std::string output = custom_exec_str(gz + " service -l " + g_gzVersion); + std::string output = custom_exec_str({"service", "-l"}); serviceFound = output == "/foo\n"; std::this_thread::sleep_for(std::chrono::milliseconds(300)); } EXPECT_TRUE(serviceFound); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// /// \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); + // Launch a new responser process that advertises a service. + auto proc = gz::utils::Subprocess({kTwoProcsSrvCallReplierExe, g_partition}); unsigned int retries = 0u; bool infoFound = false; @@ -168,16 +151,13 @@ TEST(gzTest, ServiceInfo) while (!infoFound && retries++ < 10u) { - output = custom_exec_str(gz + " service -s /foo -i " + g_gzVersion); + output = custom_exec_str({"service", "-s", "/foo", "-i"}); infoFound = output.size() > 50u; std::this_thread::sleep_for(std::chrono::milliseconds(300)); } EXPECT_TRUE(infoFound); EXPECT_TRUE(output.find("gz.msgs.Int32") != std::string::npos); - - // Wait for the child process to return. - testing::waitAndCleanupFork(pi); } ////////////////////////////////////////////////// @@ -195,15 +175,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); + std::string output = custom_exec_str({"topic", "-l"}); topicFound = output == "/foo\n"; std::this_thread::sleep_for(std::chrono::milliseconds(300)); } @@ -226,16 +203,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); + output = custom_exec_str({"topic", "-t", "/foo", "-i"}); infoFound = output.size() > 50u; std::this_thread::sleep_for(std::chrono::milliseconds(300)); } @@ -251,15 +225,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); + std::string output = custom_exec_str({"service", "-l"}); serviceFound = output == "/foo\n"; std::this_thread::sleep_for(std::chrono::milliseconds(300)); } @@ -274,16 +245,13 @@ 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); + output = custom_exec_str({"service", "-s", "/foo", "-i"}); infoFound = output.size() > 50u; std::this_thread::sleep_for(std::chrono::milliseconds(300)); } @@ -301,8 +269,6 @@ 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; @@ -311,9 +277,10 @@ TEST(gzTest, TopicPublish) // 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); + output = custom_exec_str({"topic", + "-t", "/bar", + "-m", "gz_msgs.StringMsg", + "-p", R"('data: "good_value"')"}); EXPECT_TRUE(output.empty()) << output; } std::this_thread::sleep_for(std::chrono::milliseconds(30)); @@ -322,23 +289,26 @@ TEST(gzTest, TopicPublish) // 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); + output = custom_exec_str({"topic", + "-t", "/bar", + "-m", "gz_msgs.__bad_msg_type", + "-p", R"('data:"good_value"')"}); EXPECT_EQ(output.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); + output = custom_exec_str({"topic", + "-t", "/", + "-m", "gz_msgs.StringMsg", + "-p", R"('data: "good_value"')"}); EXPECT_EQ(output.compare(0, error.size(), error), 0) << output; // 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); + output = custom_exec_str({"topic", + "-t", "/", "wrong_topic", + "-m", "gz_msgs.StringMsg", + "-p", R"('data: "good_value"')"}); EXPECT_EQ(output.compare(0, error.size(), error), 0) << output; } @@ -357,12 +327,12 @@ 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); - + std::string output = custom_exec_str({"service", + "-s", service, + "--reqtype", "gz_msgs.Int32", + "--reptype", "gz_msgs.Int32", + "--timeout", "1000", + "--req", "'data: " + value + "'"}); ASSERT_EQ(output, "data: " + value + "\n\n"); } @@ -371,24 +341,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"); - - 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' command. - std::string gz = std::string(GZ_PATH); std::string output = custom_exec_str( - gz + " topic -e -t /foo -d 1.5 " + g_gzVersion); + {"topic", "-e", "-t", "/foo", "-d", "1.5"}); 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); } ////////////////////////////////////////////////// @@ -397,17 +357,10 @@ 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); + {"topic", "-e", "-t", "/foo", "-n", "2"}); size_t pos = output.find("x: 1"); EXPECT_TRUE(pos != std::string::npos); @@ -429,76 +382,8 @@ TEST(gzTest, TopicEchoNum) EXPECT_TRUE(pos != std::string::npos); pos = output.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) @@ -512,8 +397,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 bea650004..37b6d3df4 100644 --- a/test/integration/CMakeLists.txt +++ b/test/integration/CMakeLists.txt @@ -29,13 +29,11 @@ gz_build_tests(TYPE INTEGRATION SOURCES ${tests} 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 diff --git a/test/integration/twoProcsSrvCallWithoutInput.cc b/test/integration/twoProcsSrvCallWithoutInput.cc index e675e3452..8d7b1f69a 100644 --- a/test/integration/twoProcsSrvCallWithoutInput.cc +++ b/test/integration/twoProcsSrvCallWithoutInput.cc @@ -186,10 +186,6 @@ TEST(twoProcSrvCallWithoutInput, SrvTwoRequestsOneWrong) /// getting the list of available services. TEST(twoProcSrvCallWithoutInput, ServiceList) { - std::string publisherPath = testing::portablePathUnion( - GZ_TRANSPORT_TEST_DIR, - "INTEGRATION_twoProcsSrvCallWithoutInputReplier_aux"); - auto pi = gz::utils::Subprocess( {kTwoProcsSrvCallWithoutInputReplierExe, g_partition}); diff --git a/test/test_config.hh.in b/test/test_config.hh.in index 1ecaad1f1..df25a23f0 100644 --- a/test/test_config.hh.in +++ b/test/test_config.hh.in @@ -36,29 +36,8 @@ #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(); - } - /// \brief Get a random number based on an integer converted to string. /// \return A random integer converted to string. std::string getRandomNumber()