OSDN Git Service

[unittests] Change std::sort to llvm::sort in response to r327219
[android-x86/external-llvm.git] / unittests / Support / MemoryBufferTest.cpp
1 //===- llvm/unittest/Support/MemoryBufferTest.cpp - MemoryBuffer tests ----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements unit tests for the MemoryBuffer support class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Support/MemoryBuffer.h"
15 #include "llvm/Support/FileSystem.h"
16 #include "llvm/Support/FileUtilities.h"
17 #include "llvm/Support/raw_ostream.h"
18 #include "llvm/Testing/Support/Error.h"
19 #include "gtest/gtest.h"
20
21 using namespace llvm;
22
23 namespace {
24
25 class MemoryBufferTest : public testing::Test {
26 protected:
27   MemoryBufferTest()
28   : data("this is some data")
29   { }
30
31   void SetUp() override {}
32
33   /// Common testing for different modes of getOpenFileSlice.
34   /// Creates a temporary file with known contents, and uses
35   /// MemoryBuffer::getOpenFileSlice to map it.
36   /// If \p Reopen is true, the file is closed after creating and reopened
37   /// anew before using MemoryBuffer.
38   void testGetOpenFileSlice(bool Reopen);
39
40   typedef std::unique_ptr<MemoryBuffer> OwningBuffer;
41
42   std::string data;
43 };
44
45 TEST_F(MemoryBufferTest, get) {
46   // Default name and null-terminator flag
47   OwningBuffer MB1(MemoryBuffer::getMemBuffer(data));
48   EXPECT_TRUE(nullptr != MB1.get());
49
50   // RequiresNullTerminator = false
51   OwningBuffer MB2(MemoryBuffer::getMemBuffer(data, "one", false));
52   EXPECT_TRUE(nullptr != MB2.get());
53
54   // RequiresNullTerminator = true
55   OwningBuffer MB3(MemoryBuffer::getMemBuffer(data, "two", true));
56   EXPECT_TRUE(nullptr != MB3.get());
57
58   // verify all 3 buffers point to the same address
59   EXPECT_EQ(MB1->getBufferStart(), MB2->getBufferStart());
60   EXPECT_EQ(MB2->getBufferStart(), MB3->getBufferStart());
61
62   // verify the original data is unmodified after deleting the buffers
63   MB1.reset();
64   MB2.reset();
65   MB3.reset();
66   EXPECT_EQ("this is some data", data);
67 }
68
69 TEST_F(MemoryBufferTest, NullTerminator4K) {
70   // Test that a file with size that is a multiple of the page size can be null
71   // terminated correctly by MemoryBuffer.
72   int TestFD;
73   SmallString<64> TestPath;
74   sys::fs::createTemporaryFile("MemoryBufferTest_NullTerminator4K", "temp",
75                                TestFD, TestPath);
76   FileRemover Cleanup(TestPath);
77   raw_fd_ostream OF(TestFD, true, /*unbuffered=*/true);
78   for (unsigned i = 0; i < 4096 / 16; ++i) {
79     OF << "0123456789abcdef";
80   }
81   OF.close();
82
83   ErrorOr<OwningBuffer> MB = MemoryBuffer::getFile(TestPath.c_str());
84   std::error_code EC = MB.getError();
85   ASSERT_FALSE(EC);
86
87   const char *BufData = MB.get()->getBufferStart();
88   EXPECT_EQ('f', BufData[4095]);
89   EXPECT_EQ('\0', BufData[4096]);
90 }
91
92 TEST_F(MemoryBufferTest, copy) {
93   // copy with no name
94   OwningBuffer MBC1(MemoryBuffer::getMemBufferCopy(data));
95   EXPECT_TRUE(nullptr != MBC1.get());
96
97   // copy with a name
98   OwningBuffer MBC2(MemoryBuffer::getMemBufferCopy(data, "copy"));
99   EXPECT_TRUE(nullptr != MBC2.get());
100
101   // verify the two copies do not point to the same place
102   EXPECT_NE(MBC1->getBufferStart(), MBC2->getBufferStart());
103 }
104
105 TEST_F(MemoryBufferTest, make_new) {
106   // 0-sized buffer
107   OwningBuffer Zero(WritableMemoryBuffer::getNewUninitMemBuffer(0));
108   EXPECT_TRUE(nullptr != Zero.get());
109
110   // uninitialized buffer with no name
111   OwningBuffer One(WritableMemoryBuffer::getNewUninitMemBuffer(321));
112   EXPECT_TRUE(nullptr != One.get());
113
114   // uninitialized buffer with name
115   OwningBuffer Two(WritableMemoryBuffer::getNewUninitMemBuffer(123, "bla"));
116   EXPECT_TRUE(nullptr != Two.get());
117
118   // 0-initialized buffer with no name
119   OwningBuffer Three(WritableMemoryBuffer::getNewMemBuffer(321, data));
120   EXPECT_TRUE(nullptr != Three.get());
121   for (size_t i = 0; i < 321; ++i)
122     EXPECT_EQ(0, Three->getBufferStart()[0]);
123
124   // 0-initialized buffer with name
125   OwningBuffer Four(WritableMemoryBuffer::getNewMemBuffer(123, "zeros"));
126   EXPECT_TRUE(nullptr != Four.get());
127   for (size_t i = 0; i < 123; ++i)
128     EXPECT_EQ(0, Four->getBufferStart()[0]);
129 }
130
131 void MemoryBufferTest::testGetOpenFileSlice(bool Reopen) {
132   // Test that MemoryBuffer::getOpenFile works properly when no null
133   // terminator is requested and the size is large enough to trigger
134   // the usage of memory mapping.
135   int TestFD;
136   SmallString<64> TestPath;
137   // Create a temporary file and write data into it.
138   sys::fs::createTemporaryFile("prefix", "temp", TestFD, TestPath);
139   FileRemover Cleanup(TestPath);
140   // OF is responsible for closing the file; If the file is not
141   // reopened, it will be unbuffered so that the results are
142   // immediately visible through the fd.
143   raw_fd_ostream OF(TestFD, true, !Reopen);
144   for (int i = 0; i < 60000; ++i) {
145     OF << "0123456789";
146   }
147
148   if (Reopen) {
149     OF.close();
150     EXPECT_FALSE(sys::fs::openFileForRead(TestPath.c_str(), TestFD));
151   }
152
153   ErrorOr<OwningBuffer> Buf =
154       MemoryBuffer::getOpenFileSlice(TestFD, TestPath.c_str(),
155                                      40000, // Size
156                                      80000  // Offset
157                                      );
158
159   std::error_code EC = Buf.getError();
160   EXPECT_FALSE(EC);
161
162   StringRef BufData = Buf.get()->getBuffer();
163   EXPECT_EQ(BufData.size(), 40000U);
164   EXPECT_EQ(BufData[0], '0');
165   EXPECT_EQ(BufData[9], '9');
166 }
167
168 TEST_F(MemoryBufferTest, getOpenFileNoReopen) {
169   testGetOpenFileSlice(false);
170 }
171
172 TEST_F(MemoryBufferTest, getOpenFileReopened) {
173   testGetOpenFileSlice(true);
174 }
175
176 TEST_F(MemoryBufferTest, reference) {
177   OwningBuffer MB(MemoryBuffer::getMemBuffer(data));
178   MemoryBufferRef MBR(*MB);
179
180   EXPECT_EQ(MB->getBufferStart(), MBR.getBufferStart());
181   EXPECT_EQ(MB->getBufferIdentifier(), MBR.getBufferIdentifier());
182 }
183
184 TEST_F(MemoryBufferTest, slice) {
185   // Create a file that is six pages long with different data on each page.
186   int FD;
187   SmallString<64> TestPath;
188   sys::fs::createTemporaryFile("MemoryBufferTest_Slice", "temp", FD, TestPath);
189   FileRemover Cleanup(TestPath);
190   raw_fd_ostream OF(FD, true, /*unbuffered=*/true);
191   for (unsigned i = 0; i < 0x2000 / 8; ++i) {
192     OF << "12345678";
193   }
194   for (unsigned i = 0; i < 0x2000 / 8; ++i) {
195     OF << "abcdefgh";
196   }
197   for (unsigned i = 0; i < 0x2000 / 8; ++i) {
198     OF << "ABCDEFGH";
199   }
200   OF.close();
201
202   // Try offset of one page.
203   ErrorOr<OwningBuffer> MB = MemoryBuffer::getFileSlice(TestPath.str(),
204                                                         0x4000, 0x1000);
205   std::error_code EC = MB.getError();
206   ASSERT_FALSE(EC);
207   EXPECT_EQ(0x4000UL, MB.get()->getBufferSize());
208  
209   StringRef BufData = MB.get()->getBuffer();
210   EXPECT_TRUE(BufData.substr(0x0000,8).equals("12345678"));
211   EXPECT_TRUE(BufData.substr(0x0FF8,8).equals("12345678"));
212   EXPECT_TRUE(BufData.substr(0x1000,8).equals("abcdefgh"));
213   EXPECT_TRUE(BufData.substr(0x2FF8,8).equals("abcdefgh"));
214   EXPECT_TRUE(BufData.substr(0x3000,8).equals("ABCDEFGH"));
215   EXPECT_TRUE(BufData.substr(0x3FF8,8).equals("ABCDEFGH"));
216    
217   // Try non-page aligned.
218   ErrorOr<OwningBuffer> MB2 = MemoryBuffer::getFileSlice(TestPath.str(),
219                                                          0x3000, 0x0800);
220   EC = MB2.getError();
221   ASSERT_FALSE(EC);
222   EXPECT_EQ(0x3000UL, MB2.get()->getBufferSize());
223   
224   StringRef BufData2 = MB2.get()->getBuffer();
225   EXPECT_TRUE(BufData2.substr(0x0000,8).equals("12345678"));
226   EXPECT_TRUE(BufData2.substr(0x17F8,8).equals("12345678"));
227   EXPECT_TRUE(BufData2.substr(0x1800,8).equals("abcdefgh"));
228   EXPECT_TRUE(BufData2.substr(0x2FF8,8).equals("abcdefgh"));
229 }
230
231 TEST_F(MemoryBufferTest, writableSlice) {
232   // Create a file initialized with some data
233   int FD;
234   SmallString<64> TestPath;
235   sys::fs::createTemporaryFile("MemoryBufferTest_WritableSlice", "temp", FD,
236                                TestPath);
237   FileRemover Cleanup(TestPath);
238   raw_fd_ostream OF(FD, true);
239   for (unsigned i = 0; i < 0x1000; ++i)
240     OF << "0123456789abcdef";
241   OF.close();
242
243   {
244     auto MBOrError =
245         WritableMemoryBuffer::getFileSlice(TestPath.str(), 0x6000, 0x2000);
246     ASSERT_FALSE(MBOrError.getError());
247     // Write some data.  It should be mapped private, so that upon completion
248     // the original file contents are not modified.
249     WritableMemoryBuffer &MB = **MBOrError;
250     ASSERT_EQ(0x6000u, MB.getBufferSize());
251     char *Start = MB.getBufferStart();
252     ASSERT_EQ(MB.getBufferEnd(), MB.getBufferStart() + MB.getBufferSize());
253     ::memset(Start, 'x', MB.getBufferSize());
254   }
255
256   auto MBOrError = MemoryBuffer::getFile(TestPath);
257   ASSERT_FALSE(MBOrError.getError());
258   auto &MB = **MBOrError;
259   ASSERT_EQ(0x10000u, MB.getBufferSize());
260   for (size_t i = 0; i < MB.getBufferSize(); i += 0x10)
261     EXPECT_EQ("0123456789abcdef", MB.getBuffer().substr(i, 0x10)) << "i: " << i;
262 }
263
264 TEST_F(MemoryBufferTest, writeThroughFile) {
265   // Create a file initialized with some data
266   int FD;
267   SmallString<64> TestPath;
268   sys::fs::createTemporaryFile("MemoryBufferTest_WriteThrough", "temp", FD,
269                                TestPath);
270   FileRemover Cleanup(TestPath);
271   raw_fd_ostream OF(FD, true);
272   OF << "0123456789abcdef";
273   OF.close();
274   {
275     auto MBOrError = WriteThroughMemoryBuffer::getFile(TestPath);
276     ASSERT_FALSE(MBOrError.getError());
277     // Write some data.  It should be mapped readwrite, so that upon completion
278     // the original file contents are modified.
279     WriteThroughMemoryBuffer &MB = **MBOrError;
280     ASSERT_EQ(16u, MB.getBufferSize());
281     char *Start = MB.getBufferStart();
282     ASSERT_EQ(MB.getBufferEnd(), MB.getBufferStart() + MB.getBufferSize());
283     ::memset(Start, 'x', MB.getBufferSize());
284   }
285
286   auto MBOrError = MemoryBuffer::getFile(TestPath);
287   ASSERT_FALSE(MBOrError.getError());
288   auto &MB = **MBOrError;
289   ASSERT_EQ(16u, MB.getBufferSize());
290   EXPECT_EQ("xxxxxxxxxxxxxxxx", MB.getBuffer());
291 }
292 }