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 <system_error>
21 #include <boost/algorithm/string.hpp>
22 #include <glog/logging.h>
24 #include <folly/Memory.h>
25 #include <folly/portability/Fcntl.h>
26 #include <folly/portability/GTest.h>
27 #include <folly/portability/Stdlib.h>
29 using namespace folly;
30 using namespace folly::test;
32 TEST(TemporaryFile, Simple) {
37 EXPECT_FALSE(f.path().empty());
38 EXPECT_TRUE(f.path().is_absolute());
41 ssize_t r = write(fd, &c, 1);
45 msvcSuppressAbortOnInvalidParams([&] {
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);
56 TEST(TemporaryFile, EarlyClose) {
61 EXPECT_TRUE(fs::exists(p));
63 EXPECT_EQ(-1, f.fd());
64 EXPECT_TRUE(fs::exists(p));
66 EXPECT_FALSE(fs::exists(p));
69 TEST(TemporaryFile, Prefix) {
70 TemporaryFile f("Foo");
71 EXPECT_TRUE(f.path().is_absolute());
72 EXPECT_TRUE(boost::algorithm::starts_with(f.path().filename().native(),
76 TEST(TemporaryFile, PathPrefix) {
77 TemporaryFile f("Foo", ".");
78 EXPECT_EQ(fs::path("."), f.path().parent_path());
79 EXPECT_TRUE(boost::algorithm::starts_with(f.path().filename().native(),
83 TEST(TemporaryFile, NoSuchPath) {
84 EXPECT_THROW({TemporaryFile f("", "/no/such/path");},
88 void testTemporaryDirectory(TemporaryDirectory::Scope scope) {
91 TemporaryDirectory d("", "", scope);
93 EXPECT_FALSE(path.empty());
94 EXPECT_TRUE(path.is_absolute());
95 EXPECT_TRUE(fs::exists(path));
96 EXPECT_TRUE(fs::is_directory(path));
98 fs::path fp = path / "bar";
99 int fd = open(fp.string().c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666);
103 TemporaryFile f("Foo", d.path());
104 EXPECT_EQ(d.path(), f.path().parent_path());
106 bool exists = (scope == TemporaryDirectory::Scope::PERMANENT);
107 EXPECT_EQ(exists, fs::exists(path));
110 TEST(TemporaryDirectory, Permanent) {
111 testTemporaryDirectory(TemporaryDirectory::Scope::PERMANENT);
114 TEST(TemporaryDirectory, DeleteOnDestruction) {
115 testTemporaryDirectory(TemporaryDirectory::Scope::DELETE_ON_DESTRUCTION);
118 void expectTempdirExists(const TemporaryDirectory& d) {
119 EXPECT_FALSE(d.path().empty());
120 EXPECT_TRUE(fs::exists(d.path()));
121 EXPECT_TRUE(fs::is_directory(d.path()));
124 TEST(TemporaryDirectory, SafelyMove) {
125 std::unique_ptr<TemporaryDirectory> dir;
126 TemporaryDirectory dir2;
128 auto scope = TemporaryDirectory::Scope::DELETE_ON_DESTRUCTION;
129 TemporaryDirectory d("", "", scope);
130 TemporaryDirectory d2("", "", scope);
131 expectTempdirExists(d);
132 expectTempdirExists(d2);
134 dir = std::make_unique<TemporaryDirectory>(std::move(d));
135 dir2 = std::move(d2);
138 expectTempdirExists(*dir);
139 expectTempdirExists(dir2);
142 TEST(ChangeToTempDir, ChangeDir) {
143 auto pwd1 = fs::current_path();
146 EXPECT_NE(pwd1, fs::current_path());
148 EXPECT_EQ(pwd1, fs::current_path());
151 TEST(PCREPatternMatch, Simple) {
152 EXPECT_PCRE_MATCH(".*a.c.*", "gabca");
153 EXPECT_NO_PCRE_MATCH("a.c", "gabca");
154 EXPECT_NO_PCRE_MATCH(".*ac.*", "gabca");
157 TEST(CaptureFD, GlogPatterns) {
158 CaptureFD err(fileno(stderr));
159 LOG(INFO) << "All is well";
160 EXPECT_NO_PCRE_MATCH(glogErrOrWarnPattern(), err.readIncremental());
162 LOG(ERROR) << "Uh-oh";
163 auto s = err.readIncremental();
164 EXPECT_PCRE_MATCH(glogErrorPattern(), s);
165 EXPECT_NO_PCRE_MATCH(glogWarningPattern(), s);
166 EXPECT_PCRE_MATCH(glogErrOrWarnPattern(), s);
169 LOG(WARNING) << "Oops";
170 auto s = err.readIncremental();
171 EXPECT_NO_PCRE_MATCH(glogErrorPattern(), s);
172 EXPECT_PCRE_MATCH(glogWarningPattern(), s);
173 EXPECT_PCRE_MATCH(glogErrOrWarnPattern(), s);
177 TEST(CaptureFD, ChunkCob) {
178 std::vector<std::string> chunks;
180 CaptureFD err(fileno(stderr), [&](StringPiece p) {
181 chunks.emplace_back(p.str());
182 switch (chunks.size()) {
184 EXPECT_PCRE_MATCH(".*foo.*bar.*", p);
187 EXPECT_PCRE_MATCH("[^\n]*baz.*", p);
190 FAIL() << "Got too many chunks: " << chunks.size();
195 EXPECT_PCRE_MATCH(".*foo.*bar.*", err.read());
196 auto chunk = err.readIncremental();
197 EXPECT_EQ(chunks.at(0), chunk);
199 EXPECT_PCRE_MATCH(".*foo.*bar.*baz.*", err.read());
201 EXPECT_EQ(2, chunks.size());