proxygen
FileTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2013-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 
17 #include <folly/File.h>
18 
19 #include <folly/String.h>
22 
23 using namespace folly;
24 
25 namespace {
26 void expectWouldBlock(ssize_t r) {
27  int savedErrno = errno;
28  EXPECT_EQ(-1, r);
29  EXPECT_EQ(EAGAIN, savedErrno) << errnoStr(savedErrno);
30 }
31 void expectOK(ssize_t r) {
32  int savedErrno = errno;
33  EXPECT_LE(0, r) << ": errno=" << errnoStr(savedErrno);
34 }
35 } // namespace
36 
37 TEST(File, Simple) {
38  // Open a file, ensure it's indeed open for reading
39  char buf = 'x';
40  {
41  File f("/etc/hosts");
42  EXPECT_NE(-1, f.fd());
43  EXPECT_EQ(1, ::read(f.fd(), &buf, 1));
44  f.close();
45  EXPECT_EQ(-1, f.fd());
46  }
47 }
48 
49 TEST(File, SimpleStringPiece) {
50  char buf = 'x';
51  File f(StringPiece("/etc/hosts"));
52  EXPECT_NE(-1, f.fd());
53  EXPECT_EQ(1, ::read(f.fd(), &buf, 1));
54  f.close();
55  EXPECT_EQ(-1, f.fd());
56 }
57 
58 TEST(File, OwnsFd) {
59  // Wrap a file descriptor, make sure that ownsFd works
60  // We'll test that the file descriptor is closed by closing the writing
61  // end of a pipe and making sure that a non-blocking read from the reading
62  // end returns 0.
63 
64  char buf = 'x';
65  int p[2];
66  expectOK(::pipe(p));
67  int flags = ::fcntl(p[0], F_GETFL);
68  expectOK(flags);
69  expectOK(::fcntl(p[0], F_SETFL, flags | O_NONBLOCK));
70  expectWouldBlock(::read(p[0], &buf, 1));
71  {
72  File f(p[1]);
73  EXPECT_EQ(p[1], f.fd());
74  }
75  // Ensure that moving the file doesn't close it
76  {
77  File f(p[1]);
78  EXPECT_EQ(p[1], f.fd());
79  File f1(std::move(f));
80  EXPECT_EQ(-1, f.fd());
81  EXPECT_EQ(p[1], f1.fd());
82  }
83  expectWouldBlock(::read(p[0], &buf, 1)); // not closed
84  {
85  File f(p[1], true);
86  EXPECT_EQ(p[1], f.fd());
87  }
88  ssize_t r = ::read(p[0], &buf, 1); // eof
89  expectOK(r);
90  EXPECT_EQ(0, r);
91  ::close(p[0]);
92 }
93 
94 TEST(File, Release) {
95  File in(STDOUT_FILENO, false);
96  CHECK_EQ(STDOUT_FILENO, in.release());
97  CHECK_EQ(-1, in.release());
98 }
99 
100 #define EXPECT_CONTAINS(haystack, needle) \
101  EXPECT_NE(::std::string::npos, ::folly::StringPiece(haystack).find(needle)) \
102  << "Haystack: '" << haystack << "'\nNeedle: '" << needle << "'";
103 
104 TEST(File, UsefulError) {
105  try {
106  File("does_not_exist.txt", 0, 0666);
107  } catch (const std::runtime_error& e) {
108  EXPECT_CONTAINS(e.what(), "does_not_exist.txt");
109  EXPECT_CONTAINS(e.what(), "0666");
110  }
111 }
112 
113 TEST(File, Truthy) {
115 
116  EXPECT_TRUE(bool(temp));
117 
118  if (temp) {
119  ;
120  } else {
121  ADD_FAILURE();
122  }
123 
124  if (File file = File::temporary()) {
125  ;
126  } else {
127  ADD_FAILURE();
128  }
129 
130  EXPECT_FALSE(bool(File()));
131  if (File()) {
132  ADD_FAILURE();
133  }
134  if (File notOpened = File()) {
135  ADD_FAILURE();
136  }
137 }
138 
139 TEST(File, HelperCtor) {
140  File::makeFile(StringPiece("/etc/hosts")).then([](File&& f) {
141  char buf = 'x';
142  EXPECT_NE(-1, f.fd());
143  EXPECT_EQ(1, ::read(f.fd(), &buf, 1));
144  f.close();
145  EXPECT_EQ(-1, f.fd());
146  });
147 }
#define EXPECT_LE(val1, val2)
Definition: gtest.h:1928
auto f
flags
Definition: http_parser.h:127
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
int release() noexcept
Definition: File.cpp:89
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
#define EXPECT_CONTAINS(haystack, needle)
Definition: FileTest.cpp:100
int fd() const
Definition: File.h:85
static Expected< File, exception_wrapper > makeFile(Args &&...args) noexcept
Definition: File.h:67
size_t read(T &out, folly::io::Cursor &cursor)
Definition: Types-inl.h:258
void close()
Definition: File.cpp:117
fbstring errnoStr(int err)
Definition: String.cpp:463
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
static File temporary()
Definition: File.cpp:75
Range< const char * > StringPiece
#define ADD_FAILURE()
Definition: gtest.h:1808
int close(NetworkSocket s)
Definition: NetOps.cpp:90
TEST(SequencedExecutor, CPUThreadPoolExecutor)
void pipe(CPUExecutor cpu, IOExecutor io)