2 * Copyright 2016 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>
20 #include <sys/types.h>
22 #include <system_error>
24 #include <boost/algorithm/string.hpp>
25 #include <glog/logging.h>
26 #include <gtest/gtest.h>
28 #include <folly/Memory.h>
29 #include <folly/portability/Environment.h>
30 #include <folly/portability/Fcntl.h>
32 using namespace folly;
33 using namespace folly::test;
35 TEST(TemporaryFile, Simple) {
40 EXPECT_FALSE(f.path().empty());
41 EXPECT_TRUE(f.path().is_absolute());
44 ssize_t r = write(fd, &c, 1);
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);
57 TEST(TemporaryFile, Prefix) {
58 TemporaryFile f("Foo");
59 EXPECT_TRUE(f.path().is_absolute());
60 EXPECT_TRUE(boost::algorithm::starts_with(f.path().filename().native(),
64 TEST(TemporaryFile, PathPrefix) {
65 TemporaryFile f("Foo", ".");
66 EXPECT_EQ(fs::path("."), f.path().parent_path());
67 EXPECT_TRUE(boost::algorithm::starts_with(f.path().filename().native(),
71 TEST(TemporaryFile, NoSuchPath) {
72 EXPECT_THROW({TemporaryFile f("", "/no/such/path");},
76 void testTemporaryDirectory(TemporaryDirectory::Scope scope) {
79 TemporaryDirectory d("", "", scope);
81 EXPECT_FALSE(path.empty());
82 EXPECT_TRUE(path.is_absolute());
83 EXPECT_TRUE(fs::exists(path));
84 EXPECT_TRUE(fs::is_directory(path));
86 fs::path fp = path / "bar";
87 int fd = open(fp.string().c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666);
91 TemporaryFile f("Foo", d.path());
92 EXPECT_EQ(d.path(), f.path().parent_path());
94 bool exists = (scope == TemporaryDirectory::Scope::PERMANENT);
95 EXPECT_EQ(exists, fs::exists(path));
98 TEST(TemporaryDirectory, Permanent) {
99 testTemporaryDirectory(TemporaryDirectory::Scope::PERMANENT);
102 TEST(TemporaryDirectory, DeleteOnDestruction) {
103 testTemporaryDirectory(TemporaryDirectory::Scope::DELETE_ON_DESTRUCTION);
106 void expectTempdirExists(const TemporaryDirectory& d) {
107 EXPECT_FALSE(d.path().empty());
108 EXPECT_TRUE(fs::exists(d.path()));
109 EXPECT_TRUE(fs::is_directory(d.path()));
112 TEST(TemporaryDirectory, SafelyMove) {
113 std::unique_ptr<TemporaryDirectory> dir;
114 TemporaryDirectory dir2;
116 auto scope = TemporaryDirectory::Scope::DELETE_ON_DESTRUCTION;
117 TemporaryDirectory d("", "", scope);
118 TemporaryDirectory d2("", "", scope);
119 expectTempdirExists(d);
120 expectTempdirExists(d2);
122 dir = folly::make_unique<TemporaryDirectory>(std::move(d));
123 dir2 = std::move(d2);
126 expectTempdirExists(*dir);
127 expectTempdirExists(dir2);
130 TEST(ChangeToTempDir, ChangeDir) {
131 auto pwd1 = fs::current_path();
134 EXPECT_NE(pwd1, fs::current_path());
136 EXPECT_EQ(pwd1, fs::current_path());
139 TEST(PCREPatternMatch, Simple) {
140 EXPECT_PCRE_MATCH(".*a.c.*", "gabca");
141 EXPECT_NO_PCRE_MATCH("a.c", "gabca");
142 EXPECT_NO_PCRE_MATCH(".*ac.*", "gabca");
145 TEST(CaptureFD, GlogPatterns) {
146 CaptureFD err(fileno(stderr));
147 LOG(INFO) << "All is well";
148 EXPECT_NO_PCRE_MATCH(glogErrOrWarnPattern(), err.readIncremental());
150 LOG(ERROR) << "Uh-oh";
151 auto s = err.readIncremental();
152 EXPECT_PCRE_MATCH(glogErrorPattern(), s);
153 EXPECT_NO_PCRE_MATCH(glogWarningPattern(), s);
154 EXPECT_PCRE_MATCH(glogErrOrWarnPattern(), s);
157 LOG(WARNING) << "Oops";
158 auto s = err.readIncremental();
159 EXPECT_NO_PCRE_MATCH(glogErrorPattern(), s);
160 EXPECT_PCRE_MATCH(glogWarningPattern(), s);
161 EXPECT_PCRE_MATCH(glogErrOrWarnPattern(), s);
165 TEST(CaptureFD, ChunkCob) {
166 std::vector<std::string> chunks;
168 CaptureFD err(fileno(stderr), [&](StringPiece p) {
169 chunks.emplace_back(p.str());
170 switch (chunks.size()) {
172 EXPECT_PCRE_MATCH(".*foo.*bar.*", p);
175 EXPECT_PCRE_MATCH("[^\n]*baz.*", p);
178 FAIL() << "Got too many chunks: " << chunks.size();
183 EXPECT_PCRE_MATCH(".*foo.*bar.*", err.read());
184 auto chunk = err.readIncremental();
185 EXPECT_EQ(chunks.at(0), chunk);
187 EXPECT_PCRE_MATCH(".*foo.*bar.*baz.*", err.read());
189 EXPECT_EQ(2, chunks.size());
193 class EnvVarSaverTest : public testing::Test {};
195 TEST_F(EnvVarSaverTest, ExampleNew) {
196 auto key = "hahahahaha";
197 EXPECT_EQ(nullptr, getenv(key));
199 PCHECK(0 == setenv(key, "", true));
200 EXPECT_STREQ("", getenv(key));
201 PCHECK(0 == unsetenv(key));
202 EXPECT_EQ(nullptr, getenv(key));
204 auto saver = make_unique<EnvVarSaver>();
205 PCHECK(0 == setenv(key, "blah", true));
206 EXPECT_EQ("blah", std::string{getenv(key)});
208 EXPECT_EQ(nullptr, getenv(key));
211 TEST_F(EnvVarSaverTest, ExampleExisting) {
213 EXPECT_NE(nullptr, getenv(key));
214 auto value = std::string{getenv(key)};
216 auto saver = make_unique<EnvVarSaver>();
217 PCHECK(0 == setenv(key, "blah", true));
218 EXPECT_EQ("blah", std::string{getenv(key)});
220 EXPECT_TRUE(value == getenv(key));
223 TEST_F(EnvVarSaverTest, ExampleDeleting) {
225 EXPECT_NE(nullptr, getenv(key));
226 auto value = std::string{getenv(key)};
228 auto saver = make_unique<EnvVarSaver>();
229 PCHECK(0 == unsetenv(key));
230 EXPECT_EQ(nullptr, getenv(key));
232 EXPECT_TRUE(value == getenv(key));
235 int main(int argc, char *argv[]) {
236 testing::InitGoogleTest(&argc, argv);
237 gflags::ParseCommandLineFlags(&argc, &argv, true);
238 return RUN_ALL_TESTS();