Home | History | Annotate | Download | only in Support
      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