proxygen
TestUtilTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2012-present Facebook, Inc.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
18 
19 #include <system_error>
20 
21 #include <boost/algorithm/string.hpp>
22 #include <glog/logging.h>
23 
24 #include <folly/Memory.h>
28 
29 using namespace folly;
30 using namespace folly::test;
31 
32 TEST(TemporaryFile, Simple) {
33  int fd = -1;
34  char c = 'x';
35  {
37  EXPECT_FALSE(f.path().empty());
38  EXPECT_TRUE(f.path().is_absolute());
39  fd = f.fd();
40  EXPECT_LE(0, fd);
41  ssize_t r = write(fd, &c, 1);
42  EXPECT_EQ(1, r);
43  }
44 
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;
51  EXPECT_EQ(-1, r);
52  EXPECT_EQ(EBADF, savedErrno);
53  });
54 }
55 
56 TEST(TemporaryFile, EarlyClose) {
57  fs::path p;
58  {
60  p = f.path();
61  EXPECT_TRUE(fs::exists(p));
62  f.close();
63  EXPECT_EQ(-1, f.fd());
64  EXPECT_TRUE(fs::exists(p));
65  }
66  EXPECT_FALSE(fs::exists(p));
67 }
68 
69 TEST(TemporaryFile, Prefix) {
70  TemporaryFile f("Foo");
71  EXPECT_TRUE(f.path().is_absolute());
73  boost::algorithm::starts_with(f.path().filename().native(), "Foo"));
74 }
75 
76 TEST(TemporaryFile, PathPrefix) {
77  TemporaryFile f("Foo", ".");
78  EXPECT_EQ(fs::path("."), f.path().parent_path());
80  boost::algorithm::starts_with(f.path().filename().native(), "Foo"));
81 }
82 
83 TEST(TemporaryFile, NoSuchPath) {
84  EXPECT_THROW({ TemporaryFile f("", "/no/such/path"); }, std::system_error);
85 }
86 
87 TEST(TemporaryFile, moveAssignment) {
89  int fd;
90 
91  EXPECT_TRUE(f.path().is_absolute());
92  {
93  TemporaryFile g("Foo", ".");
94  EXPECT_NE(g.fd(), -1);
95  fd = g.fd();
96  f = std::move(g);
97  }
98  EXPECT_EQ(fs::path("."), f.path().parent_path());
99  EXPECT_EQ(f.fd(), fd);
100 
101  TemporaryFile h = TemporaryFile("FooBar", ".");
102  EXPECT_NE(h.fd(), -1);
103 }
104 
105 TEST(TemporaryFile, moveCtor) {
106  struct FooBar {
107  TemporaryFile f_;
108  explicit FooBar(TemporaryFile&& f) : f_(std::move(f)) {}
109  };
110  TemporaryFile g("Foo");
111  FooBar fb(std::move(g));
112  EXPECT_EQ(g.fd(), -1);
113  EXPECT_NE(fb.f_.fd(), -1);
114 }
115 
117  fs::path path;
118  {
119  TemporaryDirectory d("", "", scope);
120  path = d.path();
121  EXPECT_FALSE(path.empty());
122  EXPECT_TRUE(path.is_absolute());
123  EXPECT_TRUE(fs::exists(path));
124  EXPECT_TRUE(fs::is_directory(path));
125 
126  fs::path fp = path / "bar";
127  int fd = open(fp.string().c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666);
128  EXPECT_NE(fd, -1);
129  close(fd);
130 
131  TemporaryFile f("Foo", d.path());
132  EXPECT_EQ(d.path(), f.path().parent_path());
133  }
134  bool exists = (scope == TemporaryDirectory::Scope::PERMANENT);
135  EXPECT_EQ(exists, fs::exists(path));
136 }
137 
140 }
141 
142 TEST(TemporaryDirectory, DeleteOnDestruction) {
144 }
145 
147  EXPECT_FALSE(d.path().empty());
148  EXPECT_TRUE(fs::exists(d.path()));
149  EXPECT_TRUE(fs::is_directory(d.path()));
150 }
151 
152 TEST(TemporaryDirectory, SafelyMove) {
153  std::unique_ptr<TemporaryDirectory> dir;
154  TemporaryDirectory dir2;
155  {
157  TemporaryDirectory d("", "", scope);
158  TemporaryDirectory d2("", "", scope);
161 
162  dir = std::make_unique<TemporaryDirectory>(std::move(d));
163  dir2 = std::move(d2);
164  }
165 
166  expectTempdirExists(*dir);
167  expectTempdirExists(dir2);
168 }
169 
170 TEST(ChangeToTempDir, ChangeDir) {
171  auto pwd1 = fs::current_path();
172  {
173  ChangeToTempDir d;
174  EXPECT_NE(pwd1, fs::current_path());
175  }
176  EXPECT_EQ(pwd1, fs::current_path());
177 }
178 
179 TEST(PCREPatternMatch, Simple) {
180  EXPECT_PCRE_MATCH(".*a.c.*", "gabca");
181  EXPECT_NO_PCRE_MATCH("a.c", "gabca");
182  EXPECT_NO_PCRE_MATCH(".*ac.*", "gabca");
183 }
184 
185 TEST(CaptureFD, GlogPatterns) {
186  CaptureFD err(fileno(stderr));
187  LOG(INFO) << "All is well";
189  {
190  LOG(ERROR) << "Uh-oh";
191  auto s = err.readIncremental();
195  }
196  {
197  LOG(WARNING) << "Oops";
198  auto s = err.readIncremental();
202  }
203 }
204 
205 TEST(CaptureFD, ChunkCob) {
206  std::vector<std::string> chunks;
207  {
208  CaptureFD err(fileno(stderr), [&](StringPiece p) {
209  chunks.emplace_back(p.str());
210  switch (chunks.size()) {
211  case 1:
212  EXPECT_PCRE_MATCH(".*foo.*bar.*", p);
213  break;
214  case 2:
215  EXPECT_PCRE_MATCH("[^\n]*baz.*", p);
216  break;
217  default:
218  FAIL() << "Got too many chunks: " << chunks.size();
219  }
220  });
221  LOG(INFO) << "foo";
222  LOG(INFO) << "bar";
223  EXPECT_PCRE_MATCH(".*foo.*bar.*", err.read());
224  auto chunk = err.readIncremental();
225  EXPECT_EQ(chunks.at(0), chunk);
226  LOG(INFO) << "baz";
227  EXPECT_PCRE_MATCH(".*foo.*bar.*baz.*", err.read());
228  }
229  EXPECT_EQ(2, chunks.size());
230 }
#define EXPECT_LE(val1, val2)
Definition: gtest.h:1928
auto chunks
*than *hazptr_holder h
Definition: Hazptr.h:116
auto f
#define FAIL()
Definition: gtest.h:1822
void write(const T &in, folly::io::Appender &appender)
Definition: Types-inl.h:112
std::string str() const
Definition: Range.h:591
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
#define EXPECT_NO_PCRE_MATCH(pattern_stringpiece, target_stringpiece)
Definition: TestUtil.h:184
#define EXPECT_PCRE_MATCH(pattern_stringpiece, target_stringpiece)
Definition: TestUtil.h:179
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::string readIncremental()
Definition: TestUtil.cpp:217
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
void expectTempdirExists(const TemporaryDirectory &d)
auto msvcSuppressAbortOnInvalidParams(Func func) -> decltype(func())
Definition: TestUtil.h:166
std::string glogErrOrWarnPattern()
Definition: TestUtil.h:212
void testTemporaryDirectory(TemporaryDirectory::Scope scope)
std::string glogWarningPattern()
Definition: TestUtil.h:208
const fs::path & path() const
Definition: TestUtil.cpp:85
std::string glogErrorPattern()
Definition: TestUtil.h:205
TEST(ProgramOptionsTest, Errors)
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
g_t g(f_t)
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
static set< string > s
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
char c
int close(NetworkSocket s)
Definition: NetOps.cpp:90
const fs::path & path() const
Definition: TestUtil.h:116
bool starts_with(const path &pth, const path &prefix)
Definition: FsUtil.cpp:45