folly/{experimental => .}/File
[folly.git] / folly / test / FileTest.cpp
1 /*
2  * Copyright 2013 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 <glog/logging.h>
20 #include <gtest/gtest.h>
21
22 #include "folly/Benchmark.h"
23 #include "folly/String.h"
24
25 using namespace folly;
26
27 namespace {
28 void expectWouldBlock(ssize_t r) {
29   int savedErrno = errno;
30   EXPECT_EQ(-1, r);
31   EXPECT_EQ(EAGAIN, savedErrno) << errnoStr(errno);
32 }
33 void expectOK(ssize_t r) {
34   int savedErrno = errno;
35   EXPECT_LE(0, r) << ": errno=" << errnoStr(errno);
36 }
37 }  // namespace
38
39 TEST(File, Simple) {
40   // Open a file, ensure it's indeed open for reading
41   char buf = 'x';
42   {
43     File f("/etc/hosts");
44     EXPECT_NE(-1, f.fd());
45     EXPECT_EQ(1, ::read(f.fd(), &buf, 1));
46     f.close();
47     EXPECT_EQ(-1, f.fd());
48   }
49 }
50
51 TEST(File, OwnsFd) {
52   // Wrap a file descriptor, make sure that ownsFd works
53   // We'll test that the file descriptor is closed by closing the writing
54   // end of a pipe and making sure that a non-blocking read from the reading
55   // end returns 0.
56
57   char buf = 'x';
58   int p[2];
59   expectOK(::pipe(p));
60   int flags = ::fcntl(p[0], F_GETFL);
61   expectOK(flags);
62   expectOK(::fcntl(p[0], F_SETFL, flags | O_NONBLOCK));
63   expectWouldBlock(::read(p[0], &buf, 1));
64   {
65     File f(p[1]);
66     EXPECT_EQ(p[1], f.fd());
67   }
68   // Ensure that moving the file doesn't close it
69   {
70     File f(p[1]);
71     EXPECT_EQ(p[1], f.fd());
72     File f1(std::move(f));
73     EXPECT_EQ(-1, f.fd());
74     EXPECT_EQ(p[1], f1.fd());
75   }
76   expectWouldBlock(::read(p[0], &buf, 1));  // not closed
77   {
78     File f(p[1], true);
79     EXPECT_EQ(p[1], f.fd());
80   }
81   ssize_t r = ::read(p[0], &buf, 1);  // eof
82   expectOK(r);
83   EXPECT_EQ(0, r);
84   ::close(p[0]);
85 }
86