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