2 * Copyright 2017 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <folly/experimental/TestUtil.h>
19 #include <sys/types.h>
21 #include <system_error>
23 #include <boost/algorithm/string.hpp>
24 #include <glog/logging.h>
26 #include <folly/Memory.h>
27 #include <folly/portability/Environment.h>
28 #include <folly/portability/Fcntl.h>
29 #include <folly/portability/GTest.h>
31 using namespace folly;
32 using namespace folly::test;
34 TEST(TemporaryFile, Simple) {
39 EXPECT_FALSE(f.path().empty());
40 EXPECT_TRUE(f.path().is_absolute());
43 ssize_t r = write(fd, &c, 1);
47 msvcSuppressAbortOnInvalidParams([&] {
48 // The file must have been closed. This assumes that no other thread
49 // has opened another file in the meanwhile, which is a sane assumption
50 // to make in this test.
51 ssize_t r = write(fd, &c, 1);
52 int savedErrno = errno;
54 EXPECT_EQ(EBADF, savedErrno);
58 TEST(TemporaryFile, Prefix) {
59 TemporaryFile f("Foo");
60 EXPECT_TRUE(f.path().is_absolute());
61 EXPECT_TRUE(boost::algorithm::starts_with(f.path().filename().native(),
65 TEST(TemporaryFile, PathPrefix) {
66 TemporaryFile f("Foo", ".");
67 EXPECT_EQ(fs::path("."), f.path().parent_path());
68 EXPECT_TRUE(boost::algorithm::starts_with(f.path().filename().native(),
72 TEST(TemporaryFile, NoSuchPath) {
73 EXPECT_THROW({TemporaryFile f("", "/no/such/path");},
77 void testTemporaryDirectory(TemporaryDirectory::Scope scope) {
80 TemporaryDirectory d("", "", scope);
82 EXPECT_FALSE(path.empty());
83 EXPECT_TRUE(path.is_absolute());
84 EXPECT_TRUE(fs::exists(path));
85 EXPECT_TRUE(fs::is_directory(path));
87 fs::path fp = path / "bar";
88 int fd = open(fp.string().c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666);
92 TemporaryFile f("Foo", d.path());
93 EXPECT_EQ(d.path(), f.path().parent_path());
95 bool exists = (scope == TemporaryDirectory::Scope::PERMANENT);
96 EXPECT_EQ(exists, fs::exists(path));
99 TEST(TemporaryDirectory, Permanent) {
100 testTemporaryDirectory(TemporaryDirectory::Scope::PERMANENT);
103 TEST(TemporaryDirectory, DeleteOnDestruction) {
104 testTemporaryDirectory(TemporaryDirectory::Scope::DELETE_ON_DESTRUCTION);
107 void expectTempdirExists(const TemporaryDirectory& d) {
108 EXPECT_FALSE(d.path().empty());
109 EXPECT_TRUE(fs::exists(d.path()));
110 EXPECT_TRUE(fs::is_directory(d.path()));
113 TEST(TemporaryDirectory, SafelyMove) {
114 std::unique_ptr<TemporaryDirectory> dir;
115 TemporaryDirectory dir2;
117 auto scope = TemporaryDirectory::Scope::DELETE_ON_DESTRUCTION;
118 TemporaryDirectory d("", "", scope);
119 TemporaryDirectory d2("", "", scope);
120 expectTempdirExists(d);
121 expectTempdirExists(d2);
123 dir = folly::make_unique<TemporaryDirectory>(std::move(d));
124 dir2 = std::move(d2);
127 expectTempdirExists(*dir);
128 expectTempdirExists(dir2);
131 TEST(ChangeToTempDir, ChangeDir) {
132 auto pwd1 = fs::current_path();
135 EXPECT_NE(pwd1, fs::current_path());
137 EXPECT_EQ(pwd1, fs::current_path());
140 TEST(PCREPatternMatch, Simple) {
141 EXPECT_PCRE_MATCH(".*a.c.*", "gabca");
142 EXPECT_NO_PCRE_MATCH("a.c", "gabca");
143 EXPECT_NO_PCRE_MATCH(".*ac.*", "gabca");
146 TEST(CaptureFD, GlogPatterns) {
147 CaptureFD err(fileno(stderr));
148 LOG(INFO) << "All is well";
149 EXPECT_NO_PCRE_MATCH(glogErrOrWarnPattern(), err.readIncremental());
151 LOG(ERROR) << "Uh-oh";
152 auto s = err.readIncremental();
153 EXPECT_PCRE_MATCH(glogErrorPattern(), s);
154 EXPECT_NO_PCRE_MATCH(glogWarningPattern(), s);
155 EXPECT_PCRE_MATCH(glogErrOrWarnPattern(), s);
158 LOG(WARNING) << "Oops";
159 auto s = err.readIncremental();
160 EXPECT_NO_PCRE_MATCH(glogErrorPattern(), s);
161 EXPECT_PCRE_MATCH(glogWarningPattern(), s);
162 EXPECT_PCRE_MATCH(glogErrOrWarnPattern(), s);
166 TEST(CaptureFD, ChunkCob) {
167 std::vector<std::string> chunks;
169 CaptureFD err(fileno(stderr), [&](StringPiece p) {
170 chunks.emplace_back(p.str());
171 switch (chunks.size()) {
173 EXPECT_PCRE_MATCH(".*foo.*bar.*", p);
176 EXPECT_PCRE_MATCH("[^\n]*baz.*", p);
179 FAIL() << "Got too many chunks: " << chunks.size();
184 EXPECT_PCRE_MATCH(".*foo.*bar.*", err.read());
185 auto chunk = err.readIncremental();
186 EXPECT_EQ(chunks.at(0), chunk);
188 EXPECT_PCRE_MATCH(".*foo.*bar.*baz.*", err.read());
190 EXPECT_EQ(2, chunks.size());
194 class EnvVarSaverTest : public testing::Test {};
196 TEST_F(EnvVarSaverTest, ExampleNew) {
197 auto key = "hahahahaha";
198 EXPECT_EQ(nullptr, getenv(key));
200 PCHECK(0 == setenv(key, "", true));
201 EXPECT_STREQ("", getenv(key));
202 PCHECK(0 == unsetenv(key));
203 EXPECT_EQ(nullptr, getenv(key));
205 auto saver = make_unique<EnvVarSaver>();
206 PCHECK(0 == setenv(key, "blah", true));
207 EXPECT_EQ("blah", std::string{getenv(key)});
209 EXPECT_EQ(nullptr, getenv(key));
212 TEST_F(EnvVarSaverTest, ExampleExisting) {
214 EXPECT_NE(nullptr, getenv(key));
215 auto value = std::string{getenv(key)};
217 auto saver = make_unique<EnvVarSaver>();
218 PCHECK(0 == setenv(key, "blah", true));
219 EXPECT_EQ("blah", std::string{getenv(key)});
221 EXPECT_TRUE(value == getenv(key));
224 TEST_F(EnvVarSaverTest, ExampleDeleting) {
226 EXPECT_NE(nullptr, getenv(key));
227 auto value = std::string{getenv(key)};
229 auto saver = make_unique<EnvVarSaver>();
230 PCHECK(0 == unsetenv(key));
231 EXPECT_EQ(nullptr, getenv(key));
233 EXPECT_TRUE(value == getenv(key));
236 int main(int argc, char *argv[]) {
237 testing::InitGoogleTest(&argc, argv);
238 gflags::ParseCommandLineFlags(&argc, &argv, true);
239 return RUN_ALL_TESTS();