From f639ffe807a7ef557e2b590cb9bedd73a978d154 Mon Sep 17 00:00:00 2001 From: Scott K Logan Date: Mon, 1 Jun 2020 16:05:37 -0700 Subject: [PATCH 1/8] Create a separate allocator test fixture Signed-off-by: Scott K Logan --- rcl_logging_spdlog/test/fixtures.hpp | 55 +++++++++++++++++++ .../test/test_logging_interface.cpp | 21 ++----- 2 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 rcl_logging_spdlog/test/fixtures.hpp diff --git a/rcl_logging_spdlog/test/fixtures.hpp b/rcl_logging_spdlog/test/fixtures.hpp new file mode 100644 index 0000000..d1916b0 --- /dev/null +++ b/rcl_logging_spdlog/test/fixtures.hpp @@ -0,0 +1,55 @@ +// Copyright 2020 Open Source Robotics Foundation, Inc. +// +// 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 FIXTURES_HPP_ +#define FIXTURES_HPP_ + +#include +#include "gtest/gtest.h" + +class AllocatorTest : public ::testing::Test +{ +public: + AllocatorTest() + : allocator(rcutils_get_default_allocator()), + bad_allocator(get_bad_allocator()), + invalid_allocator(rcutils_get_zero_initialized_allocator()) + { + } + + rcutils_allocator_t allocator; + rcutils_allocator_t bad_allocator; + rcutils_allocator_t invalid_allocator; + +private: + static rcutils_allocator_t get_bad_allocator() + { + rcutils_allocator_t bad_allocator = rcutils_get_default_allocator(); + bad_allocator.allocate = AllocatorTest::bad_malloc; + bad_allocator.reallocate = AllocatorTest::bad_realloc; + return bad_allocator; + } + + static void * bad_malloc(size_t, void *) + { + return nullptr; + } + + static void * bad_realloc(void *, size_t, void *) + { + return nullptr; + } +}; + +#endif // FIXTURES_HPP_ diff --git a/rcl_logging_spdlog/test/test_logging_interface.cpp b/rcl_logging_spdlog/test/test_logging_interface.cpp index cfe86a2..28d2f04 100644 --- a/rcl_logging_spdlog/test/test_logging_interface.cpp +++ b/rcl_logging_spdlog/test/test_logging_interface.cpp @@ -12,24 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include #include #include -#include "rcl_logging_spdlog/logging_interface.h" -#include "gtest/gtest.h" -static void * bad_malloc(size_t, void *) -{ - return nullptr; -} +#include "fixtures.hpp" +#include "gtest/gtest.h" +#include "rcl_logging_spdlog/logging_interface.h" -TEST(logging_interface, init_invalid) +TEST_F(AllocatorTest, init_invalid) { - rcutils_allocator_t allocator = rcutils_get_default_allocator(); - rcutils_allocator_t bad_allocator = rcutils_get_default_allocator(); - rcutils_allocator_t invalid_allocator = rcutils_get_zero_initialized_allocator(); - bad_allocator.allocate = bad_malloc; - // Config files are not supported by spdlog EXPECT_EQ(2, rcl_logging_external_initialize("anything", allocator)); rcutils_reset_error(); @@ -39,10 +30,8 @@ TEST(logging_interface, init_invalid) rcutils_reset_error(); } -TEST(logging_interface, full_cycle) +TEST_F(AllocatorTest, full_cycle) { - rcutils_allocator_t allocator = rcutils_get_default_allocator(); - ASSERT_EQ(0, rcl_logging_external_initialize(nullptr, allocator)); EXPECT_EQ(0, rcl_logging_external_set_logger_level(nullptr, RCUTILS_LOG_SEVERITY_INFO)); rcl_logging_external_log(RCUTILS_LOG_SEVERITY_INFO, nullptr, "Log Message"); From daab7b1406c65061a32b18b553a66ea4e09bae01 Mon Sep 17 00:00:00 2001 From: Scott K Logan Date: Mon, 1 Jun 2020 19:06:20 -0700 Subject: [PATCH 2/8] Add LoggingTest fixture and test logging impl Signed-off-by: Scott K Logan --- rcl_logging_spdlog/CMakeLists.txt | 2 + rcl_logging_spdlog/package.xml | 1 + rcl_logging_spdlog/test/fixtures.hpp | 72 +++++++++++++++++++ .../test/test_logging_interface.cpp | 39 ++++++++-- 4 files changed, 110 insertions(+), 4 deletions(-) diff --git a/rcl_logging_spdlog/CMakeLists.txt b/rcl_logging_spdlog/CMakeLists.txt index 68432dc..31855ea 100644 --- a/rcl_logging_spdlog/CMakeLists.txt +++ b/rcl_logging_spdlog/CMakeLists.txt @@ -47,9 +47,11 @@ if(BUILD_TESTING) ament_lint_auto_find_test_dependencies() find_package(ament_cmake_gtest REQUIRED) + find_package(rcpputils REQUIRED) ament_add_gtest(test_logging_interface test/test_logging_interface.cpp) if(TARGET test_logging_interface) target_link_libraries(test_logging_interface ${PROJECT_NAME}) + ament_target_dependencies(test_logging_interface rcpputils) endif() endif() diff --git a/rcl_logging_spdlog/package.xml b/rcl_logging_spdlog/package.xml index c0b4e26..2f85677 100644 --- a/rcl_logging_spdlog/package.xml +++ b/rcl_logging_spdlog/package.xml @@ -20,6 +20,7 @@ ament_lint_auto ament_lint_common + rcpputils rcl_logging_packages diff --git a/rcl_logging_spdlog/test/fixtures.hpp b/rcl_logging_spdlog/test/fixtures.hpp index d1916b0..f8211be 100644 --- a/rcl_logging_spdlog/test/fixtures.hpp +++ b/rcl_logging_spdlog/test/fixtures.hpp @@ -15,9 +15,24 @@ #ifndef FIXTURES_HPP_ #define FIXTURES_HPP_ +#include #include +#include +#include +#include +#include + +#include + #include "gtest/gtest.h" +#ifdef _WIN32 +#define popen _popen +#define pclose _pclose +#endif + +namespace fs = rcpputils::fs; + class AllocatorTest : public ::testing::Test { public: @@ -52,4 +67,61 @@ class AllocatorTest : public ::testing::Test } }; +class LoggingTest : public AllocatorTest +{ +public: + LoggingTest() + : AllocatorTest() + { + } + + fs::path find_single_log() + { + fs::path log_dir = get_log_dir(); + std::stringstream dir_command; + dir_command << "dir"; +#ifdef _WIN32 + dir_command << " /B"; +#endif + dir_command << " " << (log_dir / get_expected_log_prefix()).string() << "*"; + + FILE * fp = popen(dir_command.str().c_str(), "r"); + if (nullptr == fp) { + throw std::runtime_error("Failed to glob for log files"); + } + + char raw_line[2048]; + while (fgets(raw_line, sizeof(raw_line), fp) != NULL) { + pclose(fp); + + std::string line(raw_line); + fs::path line_path(line.substr(0, line.find_last_not_of(" \t\r\n") + 1)); + // This should be changed once ros2/rcpputils#68 is resolved + return line_path.is_absolute() ? line_path : log_dir / line_path; + } + + pclose(fp); + throw std::runtime_error("No log files were found"); + } + +private: + std::string get_expected_log_prefix() + { + char * exe_name = rcutils_get_executable_name(allocator); + if (nullptr == exe_name) { + throw std::runtime_error("Failed to determine executable name"); + } + std::stringstream prefix; + prefix << exe_name << "_" << + rcutils_get_pid() << "_"; + allocator.deallocate(exe_name, allocator.state); + return prefix.str(); + } + + fs::path get_log_dir() + { + return fs::path(rcutils_get_home_dir()) / ".ros" / "log"; + } +}; + #endif // FIXTURES_HPP_ diff --git a/rcl_logging_spdlog/test/test_logging_interface.cpp b/rcl_logging_spdlog/test/test_logging_interface.cpp index 28d2f04..37bd361 100644 --- a/rcl_logging_spdlog/test/test_logging_interface.cpp +++ b/rcl_logging_spdlog/test/test_logging_interface.cpp @@ -12,14 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include +#include +#include + #include "fixtures.hpp" #include "gtest/gtest.h" #include "rcl_logging_spdlog/logging_interface.h" -TEST_F(AllocatorTest, init_invalid) +TEST_F(LoggingTest, init_invalid) { // Config files are not supported by spdlog EXPECT_EQ(2, rcl_logging_external_initialize("anything", allocator)); @@ -30,10 +34,37 @@ TEST_F(AllocatorTest, init_invalid) rcutils_reset_error(); } -TEST_F(AllocatorTest, full_cycle) +TEST_F(LoggingTest, full_cycle) { ASSERT_EQ(0, rcl_logging_external_initialize(nullptr, allocator)); - EXPECT_EQ(0, rcl_logging_external_set_logger_level(nullptr, RCUTILS_LOG_SEVERITY_INFO)); - rcl_logging_external_log(RCUTILS_LOG_SEVERITY_INFO, nullptr, "Log Message"); + + std::stringstream expected_log; + for (int level = RCUTILS_LOG_SEVERITY_UNSET; level <= RCUTILS_LOG_SEVERITY_FATAL; level += 10) { + EXPECT_EQ(0, rcl_logging_external_set_logger_level(nullptr, level)); + + for (int severity = RCUTILS_LOG_SEVERITY_UNSET; severity <= RCUTILS_LOG_SEVERITY_FATAL; + severity += 10) + { + std::stringstream ss; + ss << "Message of severity " << severity << " at level " << level; + rcl_logging_external_log(severity, nullptr, ss.str().c_str()); + + if (severity >= level) { + expected_log << ss.str() << std::endl; + } else if (severity == 0 && level == 10) { + // This is a special case - not sure what the right behavior is + expected_log << ss.str() << std::endl; + } + } + } + EXPECT_EQ(0, rcl_logging_external_shutdown()); + + std::string log_file_path = find_single_log().string(); + std::ifstream log_file(log_file_path); + std::stringstream actual_log; + actual_log << log_file.rdbuf(); + EXPECT_EQ( + expected_log.str(), + actual_log.str()) << "Unexpected log contents in " << log_file_path; } From 3ad5863f1b4bee3f723f2f85646bd6e41eb48e3b Mon Sep 17 00:00:00 2001 From: Scott K Logan Date: Tue, 2 Jun 2020 15:01:28 -0700 Subject: [PATCH 3/8] Improve test coverage a little bit Signed-off-by: Scott K Logan --- rcl_logging_spdlog/test/test_logging_interface.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rcl_logging_spdlog/test/test_logging_interface.cpp b/rcl_logging_spdlog/test/test_logging_interface.cpp index 37bd361..02baed8 100644 --- a/rcl_logging_spdlog/test/test_logging_interface.cpp +++ b/rcl_logging_spdlog/test/test_logging_interface.cpp @@ -38,6 +38,9 @@ TEST_F(LoggingTest, full_cycle) { ASSERT_EQ(0, rcl_logging_external_initialize(nullptr, allocator)); + // Make sure we can call initialize more than once + ASSERT_EQ(0, rcl_logging_external_initialize(nullptr, allocator)); + std::stringstream expected_log; for (int level = RCUTILS_LOG_SEVERITY_UNSET; level <= RCUTILS_LOG_SEVERITY_FATAL; level += 10) { EXPECT_EQ(0, rcl_logging_external_set_logger_level(nullptr, level)); From 46a5633e6539cc4aa0e9861f35cfa1544ba94c43 Mon Sep 17 00:00:00 2001 From: Scott K Logan Date: Tue, 2 Jun 2020 15:09:43 -0700 Subject: [PATCH 4/8] Fix globbing on macOS Signed-off-by: Scott K Logan --- rcl_logging_spdlog/test/fixtures.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/rcl_logging_spdlog/test/fixtures.hpp b/rcl_logging_spdlog/test/fixtures.hpp index f8211be..cc71ddc 100644 --- a/rcl_logging_spdlog/test/fixtures.hpp +++ b/rcl_logging_spdlog/test/fixtures.hpp @@ -29,6 +29,9 @@ #ifdef _WIN32 #define popen _popen #define pclose _pclose +#define DIR_CMD "dir /B" +#else +#define DIR_CMD "ls -d" #endif namespace fs = rcpputils::fs; @@ -79,11 +82,7 @@ class LoggingTest : public AllocatorTest { fs::path log_dir = get_log_dir(); std::stringstream dir_command; - dir_command << "dir"; -#ifdef _WIN32 - dir_command << " /B"; -#endif - dir_command << " " << (log_dir / get_expected_log_prefix()).string() << "*"; + dir_command << DIR_CMD << " " << (log_dir / get_expected_log_prefix()).string() << "*"; FILE * fp = popen(dir_command.str().c_str(), "r"); if (nullptr == fp) { From 2fcfff9f68d7d5204921cb08a55404b903c1c79a Mon Sep 17 00:00:00 2001 From: Scott K Logan Date: Tue, 2 Jun 2020 15:27:10 -0700 Subject: [PATCH 5/8] PR feedback Signed-off-by: Scott K Logan --- rcl_logging_spdlog/test/fixtures.hpp | 20 +++++++++---------- .../test/test_logging_interface.cpp | 16 +++++++++++---- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/rcl_logging_spdlog/test/fixtures.hpp b/rcl_logging_spdlog/test/fixtures.hpp index cc71ddc..fb885d3 100644 --- a/rcl_logging_spdlog/test/fixtures.hpp +++ b/rcl_logging_spdlog/test/fixtures.hpp @@ -90,17 +90,16 @@ class LoggingTest : public AllocatorTest } char raw_line[2048]; - while (fgets(raw_line, sizeof(raw_line), fp) != NULL) { - pclose(fp); - - std::string line(raw_line); - fs::path line_path(line.substr(0, line.find_last_not_of(" \t\r\n") + 1)); - // This should be changed once ros2/rcpputils#68 is resolved - return line_path.is_absolute() ? line_path : log_dir / line_path; + char * ret = fgets(raw_line, sizeof(raw_line), fp); + pclose(fp); + if (nullptr == ret) { + throw std::runtime_error("No log files were found"); } - pclose(fp); - throw std::runtime_error("No log files were found"); + std::string line(raw_line); + fs::path line_path(line.substr(0, line.find_last_not_of(" \t\r\n") + 1)); + // This should be changed once ros2/rcpputils#68 is resolved + return line_path.is_absolute() ? line_path : log_dir / line_path; } private: @@ -111,8 +110,7 @@ class LoggingTest : public AllocatorTest throw std::runtime_error("Failed to determine executable name"); } std::stringstream prefix; - prefix << exe_name << "_" << - rcutils_get_pid() << "_"; + prefix << exe_name << "_" << rcutils_get_pid() << "_"; allocator.deallocate(exe_name, allocator.state); return prefix.str(); } diff --git a/rcl_logging_spdlog/test/test_logging_interface.cpp b/rcl_logging_spdlog/test/test_logging_interface.cpp index 02baed8..132a293 100644 --- a/rcl_logging_spdlog/test/test_logging_interface.cpp +++ b/rcl_logging_spdlog/test/test_logging_interface.cpp @@ -23,6 +23,16 @@ #include "gtest/gtest.h" #include "rcl_logging_spdlog/logging_interface.h" +const int logger_levels[] = +{ + RCUTILS_LOG_SEVERITY_UNSET, + RCUTILS_LOG_SEVERITY_DEBUG, + RCUTILS_LOG_SEVERITY_INFO, + RCUTILS_LOG_SEVERITY_WARN, + RCUTILS_LOG_SEVERITY_ERROR, + RCUTILS_LOG_SEVERITY_FATAL, +}; + TEST_F(LoggingTest, init_invalid) { // Config files are not supported by spdlog @@ -42,12 +52,10 @@ TEST_F(LoggingTest, full_cycle) ASSERT_EQ(0, rcl_logging_external_initialize(nullptr, allocator)); std::stringstream expected_log; - for (int level = RCUTILS_LOG_SEVERITY_UNSET; level <= RCUTILS_LOG_SEVERITY_FATAL; level += 10) { + for (int level : logger_levels) { EXPECT_EQ(0, rcl_logging_external_set_logger_level(nullptr, level)); - for (int severity = RCUTILS_LOG_SEVERITY_UNSET; severity <= RCUTILS_LOG_SEVERITY_FATAL; - severity += 10) - { + for (int severity : logger_levels) { std::stringstream ss; ss << "Message of severity " << severity << " at level " << level; rcl_logging_external_log(severity, nullptr, ss.str().c_str()); From 1f5dad14b3067d8203e6a276fda3f4015558896c Mon Sep 17 00:00:00 2001 From: Scott K Logan Date: Tue, 2 Jun 2020 16:42:07 -0700 Subject: [PATCH 6/8] Add 3 more tests to improve coverage a little bit Signed-off-by: Scott K Logan --- .../test/test_logging_interface.cpp | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/rcl_logging_spdlog/test/test_logging_interface.cpp b/rcl_logging_spdlog/test/test_logging_interface.cpp index 132a293..bf176a4 100644 --- a/rcl_logging_spdlog/test/test_logging_interface.cpp +++ b/rcl_logging_spdlog/test/test_logging_interface.cpp @@ -12,7 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include #include +#include #include #include @@ -23,6 +26,8 @@ #include "gtest/gtest.h" #include "rcl_logging_spdlog/logging_interface.h" +namespace fs = rcpputils::fs; + const int logger_levels[] = { RCUTILS_LOG_SEVERITY_UNSET, @@ -33,6 +38,29 @@ const int logger_levels[] = RCUTILS_LOG_SEVERITY_FATAL, }; +// This is a helper class that resets an environment +// variable when leaving scope +class RestoreEnvVar +{ +public: + explicit RestoreEnvVar(const std::string & name) + : name_(name), + value_(rcpputils::get_env_var(name.c_str())) + { + } + + ~RestoreEnvVar() + { + if (!rcutils_set_env(name_.c_str(), value_.c_str())) { + std::cerr << "Failed to restore value of environment variable: " << name_ << std::endl; + } + } + +private: + const std::string name_; + const std::string value_; +}; + TEST_F(LoggingTest, init_invalid) { // Config files are not supported by spdlog @@ -44,6 +72,39 @@ TEST_F(LoggingTest, init_invalid) rcutils_reset_error(); } +TEST_F(LoggingTest, init_failure) +{ + RestoreEnvVar home_var("HOME"); + RestoreEnvVar userprofile_var("USERPROFILE"); + + // No home directory to write log to + ASSERT_EQ(true, rcutils_set_env("HOME", nullptr)); + ASSERT_EQ(true, rcutils_set_env("USERPROFILE", nullptr)); + EXPECT_EQ(2, rcl_logging_external_initialize(nullptr, allocator)); + rcutils_reset_error(); + + // Force failure to create directories + fs::path fake_home("fake_home_dir"); + ASSERT_TRUE(fs::create_directories(fake_home)); + ASSERT_EQ(true, rcutils_set_env("HOME", fake_home.string().c_str())); + + // ...fail to create .ros dir + fs::path ros_dir = fake_home / ".ros"; + std::fstream(ros_dir.string(), std::ios_base::out).close(); + EXPECT_EQ(2, rcl_logging_external_initialize(nullptr, allocator)); + ASSERT_TRUE(fs::remove(ros_dir)); + + // ...fail to create .ros/log dir + ASSERT_TRUE(fs::create_directories(ros_dir)); + fs::path ros_log_dir = ros_dir / "log"; + std::fstream(ros_log_dir.string(), std::ios_base::out).close(); + EXPECT_EQ(2, rcl_logging_external_initialize(nullptr, allocator)); + ASSERT_TRUE(fs::remove(ros_log_dir)); + ASSERT_TRUE(fs::remove(ros_dir)); + + ASSERT_TRUE(fs::remove(fake_home)); +} + TEST_F(LoggingTest, full_cycle) { ASSERT_EQ(0, rcl_logging_external_initialize(nullptr, allocator)); From ee6a8dcb0fd6b3b04cfa8495274c0919b478cf02 Mon Sep 17 00:00:00 2001 From: Scott K Logan Date: Tue, 2 Jun 2020 16:57:45 -0700 Subject: [PATCH 7/8] Use absolute path in fake home directory Signed-off-by: Scott K Logan --- .../test/test_logging_interface.cpp | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/rcl_logging_spdlog/test/test_logging_interface.cpp b/rcl_logging_spdlog/test/test_logging_interface.cpp index bf176a4..c4f6816 100644 --- a/rcl_logging_spdlog/test/test_logging_interface.cpp +++ b/rcl_logging_spdlog/test/test_logging_interface.cpp @@ -61,6 +61,29 @@ class RestoreEnvVar const std::string value_; }; +// TODO(cottsay): Remove when ros2/rcpputils#63 is resolved +static fs::path current_path() +{ + char * cwd; +#ifdef _WIN32 +#ifdef UNICODE +#error "rcpputils::fs does not support Unicode paths" +#endif + cwd = _getcwd(NULL, 0); +#else + cwd = getcwd(NULL, 0); +#endif + if (nullptr == cwd) { + std::error_code ec{errno, std::system_category()}; + errno = 0; + throw std::system_error{ec, "cannot get current working directory"}; + } + + std::string ret(cwd); + free(cwd); + return fs::path(ret); +} + TEST_F(LoggingTest, init_invalid) { // Config files are not supported by spdlog @@ -84,7 +107,7 @@ TEST_F(LoggingTest, init_failure) rcutils_reset_error(); // Force failure to create directories - fs::path fake_home("fake_home_dir"); + fs::path fake_home = current_path() / "fake_home_dir"; ASSERT_TRUE(fs::create_directories(fake_home)); ASSERT_EQ(true, rcutils_set_env("HOME", fake_home.string().c_str())); From a68f7ae71425ecaa44433c05e74fe650b8656529 Mon Sep 17 00:00:00 2001 From: Scott K Logan Date: Thu, 4 Jun 2020 14:19:33 -0700 Subject: [PATCH 8/8] PR feedback Signed-off-by: Scott K Logan --- rcl_logging_spdlog/test/fixtures.hpp | 7 ++++++- rcl_logging_spdlog/test/test_logging_interface.cpp | 13 ++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/rcl_logging_spdlog/test/fixtures.hpp b/rcl_logging_spdlog/test/fixtures.hpp index fb885d3..51db959 100644 --- a/rcl_logging_spdlog/test/fixtures.hpp +++ b/rcl_logging_spdlog/test/fixtures.hpp @@ -22,6 +22,7 @@ #include #include +#include #include #include "gtest/gtest.h" @@ -89,7 +90,11 @@ class LoggingTest : public AllocatorTest throw std::runtime_error("Failed to glob for log files"); } - char raw_line[2048]; +#ifdef _WIN32 + char raw_line[MAX_PATH]; +#else + char raw_line[PATH_MAX]; +#endif char * ret = fgets(raw_line, sizeof(raw_line), fp); pclose(fp); if (nullptr == ret) { diff --git a/rcl_logging_spdlog/test/test_logging_interface.cpp b/rcl_logging_spdlog/test/test_logging_interface.cpp index c4f6816..e1e9b83 100644 --- a/rcl_logging_spdlog/test/test_logging_interface.cpp +++ b/rcl_logging_spdlog/test/test_logging_interface.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -64,24 +65,22 @@ class RestoreEnvVar // TODO(cottsay): Remove when ros2/rcpputils#63 is resolved static fs::path current_path() { - char * cwd; #ifdef _WIN32 #ifdef UNICODE #error "rcpputils::fs does not support Unicode paths" #endif - cwd = _getcwd(NULL, 0); + char cwd[MAX_PATH]; + if (nullptr == _getcwd(cwd, MAX_PATH)) { #else - cwd = getcwd(NULL, 0); + char cwd[PATH_MAX]; + if (nullptr == getcwd(cwd, PATH_MAX)) { #endif - if (nullptr == cwd) { std::error_code ec{errno, std::system_category()}; errno = 0; throw std::system_error{ec, "cannot get current working directory"}; } - std::string ret(cwd); - free(cwd); - return fs::path(ret); + return fs::path(cwd); } TEST_F(LoggingTest, init_invalid)