Add EXPECT_{NO_,}_PCRE_MATCH macros
[folly.git] / folly / test / MemoryMappingTest.cpp
1 /*
2  * Copyright 2015 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 <cstdlib>
18 #include <gtest/gtest.h>
19 #include <folly/MemoryMapping.h>
20
21 namespace folly {
22
23 TEST(MemoryMapping, Basic) {
24   File f = File::temporary();
25   {
26     MemoryMapping m(File(f.fd()), 0, sizeof(double), MemoryMapping::writable());
27     double* d = m.asWritableRange<double>().data();
28     *d = 37 * M_PI;
29   }
30   {
31     MemoryMapping m(File(f.fd()), 0, 3);
32     EXPECT_EQ(0, m.asRange<int>().size()); // not big enough
33   }
34   {
35     MemoryMapping m(File(f.fd()), 0, sizeof(double));
36     const double* d = m.asRange<double>().data();
37     EXPECT_EQ(*d, 37 * M_PI);
38   }
39 }
40
41 TEST(MemoryMapping, Move) {
42   File f = File::temporary();
43   {
44     MemoryMapping m(
45         File(f.fd()), 0, sizeof(double) * 2, MemoryMapping::writable());
46     double* d = m.asWritableRange<double>().data();
47     d[0] = 37 * M_PI;
48     MemoryMapping m2(std::move(m));
49     double* d2 = m2.asWritableRange<double>().data();
50     d2[1] = 39 * M_PI;
51   }
52   {
53     MemoryMapping m(File(f.fd()), 0, sizeof(double));
54     const double* d = m.asRange<double>().data();
55     EXPECT_EQ(d[0], 37 * M_PI);
56     MemoryMapping m2(std::move(m));
57     const double* d2 = m2.asRange<double>().data();
58     EXPECT_EQ(d2[1], 39 * M_PI);
59   }
60 }
61
62 TEST(MemoryMapping, DoublyMapped) {
63   File f = File::temporary();
64   // two mappings of the same memory, different addresses.
65   MemoryMapping mw(File(f.fd()), 0, sizeof(double), MemoryMapping::writable());
66   MemoryMapping mr(File(f.fd()), 0, sizeof(double));
67
68   double* dw = mw.asWritableRange<double>().data();
69   const double* dr = mr.asRange<double>().data();
70
71   // Show that it's truly the same value, even though the pointers differ
72   EXPECT_NE(dw, dr);
73   *dw = 42 * M_PI;
74   EXPECT_EQ(*dr, 42 * M_PI);
75   *dw = 43 * M_PI;
76   EXPECT_EQ(*dr, 43 * M_PI);
77 }
78
79 namespace {
80
81 void writeStringToFileOrDie(const std::string& str, int fd) {
82   const char* b = str.c_str();
83   size_t count = str.size();
84   ssize_t total_bytes = 0;
85   ssize_t r;
86   do {
87     r = write(fd, b, count);
88     if (r == -1) {
89       if (errno == EINTR) {
90         continue;
91       }
92       PCHECK(r) << "write";
93     }
94
95     total_bytes += r;
96     b += r;
97     count -= r;
98   } while (r != 0 && count);
99 }
100
101 }  // anonymous namespace
102
103 TEST(MemoryMapping, Simple) {
104   File f = File::temporary();
105   writeStringToFileOrDie("hello", f.fd());
106
107   {
108     MemoryMapping m(File(f.fd()));
109     EXPECT_EQ("hello", m.data());
110   }
111   {
112     MemoryMapping m(File(f.fd()), 1, 2);
113     EXPECT_EQ("el", m.data());
114   }
115 }
116
117 TEST(MemoryMapping, LargeFile) {
118   std::string fileData;
119   size_t fileSize = sysconf(_SC_PAGESIZE) * 3 + 10;
120   fileData.reserve(fileSize);
121   for (size_t i = 0; i < fileSize; i++) {
122     fileData.push_back(0xff & random());
123   }
124
125   File f = File::temporary();
126   writeStringToFileOrDie(fileData, f.fd());
127
128   {
129     MemoryMapping m(File(f.fd()));
130     EXPECT_EQ(fileData, m.data());
131   }
132   {
133     size_t size = sysconf(_SC_PAGESIZE) * 2;
134     StringPiece s(fileData.data() + 9, size - 9);
135     MemoryMapping m(File(f.fd()), 9, size - 9);
136     EXPECT_EQ(s.toString(), m.data());
137   }
138 }
139
140 TEST(MemoryMapping, ZeroLength) {
141   File f = File::temporary();
142   MemoryMapping m(File(f.fd()));
143   EXPECT_TRUE(m.mlock(MemoryMapping::LockMode::MUST_LOCK));
144   EXPECT_TRUE(m.mlocked());
145   EXPECT_EQ(0, m.data().size());
146 }
147
148 } // namespace folly