diff --git a/src/test/test_suite.cc b/src/test/test_suite.cc index ac3f3a23c..296dd5837 100644 --- a/src/test/test_suite.cc +++ b/src/test/test_suite.cc @@ -9,13 +9,16 @@ */ #include "test/test_suite.h" +#include "test/testsupport/fileutils.h" #include "gmock/gmock.h" #include "gtest/gtest.h" namespace webrtc { namespace test { + TestSuite::TestSuite(int argc, char** argv) { + SetRelativeExecutablePath(argv[0]); testing::InitGoogleMock(&argc, argv); // Runs InitGoogleTest() internally. } diff --git a/src/test/testsupport/fileutils.cc b/src/test/testsupport/fileutils.cc index 0679b1f5f..9ec8d5fac 100644 --- a/src/test/testsupport/fileutils.cc +++ b/src/test/testsupport/fileutils.cc @@ -24,6 +24,7 @@ #endif #include +#include #include "typedefs.h" // For architecture defines @@ -46,26 +47,41 @@ static const char* kResourcesDirName = "resources"; #endif const char* kCannotFindProjectRootDir = "ERROR_CANNOT_FIND_PROJECT_ROOT_DIR"; +namespace { +char relative_dir_path[FILENAME_MAX]; +bool relative_dir_path_set = false; +} + +void SetRelativeExecutablePath(const std::string& path) { + // Trim away the executable name; we only want to store the relative dir path. + std::string temp_path = path.substr(0, path.find_last_of(kPathDelimiter)); + strncpy(relative_dir_path, temp_path.c_str(), FILENAME_MAX); + relative_dir_path_set = true; +} + +bool FileExists(std::string& file_name) { + struct stat file_info = {0}; + return stat(file_name.c_str(), &file_info) == 0; +} + std::string ProjectRootPath() { - std::string working_dir = WorkingDir(); - if (working_dir == kFallbackPath) { + std::string path = WorkingDir(); + if (path == kFallbackPath) { return kCannotFindProjectRootDir; } + if (relative_dir_path_set) { + path = path + kPathDelimiter + relative_dir_path; + } // Check for our file that verifies the root dir. - std::string current_path(working_dir); - FILE* file = NULL; - int path_delimiter_index = current_path.find_last_of(kPathDelimiter); + int path_delimiter_index = path.find_last_of(kPathDelimiter); while (path_delimiter_index > -1) { - std::string root_filename = current_path + kPathDelimiter + - kProjectRootFileName; - file = fopen(root_filename.c_str(), "r"); - if (file != NULL) { - fclose(file); - return current_path + kPathDelimiter; + std::string root_filename = path + kPathDelimiter + kProjectRootFileName; + if (FileExists(root_filename)) { + return path + kPathDelimiter; } // Move up one directory in the directory tree. - current_path = current_path.substr(0, path_delimiter_index); - path_delimiter_index = current_path.find_last_of(kPathDelimiter); + path = path.substr(0, path_delimiter_index); + path_delimiter_index = path.find_last_of(kPathDelimiter); } // Reached the root directory. fprintf(stderr, "Cannot find project root directory!\n"); @@ -126,11 +142,6 @@ bool CreateDirectory(std::string directory_name) { return true; } -bool FileExists(std::string file_name) { - struct stat file_info = {0}; - return stat(file_name.c_str(), &file_info) == 0; -} - std::string ResourcePath(std::string name, std::string extension) { std::string platform = "win"; #ifdef WEBRTC_LINUX diff --git a/src/test/testsupport/fileutils.h b/src/test/testsupport/fileutils.h index b6c134692..4fbc7abc2 100644 --- a/src/test/testsupport/fileutils.h +++ b/src/test/testsupport/fileutils.h @@ -138,6 +138,13 @@ bool CreateDirectory(std::string directory_name); // empty or if the file does not exist/is readable. size_t GetFileSize(std::string filename); +// Sets the relative executable path, i.e. the path to the executable relative +// to the working directory (the value of argv[0] for the main function on most +// platforms). By using this function, it becomes possible to fileutils.h to +// find the correct project paths even when the working directory is outside the +// project tree when running programs linked with the test_support_main target. +void SetRelativeExecutablePath(const std::string& relative_path_to_executable); + } // namespace test } // namespace webrtc diff --git a/src/test/testsupport/fileutils_unittest.cc b/src/test/testsupport/fileutils_unittest.cc index 1b76b3cae..795ad5bfd 100644 --- a/src/test/testsupport/fileutils_unittest.cc +++ b/src/test/testsupport/fileutils_unittest.cc @@ -23,7 +23,6 @@ static const char* kPathDelimiter = "\\"; static const char* kPathDelimiter = "/"; #endif -static const std::string kDummyDir = "file_utils_unittest_dummy_dir"; static const std::string kResourcesDir = "resources"; static const std::string kTestName = "fileutils_unittest"; static const std::string kExtension = "tmp"; @@ -68,9 +67,6 @@ class FileUtilsTest : public testing::Test { ASSERT_GT(fprintf(file, "%s", "Dummy data"), 0); fclose(file); } - // Create a dummy subdir that can be chdir'ed into for testing purposes. - empty_dummy_dir_ = original_working_dir_ + kPathDelimiter + kDummyDir; - webrtc::test::CreateDirectory(empty_dummy_dir_); } static void TearDownTestCase() { // Clean up all resource files written @@ -78,7 +74,6 @@ class FileUtilsTest : public testing::Test { file_it != files_.end(); ++file_it) { remove(file_it->c_str()); } - std::remove(empty_dummy_dir_.c_str()); } void SetUp() { ASSERT_EQ(chdir(original_working_dir_.c_str()), 0); @@ -88,14 +83,12 @@ class FileUtilsTest : public testing::Test { } protected: static FileList files_; - static std::string empty_dummy_dir_; private: static std::string original_working_dir_; }; FileList FileUtilsTest::files_; std::string FileUtilsTest::original_working_dir_ = ""; -std::string FileUtilsTest::empty_dummy_dir_ = ""; // Tests that the project root path is returned for the default working // directory that is automatically set when the test executable is launched. @@ -117,25 +110,6 @@ TEST_F(FileUtilsTest, OutputPathFromUnchangedWorkingDir) { ASSERT_EQ(path.length() - expected_end.length(), path.find(expected_end)); } -// Tests setting the current working directory to a directory three levels -// deeper from the current one. Then testing that the project path returned -// is still the same, when the function under test is called again. -TEST_F(FileUtilsTest, ProjectRootPathFromDeeperWorkingDir) { - std::string path = webrtc::test::ProjectRootPath(); - std::string original_working_dir = path; // This is the correct project root - // Change to a subdirectory path. - ASSERT_EQ(0, chdir(empty_dummy_dir_.c_str())); - ASSERT_EQ(original_working_dir, webrtc::test::ProjectRootPath()); -} - -// Similar to the above test, but for the output dir -TEST_F(FileUtilsTest, OutputPathFromDeeperWorkingDir) { - std::string path = webrtc::test::OutputPath(); - std::string original_working_dir = path; - ASSERT_EQ(0, chdir(empty_dummy_dir_.c_str())); - ASSERT_EQ(original_working_dir, webrtc::test::OutputPath()); -} - // Tests with current working directory set to a directory higher up in the // directory tree than the project root dir. This case shall return a specified // error string as a directory (which will be an invalid path).