diff --git a/test/test.gyp b/test/test.gyp index 728a240410..a55f56c8ff 100644 --- a/test/test.gyp +++ b/test/test.gyp @@ -16,11 +16,30 @@ 'target_name': 'test_support', 'type': 'static_library', 'dependencies': [ - '../testing/gtest.gyp:gtest', + '<(webrtc_root)/../testing/gtest.gyp:gtest', ], + 'direct_dependent_settings': { + 'include_dirs': [ + '.', + ], + }, 'sources': [ 'test_suite.cc', 'test_suite.h', + 'testsupport/fileutils.h', + 'testsupport/fileutils.cc', + ], + }, + { + 'target_name': 'test_support_unittests', + 'type': 'executable', + 'dependencies': [ + 'test_support', + '<(webrtc_root)/../testing/gtest.gyp:gtest', + ], + 'sources': [ + 'run_all_unittests.cc', + 'testsupport/fileutils_unittest.cc', ], }, ], diff --git a/test/testsupport/fileutils.cc b/test/testsupport/fileutils.cc new file mode 100644 index 0000000000..cc35772028 --- /dev/null +++ b/test/testsupport/fileutils.cc @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "fileutils.h" + +#ifdef WIN32 +#include +#define GET_CURRENT_DIR _getcwd +#define PATH_DELIMITER "\\" +#else +#include +#define GET_CURRENT_DIR getcwd +#define PATH_DELIMITER "/" +#endif + +#include + +namespace webrtc { +namespace test { + +const std::string GetProjectRootPath() { + char path_buffer[FILENAME_MAX]; + if (!GET_CURRENT_DIR(path_buffer, sizeof(path_buffer))) { + fprintf(stderr, "Cannot get current directory!\n"); + return kCannotFindProjectRootDir; + } + + // Check for our file that verifies the root dir. + std::string current_path(path_buffer); + FILE* file = NULL; + int path_delimiter_index = current_path.find_last_of(PATH_DELIMITER); + while (path_delimiter_index > -1) { + std::string root_filename = current_path + PATH_DELIMITER + + kProjectRootFileName; + file = fopen(root_filename.c_str(), "r"); + if (file != NULL) { + return current_path + PATH_DELIMITER; + } + + // 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(PATH_DELIMITER); + } + + // Reached the root directory. + fprintf(stderr, "Cannot find project root directory!\n"); + return kCannotFindProjectRootDir; +} + +} // namespace webrtc +} // namespace test diff --git a/test/testsupport/fileutils.h b/test/testsupport/fileutils.h new file mode 100644 index 0000000000..f59b651ab5 --- /dev/null +++ b/test/testsupport/fileutils.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// File utilities for testing purposes. +// The GetProjectRootPath() method is a convenient way of getting an absolute +// path to the project source tree root directory. Using this, it is easy to +// refer to test resource files in a portable way. +// +// Notice that even if Windows platforms use backslash as path delimiter, it is +// also supported to use slash, so there's no need for #ifdef checks in test +// code for setting up the paths to the resource files. +// +// Example use: +// Assume we have the following code being used in a test source file: +// const std::string kInputFile = webrtc::testing::GetProjectRootPath() + +// "test/data/voice_engine/audio_long16.wav"; +// // Use the kInputFile for the tests... +// +// Then here's some example outputs for different platforms: +// Linux: +// * Source tree located in /home/user/webrtc/trunk +// * Test project located in /home/user/webrtc/trunk/src/testproject +// * Test binary compiled as: +// /home/user/webrtc/trunk/out/Debug/testproject_unittests +// Then GetProjectRootPath() will return /home/user/webrtc/trunk/ no matter if +// the test binary is executed from standing in either of: +// /home/user/webrtc/trunk +// or +// /home/user/webrtc/trunk/out/Debug +// (or any other directory below the trunk for that matter). +// +// Windows: +// * Source tree located in C:\Users\user\webrtc\trunk +// * Test project located in C:\Users\user\webrtc\trunk\src\testproject +// * Test binary compiled as: +// C:\Users\user\webrtc\trunk\src\testproject\Debug\testproject_unittests.exe +// Then GetProjectRootPath() will return C:\Users\user\webrtc\trunk\ when the +// test binary is executed from inside Visual Studio. +// It will also return the same path if the test is executed from a command +// prompt standing in C:\Users\user\webrtc\trunk\src\testproject\Debug +// +// Mac: +// * Source tree located in /Users/user/webrtc/trunk +// * Test project located in /Users/user/webrtc/trunk/src/testproject +// * Test binary compiled as: +// /Users/user/webrtc/trunk/xcodebuild/Debug/testproject_unittests +// Then GetProjectRootPath() will return /Users/user/webrtc/trunk/ no matter if +// the test binary is executed from standing in either of: +// /Users/user/webrtc/trunk +// or +// /Users/user/webrtc/trunk/out/Debug +// (or any other directory below the trunk for that matter). + +#ifndef TEST_TESTSUPPORT_FILEUTILS_H_ +#define TEST_TESTSUPPORT_FILEUTILS_H_ + +#include + +namespace webrtc { +namespace test { + +// The file we're looking for to identify the project root dir. +const std::string kProjectRootFileName = "DEPS"; + +// This is the "directory" returned if the GetProjectPath() function fails +// to find the project root. +const std::string kCannotFindProjectRootDir = + "ERROR_CANNOT_FIND_PROJECT_ROOT_DIR"; + +// Finds the root dir of the project, to be able to set correct paths to +// resource files used by tests. +// The implementation is simple: it just looks for the file defined by +// kProjectRootFileName, starting in the current directory (the working +// directory) and then steps upward until it is found (or it is at the root of +// the file system). +// If the current working directory is above the project root dir, it will not +// be found. +// +// If symbolic links occur in the path they will be resolved and the actual +// directory will be returned. +// +// Returns the absolute path to the project root dir (usually the trunk dir) +// WITH a trailing path delimiter. +// If the project root is not found, the string specified by +// kCannotFindProjectRootDir is returned. +const std::string GetProjectRootPath(); + +} // namespace webrtc +} // namespace test + +#endif // TEST_TESTSUPPORT_FILEUTILS_H_ diff --git a/test/testsupport/fileutils_unittest.cc b/test/testsupport/fileutils_unittest.cc new file mode 100644 index 0000000000..f3772c4fe3 --- /dev/null +++ b/test/testsupport/fileutils_unittest.cc @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include "fileutils.h" +#include "gtest/gtest.h" + +#ifdef WIN32 +#define PATH_DELIMITER "\\" +#else +#define PATH_DELIMITER "/" +#endif + +namespace webrtc { +namespace test { + +// Tests that the project root path is returnd for the default working directory +// that is automatically set when the test executable is launched. +// The test is not fully testing the implementation, since we cannot be sure +// of where the executable was launched from. +// The test will fail if the top level directory is not named "trunk". +TEST(FileUtilsTest, GetProjectRootPathFromUnchangedWorkingDir) { + std::string path = GetProjectRootPath(); + std::string expected_end = "trunk"; + expected_end = PATH_DELIMITER + expected_end + PATH_DELIMITER; + 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(FileUtilsTest, GetProjectRootPathFromDeeperWorkingDir) { + std::string path = GetProjectRootPath(); + std::string original_working_dir = path; // This is the correct project root + + // Change to a subdirectory path (the full path doesn't have to exist). + path += "foo/bar/baz"; + chdir(path.c_str()); + + ASSERT_EQ(original_working_dir, GetProjectRootPath()); +} + +// 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). +TEST(FileUtilsTest, GetProjectRootPathFromRootWorkingDir) { + // Change current working dir to the root of the current file system + // (this will always be "above" our project root dir). + chdir(PATH_DELIMITER); + ASSERT_EQ(kCannotFindProjectRootDir, GetProjectRootPath()); +} + +} // namespace test +} // namespace webrtc