1761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes/*
2761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * Copyright (C) 2008 The Android Open Source Project
3761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes *
4761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
5761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * you may not use this file except in compliance with the License.
6761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * You may obtain a copy of the License at
7761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes *
8761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes *
10761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * Unless required by applicable law or agreed to in writing, software
11761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
12761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * See the License for the specific language governing permissions and
14761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * limitations under the License.
15761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes */
16761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
17761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/mapped_file.h"
189433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe#include "base/casts.h"
1907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h"
20761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/fd_file.h"
21761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/random_access_file_test.h"
22761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/random_access_file_utils.h"
23761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/string_file.h"
24761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "gtest/gtest.h"
25761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
26761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesnamespace unix_file {
27761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
28761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesclass MappedFileTest : public RandomAccessFileTest {
29761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes protected:
30761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFileTest() : kContent("some content") {
31761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  }
32761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
33761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  void SetUp() {
34f896965072343a2d6ad64d46a61112b10b3645ddAndreas Gampe    RandomAccessFileTest::SetUp();
35761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
36761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    good_path_ = GetTmpPath("some-file.txt");
37761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    int fd = TEMP_FAILURE_RETRY(open(good_path_.c_str(), O_CREAT|O_RDWR, 0666));
389433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    FdFile dst(fd, false);
39761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
40761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    StringFile src;
41761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    src.Assign(kContent);
42761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
43761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    ASSERT_TRUE(CopyFile(src, &dst));
449433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    ASSERT_EQ(dst.FlushClose(), 0);
45761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  }
46761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
47f896965072343a2d6ad64d46a61112b10b3645ddAndreas Gampe  void TearDown() {
48f896965072343a2d6ad64d46a61112b10b3645ddAndreas Gampe    ASSERT_EQ(unlink(good_path_.c_str()), 0);
49f896965072343a2d6ad64d46a61112b10b3645ddAndreas Gampe
50f896965072343a2d6ad64d46a61112b10b3645ddAndreas Gampe    RandomAccessFileTest::TearDown();
51f896965072343a2d6ad64d46a61112b10b3645ddAndreas Gampe  }
52f896965072343a2d6ad64d46a61112b10b3645ddAndreas Gampe
53761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  virtual RandomAccessFile* MakeTestFile() {
54761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    TEMP_FAILURE_RETRY(truncate(good_path_.c_str(), 0));
55761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    MappedFile* f = new MappedFile;
56761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    CHECK(f->Open(good_path_, MappedFile::kReadWriteMode));
57761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    return f;
58761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  }
59761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
609433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  void CleanUp(RandomAccessFile* file) OVERRIDE {
619433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    if (file == nullptr) {
629433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      return;
639433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    }
649433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    MappedFile* f = ::art::down_cast<MappedFile*>(file);
659433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    UNUSED(f->Flush());
669433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    UNUSED(f->Close());
679433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  }
689433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
69761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  const std::string kContent;
70761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  std::string good_path_;
71761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes};
72761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
73761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, OkayToNotUse) {
74761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
75761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(-1, file.Fd());
76761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_FALSE(file.IsOpened());
77761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_FALSE(file.IsMapped());
78761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
79761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
80761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, OpenClose) {
81761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
82761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadOnlyMode));
83761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_GE(file.Fd(), 0);
84761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_TRUE(file.IsOpened());
85ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  EXPECT_EQ(kContent.size(), static_cast<uint64_t>(file.size()));
86761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(0, file.Close());
87761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(-1, file.Fd());
88761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_FALSE(file.IsOpened());
89761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
90761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
91761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, OpenFdClose) {
92761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  FILE* f = tmpfile();
93761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(f != NULL);
949433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  MappedFile file(fileno(f), false);
95761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_GE(file.Fd(), 0);
96761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_TRUE(file.IsOpened());
97761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(0, file.Close());
98761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
99761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
100761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, CanUseAfterMapReadOnly) {
101761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
102761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadOnlyMode));
103761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_FALSE(file.IsMapped());
104761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_TRUE(file.MapReadOnly());
105761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_TRUE(file.IsMapped());
106ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  EXPECT_EQ(kContent.size(), static_cast<uint64_t>(file.size()));
107761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.data());
108761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(0, memcmp(kContent.c_str(), file.data(), file.size()));
109761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(0, file.Flush());
110761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
111761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
112761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, CanUseAfterMapReadWrite) {
113761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
114761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadWriteMode));
115761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_FALSE(file.IsMapped());
116761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_TRUE(file.MapReadWrite(1));
117761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_TRUE(file.IsMapped());
118761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(1, file.size());
119761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.data());
120761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(kContent[0], *file.data());
121761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(0, file.Flush());
1229433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  file.Close();
123761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
124761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
125761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, CanWriteNewData) {
126761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  const std::string new_path(GetTmpPath("new-file.txt"));
127761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_EQ(-1, unlink(new_path.c_str()));
128761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_EQ(ENOENT, errno);
129761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
130761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
131761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(new_path, MappedFile::kReadWriteMode));
132761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_TRUE(file.MapReadWrite(kContent.size()));
133761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_TRUE(file.IsMapped());
134ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  EXPECT_EQ(kContent.size(), static_cast<uint64_t>(file.size()));
135761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.data());
136761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  memcpy(file.data(), kContent.c_str(), kContent.size());
1379433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  EXPECT_EQ(0, file.Flush());
138761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(0, file.Close());
139761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_FALSE(file.IsMapped());
140761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
1419433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  FdFile new_file(TEMP_FAILURE_RETRY(open(new_path.c_str(), O_RDONLY)), false);
142761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  StringFile buffer;
143761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(CopyFile(new_file, &buffer));
144761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(kContent, buffer.ToStringPiece());
145761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(0, unlink(new_path.c_str()));
146761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
147761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
148761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, FileMustExist) {
149761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  const std::string bad_path(GetTmpPath("does-not-exist.txt"));
150761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
151761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_FALSE(file.Open(bad_path, MappedFile::kReadOnlyMode));
152761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(-1, file.Fd());
153761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
154761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
155761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, FileMustBeWritable) {
156761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
157761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadOnlyMode));
158761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_FALSE(file.MapReadWrite(10));
159761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
160761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
161761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, RemappingAllowedUntilSuccess) {
162761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
163761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadOnlyMode));
164761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_FALSE(file.MapReadWrite(10));
165761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_FALSE(file.MapReadWrite(10));
166761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
167761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
168761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, ResizeMappedFile) {
169761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
170761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadWriteMode));
171761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.MapReadWrite(10));
172761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(10, file.GetLength());
173761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_TRUE(file.Unmap());
174761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_TRUE(file.MapReadWrite(20));
175761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(20, file.GetLength());
176761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(0, file.Flush());
177761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_TRUE(file.Unmap());
178761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(0, file.Flush());
179761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(0, file.SetLength(5));
180761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_TRUE(file.MapReadOnly());
181761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(5, file.GetLength());
182761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
183761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
184761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, ReadNotMapped) {
185761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  TestRead();
186761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
187761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
188761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, SetLengthNotMapped) {
189761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  TestSetLength();
190761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
191761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
192761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, WriteNotMapped) {
193761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  TestWrite();
194761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
195761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
196761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, ReadMappedReadOnly) {
197761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
198761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadOnlyMode));
199761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.MapReadOnly());
200761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  TestReadContent(kContent, &file);
201761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
202761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
203761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, ReadMappedReadWrite) {
204761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
205761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadWriteMode));
206761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.MapReadWrite(kContent.size()));
207761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  TestReadContent(kContent, &file);
2089433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  UNUSED(file.FlushClose());
209761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
210761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
211761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileTest, WriteMappedReadWrite) {
212761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  TEMP_FAILURE_RETRY(unlink(good_path_.c_str()));
213761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
214761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadWriteMode));
215761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.MapReadWrite(kContent.size()));
216761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
217761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // Can't write to a negative offset.
218761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(-EINVAL, file.Write(kContent.c_str(), 0, -123));
219761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
220761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // A zero-length write is a no-op.
221761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(0, file.Write(kContent.c_str(), 0, 0));
222761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // But the file size is as given when mapped.
223ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  EXPECT_EQ(kContent.size(), static_cast<uint64_t>(file.GetLength()));
224761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
225761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // Data written past the end are discarded.
226761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(kContent.size() - 1,
227ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers            static_cast<uint64_t>(file.Write(kContent.c_str(), kContent.size(), 1)));
228761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(0, memcmp(kContent.c_str(), file.data() + 1, kContent.size() - 1));
229761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
230761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // Data can be overwritten.
231ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  EXPECT_EQ(kContent.size(),
232ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers            static_cast<uint64_t>(file.Write(kContent.c_str(), kContent.size(), 0)));
233761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(0, memcmp(kContent.c_str(), file.data(), kContent.size()));
2349433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  UNUSED(file.FlushClose());
235761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
236761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
2377934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom#if 0  // death tests don't work on android yet
238761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
239761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesclass MappedFileDeathTest : public MappedFileTest {};
240761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
241761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileDeathTest, MustMapBeforeUse) {
242761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
243761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_TRUE(file.Open(good_path_, MappedFile::kReadOnlyMode));
244761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_DEATH(file.data(), "mapped_");
245761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
246761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
247761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileDeathTest, RemappingNotAllowedReadOnly) {
248761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
249761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadOnlyMode));
250761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.MapReadOnly());
251761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_DEATH(file.MapReadOnly(), "mapped_");
252761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
253761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
254761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileDeathTest, RemappingNotAllowedReadWrite) {
255761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
256761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadWriteMode));
257761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.MapReadWrite(10));
258761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_DEATH(file.MapReadWrite(10), "mapped_");
259761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
260761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
261761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileDeathTest, SetLengthMappedReadWrite) {
262761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
263761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadWriteMode));
264761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.MapReadWrite(10));
265761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(10, file.GetLength());
266761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_DEATH(file.SetLength(0), ".*");
267761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
268761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
269761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileDeathTest, SetLengthMappedReadOnly) {
270761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
271761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadOnlyMode));
272761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.MapReadOnly());
273761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_EQ(kContent.size(), file.GetLength());
274761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_DEATH(file.SetLength(0), ".*");
275761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
276761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
277761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesTEST_F(MappedFileDeathTest, WriteMappedReadOnly) {
278761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  MappedFile file;
279761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.Open(good_path_, MappedFile::kReadOnlyMode));
280761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  ASSERT_TRUE(file.MapReadOnly());
281761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  char buf[10];
282761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  EXPECT_DEATH(file.Write(buf, 0, 0), ".*");
283761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
284761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
285761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#endif
286761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
287761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}  // namespace unix_file
288