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/FileSystem.h" 15 #include "llvm/Support/MemoryBuffer.h" 16 #include "llvm/Support/raw_ostream.h" 17 #include "llvm/ADT/OwningPtr.h" 18 #include "gtest/gtest.h" 19 20 using namespace llvm; 21 22 namespace { 23 24 class MemoryBufferTest : public testing::Test { 25 protected: 26 MemoryBufferTest() 27 : data("this is some data") 28 { } 29 30 virtual void SetUp() { } 31 32 /// Common testing for different modes of getOpenFileSlice. 33 /// Creates a temporary file with known contents, and uses 34 /// MemoryBuffer::getOpenFileSlice to map it. 35 /// If \p Reopen is true, the file is closed after creating and reopened 36 /// anew before using MemoryBuffer. 37 void testGetOpenFileSlice(bool Reopen); 38 39 typedef OwningPtr<MemoryBuffer> OwningBuffer; 40 41 std::string data; 42 }; 43 44 TEST_F(MemoryBufferTest, get) { 45 // Default name and null-terminator flag 46 OwningBuffer MB1(MemoryBuffer::getMemBuffer(data)); 47 EXPECT_TRUE(0 != MB1.get()); 48 49 // RequiresNullTerminator = false 50 OwningBuffer MB2(MemoryBuffer::getMemBuffer(data, "one", false)); 51 EXPECT_TRUE(0 != MB2.get()); 52 53 // RequiresNullTerminator = true 54 OwningBuffer MB3(MemoryBuffer::getMemBuffer(data, "two", true)); 55 EXPECT_TRUE(0 != MB3.get()); 56 57 // verify all 3 buffers point to the same address 58 EXPECT_EQ(MB1->getBufferStart(), MB2->getBufferStart()); 59 EXPECT_EQ(MB2->getBufferStart(), MB3->getBufferStart()); 60 61 // verify the original data is unmodified after deleting the buffers 62 MB1.reset(); 63 MB2.reset(); 64 MB3.reset(); 65 EXPECT_EQ("this is some data", data); 66 } 67 68 TEST_F(MemoryBufferTest, copy) { 69 // copy with no name 70 OwningBuffer MBC1(MemoryBuffer::getMemBufferCopy(data)); 71 EXPECT_TRUE(0 != MBC1.get()); 72 73 // copy with a name 74 OwningBuffer MBC2(MemoryBuffer::getMemBufferCopy(data, "copy")); 75 EXPECT_TRUE(0 != MBC2.get()); 76 77 // verify the two copies do not point to the same place 78 EXPECT_NE(MBC1->getBufferStart(), MBC2->getBufferStart()); 79 } 80 81 TEST_F(MemoryBufferTest, make_new) { 82 // 0-sized buffer 83 OwningBuffer Zero(MemoryBuffer::getNewUninitMemBuffer(0)); 84 EXPECT_TRUE(0 != Zero.get()); 85 86 // uninitialized buffer with no name 87 OwningBuffer One(MemoryBuffer::getNewUninitMemBuffer(321)); 88 EXPECT_TRUE(0 != One.get()); 89 90 // uninitialized buffer with name 91 OwningBuffer Two(MemoryBuffer::getNewUninitMemBuffer(123, "bla")); 92 EXPECT_TRUE(0 != Two.get()); 93 94 // 0-initialized buffer with no name 95 OwningBuffer Three(MemoryBuffer::getNewMemBuffer(321, data)); 96 EXPECT_TRUE(0 != Three.get()); 97 for (size_t i = 0; i < 321; ++i) 98 EXPECT_EQ(0, Three->getBufferStart()[0]); 99 100 // 0-initialized buffer with name 101 OwningBuffer Four(MemoryBuffer::getNewMemBuffer(123, "zeros")); 102 EXPECT_TRUE(0 != Four.get()); 103 for (size_t i = 0; i < 123; ++i) 104 EXPECT_EQ(0, Four->getBufferStart()[0]); 105 } 106 107 void MemoryBufferTest::testGetOpenFileSlice(bool Reopen) { 108 // Test that MemoryBuffer::getOpenFile works properly when no null 109 // terminator is requested and the size is large enough to trigger 110 // the usage of memory mapping. 111 int TestFD; 112 SmallString<64> TestPath; 113 // Create a temporary file and write data into it. 114 sys::fs::createTemporaryFile("prefix", "temp", TestFD, TestPath); 115 // OF is responsible for closing the file; If the file is not 116 // reopened, it will be unbuffered so that the results are 117 // immediately visible through the fd. 118 raw_fd_ostream OF(TestFD, true, !Reopen); 119 for (int i = 0; i < 60000; ++i) { 120 OF << "0123456789"; 121 } 122 123 if (Reopen) { 124 OF.close(); 125 EXPECT_FALSE(sys::fs::openFileForRead(TestPath.c_str(), TestFD)); 126 } 127 128 OwningBuffer Buf; 129 error_code EC = MemoryBuffer::getOpenFileSlice(TestFD, TestPath.c_str(), Buf, 130 40000, // Size 131 8000 // Offset 132 ); 133 EXPECT_FALSE(EC); 134 135 StringRef BufData = Buf->getBuffer(); 136 EXPECT_EQ(BufData.size(), 40000U); 137 EXPECT_EQ(BufData[0], '0'); 138 EXPECT_EQ(BufData[9], '9'); 139 } 140 141 TEST_F(MemoryBufferTest, getOpenFileNoReopen) { 142 testGetOpenFileSlice(false); 143 } 144 145 TEST_F(MemoryBufferTest, getOpenFileReopened) { 146 testGetOpenFileSlice(true); 147 } 148 149 } 150