memory_mapped_file_unittest.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/files/memory_mapped_file.h"
6
7#include "base/file_util.h"
8#include "base/files/file_path.h"
9#include "testing/gtest/include/gtest/gtest.h"
10#include "testing/platform_test.h"
11
12namespace base {
13
14namespace {
15
16// Create a temporary buffer and fill it with a watermark sequence.
17scoped_ptr<uint8[]> CreateTestBuffer(size_t size, size_t offset) {
18  scoped_ptr<uint8[]> buf(new uint8[size]);
19  for (size_t i = 0; i < size; ++i)
20    buf.get()[i] = static_cast<uint8>((offset + i) % 253);
21  return buf.Pass();
22}
23
24// Check that the watermark sequence is consistent with the |offset| provided.
25bool CheckBufferContents(const uint8* data, size_t size, size_t offset) {
26  scoped_ptr<uint8[]> test_data(CreateTestBuffer(size, offset));
27  return memcmp(test_data.get(), data, size) == 0;
28}
29
30class MemoryMappedFileTest : public PlatformTest {
31 protected:
32  virtual void SetUp() OVERRIDE {
33    PlatformTest::SetUp();
34    CreateTemporaryFile(&temp_file_path_);
35  }
36
37  virtual void TearDown() { EXPECT_TRUE(DeleteFile(temp_file_path_, false)); }
38
39  void CreateTemporaryTestFile(size_t size) {
40    File file(temp_file_path_,
41              File::FLAG_CREATE_ALWAYS | File::FLAG_READ | File::FLAG_WRITE);
42    EXPECT_TRUE(file.IsValid());
43
44    scoped_ptr<uint8[]> test_data(CreateTestBuffer(size, 0));
45    size_t bytes_written =
46        file.Write(0, reinterpret_cast<char*>(test_data.get()), size);
47    EXPECT_EQ(size, bytes_written);
48    file.Close();
49  }
50
51  const FilePath temp_file_path() const { return temp_file_path_; }
52
53 private:
54  FilePath temp_file_path_;
55};
56
57TEST_F(MemoryMappedFileTest, MapWholeFileByPath) {
58  const size_t kFileSize = 68 * 1024;
59  CreateTemporaryTestFile(kFileSize);
60  MemoryMappedFile map;
61  map.Initialize(temp_file_path());
62  ASSERT_EQ(kFileSize, map.length());
63  ASSERT_TRUE(map.data() != NULL);
64  EXPECT_TRUE(map.IsValid());
65  ASSERT_TRUE(CheckBufferContents(map.data(), kFileSize, 0));
66}
67
68TEST_F(MemoryMappedFileTest, MapWholeFileByFD) {
69  const size_t kFileSize = 68 * 1024;
70  CreateTemporaryTestFile(kFileSize);
71  MemoryMappedFile map;
72  map.Initialize(File(temp_file_path(), File::FLAG_OPEN | File::FLAG_READ));
73  ASSERT_EQ(kFileSize, map.length());
74  ASSERT_TRUE(map.data() != NULL);
75  EXPECT_TRUE(map.IsValid());
76  ASSERT_TRUE(CheckBufferContents(map.data(), kFileSize, 0));
77}
78
79TEST_F(MemoryMappedFileTest, MapSmallFile) {
80  const size_t kFileSize = 127;
81  CreateTemporaryTestFile(kFileSize);
82  MemoryMappedFile map;
83  map.Initialize(temp_file_path());
84  ASSERT_EQ(kFileSize, map.length());
85  ASSERT_TRUE(map.data() != NULL);
86  EXPECT_TRUE(map.IsValid());
87  ASSERT_TRUE(CheckBufferContents(map.data(), kFileSize, 0));
88}
89
90TEST_F(MemoryMappedFileTest, MapWholeFileUsingRegion) {
91  const size_t kFileSize = 157 * 1024;
92  CreateTemporaryTestFile(kFileSize);
93  MemoryMappedFile map;
94
95  File file(temp_file_path(), File::FLAG_OPEN | File::FLAG_READ);
96  map.Initialize(file.Pass(), MemoryMappedFile::Region::kWholeFile);
97  ASSERT_EQ(kFileSize, map.length());
98  ASSERT_TRUE(map.data() != NULL);
99  EXPECT_TRUE(map.IsValid());
100  ASSERT_TRUE(CheckBufferContents(map.data(), kFileSize, 0));
101}
102
103TEST_F(MemoryMappedFileTest, MapPartialRegionAtBeginning) {
104  const size_t kFileSize = 157 * 1024;
105  const size_t kPartialSize = 4 * 1024 + 32;
106  CreateTemporaryTestFile(kFileSize);
107  MemoryMappedFile map;
108
109  File file(temp_file_path(), File::FLAG_OPEN | File::FLAG_READ);
110  map.Initialize(file.Pass(), MemoryMappedFile::Region(0, kPartialSize));
111  ASSERT_EQ(kPartialSize, map.length());
112  ASSERT_TRUE(map.data() != NULL);
113  EXPECT_TRUE(map.IsValid());
114  ASSERT_TRUE(CheckBufferContents(map.data(), kPartialSize, 0));
115}
116
117TEST_F(MemoryMappedFileTest, MapPartialRegionAtEnd) {
118  const size_t kFileSize = 157 * 1024;
119  const size_t kPartialSize = 5 * 1024 - 32;
120  const size_t kOffset = kFileSize - kPartialSize;
121  CreateTemporaryTestFile(kFileSize);
122  MemoryMappedFile map;
123
124  File file(temp_file_path(), File::FLAG_OPEN | File::FLAG_READ);
125  map.Initialize(file.Pass(), MemoryMappedFile::Region(kOffset, kPartialSize));
126  ASSERT_EQ(kPartialSize, map.length());
127  ASSERT_TRUE(map.data() != NULL);
128  EXPECT_TRUE(map.IsValid());
129  ASSERT_TRUE(CheckBufferContents(map.data(), kPartialSize, kOffset));
130}
131
132TEST_F(MemoryMappedFileTest, MapSmallPartialRegionInTheMiddle) {
133  const size_t kFileSize = 157 * 1024;
134  const size_t kOffset = 1024 * 5 + 32;
135  const size_t kPartialSize = 8;
136
137  CreateTemporaryTestFile(kFileSize);
138  MemoryMappedFile map;
139
140  File file(temp_file_path(), File::FLAG_OPEN | File::FLAG_READ);
141  map.Initialize(file.Pass(), MemoryMappedFile::Region(kOffset, kPartialSize));
142  ASSERT_EQ(kPartialSize, map.length());
143  ASSERT_TRUE(map.data() != NULL);
144  EXPECT_TRUE(map.IsValid());
145  ASSERT_TRUE(CheckBufferContents(map.data(), kPartialSize, kOffset));
146}
147
148TEST_F(MemoryMappedFileTest, MapLargePartialRegionInTheMiddle) {
149  const size_t kFileSize = 157 * 1024;
150  const size_t kOffset = 1024 * 5 + 32;
151  const size_t kPartialSize = 16 * 1024 - 32;
152
153  CreateTemporaryTestFile(kFileSize);
154  MemoryMappedFile map;
155
156  File file(temp_file_path(), File::FLAG_OPEN | File::FLAG_READ);
157  map.Initialize(file.Pass(), MemoryMappedFile::Region(kOffset, kPartialSize));
158  ASSERT_EQ(kPartialSize, map.length());
159  ASSERT_TRUE(map.data() != NULL);
160  EXPECT_TRUE(map.IsValid());
161  ASSERT_TRUE(CheckBufferContents(map.data(), kPartialSize, kOffset));
162}
163
164}  // namespace
165
166}  // namespace base
167