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>
23 #include <system_error>
25 #include <boost/algorithm/string.hpp>
26 #include <folly/Memory.h>
27 #include <glog/logging.h>
28 #include <gtest/gtest.h>
30 using namespace folly;
31 using namespace folly::test;
33 TEST(TemporaryFile, Simple) {
38 EXPECT_FALSE(f.path().empty());
39 EXPECT_TRUE(f.path().is_absolute());
42 ssize_t r = write(fd, &c, 1);
46 // The file must have been closed. This assumes that no other thread
47 // has opened another file in the meanwhile, which is a sane assumption
48 // to make in this test.
49 ssize_t r = write(fd, &c, 1);
50 int savedErrno = errno;
52 EXPECT_EQ(EBADF, savedErrno);
55 TEST(TemporaryFile, Prefix) {
56 TemporaryFile f("Foo");
57 EXPECT_TRUE(f.path().is_absolute());
58 EXPECT_TRUE(boost::algorithm::starts_with(f.path().filename().native(),
62 TEST(TemporaryFile, PathPrefix) {
63 TemporaryFile f("Foo", ".");
64 EXPECT_EQ(fs::path("."), f.path().parent_path());
65 EXPECT_TRUE(boost::algorithm::starts_with(f.path().filename().native(),
69 TEST(TemporaryFile, NoSuchPath) {
70 EXPECT_THROW({TemporaryFile f("", "/no/such/path");},
74 void testTemporaryDirectory(TemporaryDirectory::Scope scope) {
77 TemporaryDirectory d("", "", scope);
79 EXPECT_FALSE(path.empty());
80 EXPECT_TRUE(path.is_absolute());
81 EXPECT_TRUE(fs::exists(path));
82 EXPECT_TRUE(fs::is_directory(path));
84 fs::path fp = path / "bar";
85 int fd = open(fp.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666);
89 TemporaryFile f("Foo", d.path());
90 EXPECT_EQ(d.path(), f.path().parent_path());
92 bool exists = (scope == TemporaryDirectory::Scope::PERMANENT);
93 EXPECT_EQ(exists, fs::exists(path));
96 TEST(TemporaryDirectory, Permanent) {
97 testTemporaryDirectory(TemporaryDirectory::Scope::PERMANENT);
100 TEST(TemporaryDirectory, DeleteOnDestruction) {
101 testTemporaryDirectory(TemporaryDirectory::Scope::DELETE_ON_DESTRUCTION);
104 void expectTempdirExists(const TemporaryDirectory& d) {
105 EXPECT_FALSE(d.path().empty());
106 EXPECT_TRUE(fs::exists(d.path()));
107 EXPECT_TRUE(fs::is_directory(d.path()));
110 TEST(TemporaryDirectory, SafelyMove) {
111 std::unique_ptr<TemporaryDirectory> dir;
112 TemporaryDirectory dir2;
114 auto scope = TemporaryDirectory::Scope::DELETE_ON_DESTRUCTION;
115 TemporaryDirectory d("", "", scope);
116 TemporaryDirectory d2("", "", scope);
117 expectTempdirExists(d);
118 expectTempdirExists(d2);
120 dir = std::make_unique<TemporaryDirectory>(std::move(d));
121 dir2 = std::move(d2);
124 expectTempdirExists(*dir);
125 expectTempdirExists(dir2);
128 TEST(ChangeToTempDir, ChangeDir) {
129 auto pwd1 = fs::current_path();
132 EXPECT_NE(pwd1, fs::current_path());
134 EXPECT_EQ(pwd1, fs::current_path());
137 TEST(PCREPatternMatch, Simple) {
138 EXPECT_PCRE_MATCH(".*a.c.*", "gabca");
139 EXPECT_NO_PCRE_MATCH("a.c", "gabca");
140 EXPECT_NO_PCRE_MATCH(".*ac.*", "gabca");
143 TEST(CaptureFD, GlogPatterns) {
145 LOG(INFO) << "All is well";
146 EXPECT_NO_PCRE_MATCH(glogErrOrWarnPattern(), stderr.readIncremental());
148 LOG(ERROR) << "Uh-oh";
149 auto s = stderr.readIncremental();
150 EXPECT_PCRE_MATCH(glogErrorPattern(), s);
151 EXPECT_NO_PCRE_MATCH(glogWarningPattern(), s);
152 EXPECT_PCRE_MATCH(glogErrOrWarnPattern(), s);
155 LOG(WARNING) << "Oops";
156 auto s = stderr.readIncremental();
157 EXPECT_NO_PCRE_MATCH(glogErrorPattern(), s);
158 EXPECT_PCRE_MATCH(glogWarningPattern(), s);
159 EXPECT_PCRE_MATCH(glogErrOrWarnPattern(), s);
163 TEST(CaptureFD, ChunkCob) {
164 std::vector<std::string> chunks;
166 CaptureFD stderr(2, [&](StringPiece p) {
167 chunks.emplace_back(p.str());
168 switch (chunks.size()) {
170 EXPECT_PCRE_MATCH(".*foo.*bar.*", p);
173 EXPECT_PCRE_MATCH("[^\n]*baz.*", p);
176 FAIL() << "Got too many chunks: " << chunks.size();
181 EXPECT_PCRE_MATCH(".*foo.*bar.*", stderr.read());
182 auto chunk = stderr.readIncremental();
183 EXPECT_EQ(chunks.at(0), chunk);
185 EXPECT_PCRE_MATCH(".*foo.*bar.*baz.*", stderr.read());
187 EXPECT_EQ(2, chunks.size());
191 class EnvVarSaverTest : public testing::Test {};
193 TEST_F(EnvVarSaverTest, ExampleNew) {
194 auto key = "hahahahaha";
195 EXPECT_EQ(nullptr, getenv(key));
197 auto saver = make_unique<EnvVarSaver>();
198 PCHECK(0 == setenv(key, "blah", true));
199 EXPECT_EQ("blah", std::string{getenv(key)});
201 EXPECT_EQ(nullptr, getenv(key));
204 TEST_F(EnvVarSaverTest, ExampleExisting) {
206 EXPECT_NE(nullptr, getenv(key));
207 auto value = std::string{getenv(key)};
209 auto saver = make_unique<EnvVarSaver>();
210 PCHECK(0 == setenv(key, "blah", true));
211 EXPECT_EQ("blah", std::string{getenv(key)});
213 EXPECT_TRUE(value == getenv(key));
216 TEST_F(EnvVarSaverTest, ExampleDeleting) {
218 EXPECT_NE(nullptr, getenv(key));
219 auto value = std::string{getenv(key)};
221 auto saver = make_unique<EnvVarSaver>();
222 PCHECK(0 == unsetenv(key));
223 EXPECT_EQ(nullptr, getenv(key));
225 EXPECT_TRUE(value == getenv(key));
228 int main(int argc, char *argv[]) {
229 testing::InitGoogleTest(&argc, argv);
230 gflags::ParseCommandLineFlags(&argc, &argv, true);
231 return RUN_ALL_TESTS();