Skip to content

Commit 912db74

Browse files
Abseil Teamcopybara-github
Abseil Team
authored andcommitted
Defined a testing::SrcDir() function that returns the name of a directory
where ancillary data files can be found. PiperOrigin-RevId: 487896836 Change-Id: Ie6b1ba734e900fa33872b63090879ee6efe33411
1 parent 44c0364 commit 912db74

File tree

3 files changed

+140
-11
lines changed

3 files changed

+140
-11
lines changed

googletest/include/gtest/gtest.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2201,10 +2201,17 @@ constexpr bool StaticAssertTypeEq() noexcept {
22012201
#define TEST_F(test_fixture, test_name) GTEST_TEST_F(test_fixture, test_name)
22022202
#endif
22032203

2204-
// Returns a path to temporary directory.
2205-
// Tries to determine an appropriate directory for the platform.
2204+
// Returns a path to a temporary directory, which should be writable. It is
2205+
// implementation-dependent whether or not the path is terminated by the
2206+
// directory-separator character.
22062207
GTEST_API_ std::string TempDir();
22072208

2209+
// Returns a path to a directory that contains ancillary data files that might
2210+
// be used by tests. It is implementation dependent whether or not the path is
2211+
// terminated by the directory-separator character. The directory and the files
2212+
// in it should be considered read-only.
2213+
GTEST_API_ std::string SrcDir();
2214+
22082215
#ifdef _MSC_VER
22092216
#pragma warning(pop)
22102217
#endif

googletest/src/gtest.cc

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6754,12 +6754,13 @@ void InitGoogleTest() {
67546754
#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
67556755
}
67566756

6757-
#if !defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
6758-
// Return value of first environment variable that is set and contains
6759-
// a non-empty string. If there are none, return the "fallback" string.
6760-
// Since we like the temporary directory to have a directory separator suffix,
6761-
// add it if not provided in the environment variable value.
6762-
static std::string GetTempDirFromEnv(
6757+
#if !defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) || \
6758+
!defined(GTEST_CUSTOM_SRCDIR_FUNCTION_)
6759+
// Returns the value of the first environment variable that is set and contains
6760+
// a non-empty string. If there are none, returns the "fallback" string. Adds
6761+
// the director-separator character as a suffix if not provided in the
6762+
// environment variable value.
6763+
static std::string GetDirFromEnv(
67636764
std::initializer_list<const char*> environment_variables,
67646765
const char* fallback, char separator) {
67656766
for (const char* variable_name : environment_variables) {
@@ -6779,11 +6780,35 @@ std::string TempDir() {
67796780
#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
67806781
return GTEST_CUSTOM_TEMPDIR_FUNCTION_();
67816782
#elif GTEST_OS_WINDOWS || GTEST_OS_WINDOWS_MOBILE
6782-
return GetTempDirFromEnv({"TEST_TMPDIR", "TEMP"}, "\\temp\\", '\\');
6783+
return GetDirFromEnv({"TEST_TMPDIR", "TEMP"}, "\\temp\\", '\\');
67836784
#elif GTEST_OS_LINUX_ANDROID
6784-
return GetTempDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/data/local/tmp/", '/');
6785+
return GetDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/data/local/tmp/", '/');
67856786
#else
6786-
return GetTempDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/tmp/", '/');
6787+
return GetDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/tmp/", '/');
6788+
#endif
6789+
}
6790+
6791+
#if !defined(GTEST_CUSTOM_SRCDIR_FUNCTION_)
6792+
// Returns the directory path (including terminating separator) of the current
6793+
// executable as derived from argv[0].
6794+
static std::string GetCurrentExecutableDirectory() {
6795+
internal::FilePath argv_0(internal::GetArgvs()[0]);
6796+
return argv_0.RemoveFileName().string();
6797+
}
6798+
#endif
6799+
6800+
std::string SrcDir() {
6801+
#if defined(GTEST_CUSTOM_SRCDIR_FUNCTION_)
6802+
return GTEST_CUSTOM_SRCDIR_FUNCTION_();
6803+
#elif GTEST_OS_WINDOWS || GTEST_OS_WINDOWS_MOBILE
6804+
return GetDirFromEnv({"TEST_SRCDIR"}, GetCurrentExecutableDirectory().c_str(),
6805+
'\\');
6806+
#elif GTEST_OS_LINUX_ANDROID
6807+
return GetDirFromEnv({"TEST_SRCDIR"}, GetCurrentExecutableDirectory().c_str(),
6808+
'/');
6809+
#else
6810+
return GetDirFromEnv({"TEST_SRCDIR"}, GetCurrentExecutableDirectory().c_str(),
6811+
'/');
67876812
#endif
67886813
}
67896814

googletest/test/gtest_dirs_test.cc

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#include <sys/stat.h>
2+
3+
#include <cstdlib>
4+
#include <cstring>
5+
#include <string>
6+
7+
#include "gtest/gtest.h"
8+
#include "gtest/internal/gtest-port.h"
9+
10+
namespace {
11+
12+
class SetEnv {
13+
public:
14+
// Sets the environment value with name `name` to `value`, unless `value` is
15+
// nullptr, in which case it unsets it. Restores the original value on
16+
// destruction.
17+
SetEnv(const char* name, const char* value) : name_(name) {
18+
const char* old_value = getenv(name);
19+
if (old_value != nullptr) {
20+
saved_value_ = old_value;
21+
have_saved_value_ = true;
22+
}
23+
if (value == nullptr) {
24+
GTEST_CHECK_POSIX_SUCCESS_(unsetenv(name));
25+
} else {
26+
GTEST_CHECK_POSIX_SUCCESS_(setenv(name, value, 1 /*overwrite*/));
27+
}
28+
}
29+
30+
~SetEnv() {
31+
if (have_saved_value_) {
32+
GTEST_CHECK_POSIX_SUCCESS_(
33+
setenv(name_.c_str(), saved_value_.c_str(), 1 /*overwrite*/));
34+
} else {
35+
GTEST_CHECK_POSIX_SUCCESS_(unsetenv(name_.c_str()));
36+
}
37+
}
38+
39+
private:
40+
std::string name_;
41+
bool have_saved_value_ = false;
42+
std::string saved_value_;
43+
};
44+
45+
class MakeTempDir {
46+
public:
47+
// Creates a directory with a unique name including `testname`.
48+
// The destructor removes it.
49+
explicit MakeTempDir(const std::string& testname) {
50+
// mkdtemp requires that the last 6 characters of the input pattern
51+
// are Xs, and the string is modified by replacing those characters.
52+
std::string pattern = "/tmp/" + testname + "_XXXXXX";
53+
GTEST_CHECK_(mkdtemp(pattern.data()) != nullptr);
54+
dirname_ = pattern;
55+
}
56+
57+
~MakeTempDir() { GTEST_CHECK_POSIX_SUCCESS_(rmdir(dirname_.c_str())); }
58+
59+
const char* DirName() const { return dirname_.c_str(); }
60+
61+
private:
62+
std::string dirname_;
63+
};
64+
65+
bool StartsWith(const std::string& str, const std::string& prefix) {
66+
return str.substr(0, prefix.size()) == prefix;
67+
}
68+
69+
TEST(TempDirTest, InEnvironment) {
70+
// Since the test infrastructure might be verifying directory existence or
71+
// even creating subdirectories, we need to be careful that the directories we
72+
// specify are actually valid.
73+
MakeTempDir temp_dir("TempDirTest_InEnvironment");
74+
SetEnv set_env("TEST_TMPDIR", temp_dir.DirName());
75+
EXPECT_TRUE(StartsWith(testing::TempDir(), temp_dir.DirName()));
76+
}
77+
78+
TEST(TempDirTest, NotInEnvironment) {
79+
SetEnv set_env("TEST_TMPDIR", nullptr);
80+
EXPECT_NE(testing::TempDir(), "");
81+
}
82+
83+
TEST(SrcDirTest, InEnvironment) {
84+
// Since the test infrastructure might be verifying directory existence or
85+
// even creating subdirectories, we need to be careful that the directories we
86+
// specify are actually valid.
87+
MakeTempDir temp_dir("SrcDirTest_InEnvironment");
88+
SetEnv set_env("TEST_SRCDIR", temp_dir.DirName());
89+
EXPECT_TRUE(StartsWith(testing::SrcDir(), temp_dir.DirName()));
90+
}
91+
92+
TEST(SrcDirTest, NotInEnvironment) {
93+
SetEnv set_env("TEST_SRCDIR", nullptr);
94+
EXPECT_NE(testing::SrcDir(), "");
95+
}
96+
97+
} // namespace

0 commit comments

Comments
 (0)