Refactor management of overview window copy lifetime into a separate class.
[chromium-blink-merge.git] / content / renderer / pepper / quota_file_io_unittest.cc
blobf1d7a59aec793e2e39abe6f5d1ee2a07e4c16ad6
1 // Copyright (c) 2011 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.
5 #include <deque>
6 #include <limits>
7 #include <string>
9 #include "base/basictypes.h"
10 #include "base/bind.h"
11 #include "base/file_util.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/platform_file.h"
16 #include "content/renderer/pepper/quota_file_io.h"
17 #include "content/test/ppapi_unittest.h"
19 using base::MessageLoopProxy;
20 using base::PlatformFile;
21 using base::PlatformFileError;
23 namespace content {
25 namespace {
26 class QuotaMockDelegate : public QuotaFileIO::Delegate {
27 public:
28 typedef QuotaFileIO::Delegate::AvailableSpaceCallback Callback;
30 QuotaMockDelegate()
31 : available_space_(0),
32 will_update_count_(0),
33 file_thread_(MessageLoopProxy::current()),
34 weak_factory_(this) {
36 virtual ~QuotaMockDelegate() {}
38 virtual void QueryAvailableSpace(
39 const GURL& origin,
40 quota::StorageType type,
41 const Callback& callback) OVERRIDE {
42 DCHECK_EQ(false, callback.is_null());
43 MessageLoopProxy::current()->PostTask(
44 FROM_HERE, base::Bind(
45 &QuotaMockDelegate::RunAvailableSpaceCallback,
46 weak_factory_.GetWeakPtr(), callback));
49 virtual void WillUpdateFile(const GURL& file_path) OVERRIDE {
50 file_path_ = file_path;
51 ++will_update_count_;
54 virtual void DidUpdateFile(const GURL& file_path, int64_t delta) OVERRIDE {
55 ASSERT_EQ(file_path_, file_path);
56 ASSERT_GT(will_update_count_, 0);
57 --will_update_count_;
58 available_space_ -= delta;
61 virtual scoped_refptr<base::MessageLoopProxy>
62 GetFileThreadMessageLoopProxy() OVERRIDE {
63 return file_thread_;
66 void set_available_space(int64 available) { available_space_ = available; }
67 int64_t available_space() const { return available_space_; }
69 private:
70 void RunAvailableSpaceCallback(const Callback& callback) {
71 callback.Run(available_space_);
74 int64_t available_space_;
75 int will_update_count_;
76 GURL file_path_;
77 scoped_refptr<MessageLoopProxy> file_thread_;
78 base::WeakPtrFactory<QuotaMockDelegate> weak_factory_;
80 } // namespace
82 class QuotaFileIOTest : public PpapiUnittest {
83 public:
84 QuotaFileIOTest()
85 : delegate_(NULL),
86 weak_factory_(this) {}
88 virtual void SetUp() OVERRIDE {
89 PpapiUnittest::SetUp();
90 ASSERT_TRUE(dir_.CreateUniqueTempDir());
91 base::FilePath path;
92 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(dir_.path(), &path));
93 int file_flags = base::PLATFORM_FILE_OPEN |
94 base::PLATFORM_FILE_READ |
95 base::PLATFORM_FILE_WRITE |
96 base::PLATFORM_FILE_WRITE_ATTRIBUTES;
97 bool created = false;
98 file_ = base::kInvalidPlatformFileValue;
99 PlatformFileError error = base::PLATFORM_FILE_OK;
100 file_ = base::CreatePlatformFile(path, file_flags, &created, &error);
101 ASSERT_EQ(base::PLATFORM_FILE_OK, error);
102 ASSERT_NE(base::kInvalidPlatformFileValue, file_);
103 ASSERT_FALSE(created);
104 delegate_ = new QuotaMockDelegate; // Owned by QuotaFileIO.
105 quota_file_io_.reset(new QuotaFileIO(
106 delegate_, file_, GURL(), PP_FILESYSTEMTYPE_LOCALTEMPORARY));
109 virtual void TearDown() OVERRIDE {
110 quota_file_io_.reset();
111 if (file_ != base::kInvalidPlatformFileValue)
112 base::ClosePlatformFile(file_);
113 PpapiUnittest::TearDown();
116 protected:
117 void WriteTestBody() {
118 // Attempt to write zero bytes.
119 EXPECT_FALSE(quota_file_io_->Write(
120 0, "data", 0,
121 base::Bind(&QuotaFileIOTest::DidWrite, weak_factory_.GetWeakPtr())));
122 // Attempt to write negative number of bytes.
123 EXPECT_FALSE(quota_file_io_->Write(
124 0, "data", std::numeric_limits<int32_t>::min(),
125 base::Bind(&QuotaFileIOTest::DidWrite, weak_factory_.GetWeakPtr())));
127 delegate()->set_available_space(100);
128 std::string read_buffer;
130 // Write 8 bytes at offset 0 (-> length=8).
131 std::string data("12345678");
132 Write(0, data);
133 base::MessageLoop::current()->RunUntilIdle();
134 ASSERT_EQ(1U, num_results());
135 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
136 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
137 EXPECT_EQ(100 - 8, delegate()->available_space());
138 reset_results();
140 EXPECT_EQ(8, GetPlatformFileSize());
141 ReadPlatformFile(&read_buffer);
142 EXPECT_EQ(data, read_buffer);
144 // Write 5 bytes at offset 5 (-> length=10).
145 data = "55555";
146 Write(5, data);
147 base::MessageLoop::current()->RunUntilIdle();
148 ASSERT_EQ(1U, num_results());
149 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
150 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
151 EXPECT_EQ(100 - 10, delegate()->available_space());
152 reset_results();
154 EXPECT_EQ(10, GetPlatformFileSize());
155 ReadPlatformFile(&read_buffer);
156 EXPECT_EQ("1234555555", read_buffer);
158 // Write 7 bytes at offset 8 (-> length=15).
159 data = "9012345";
160 Write(8, data);
161 base::MessageLoop::current()->RunUntilIdle();
162 ASSERT_EQ(1U, num_results());
163 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
164 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
165 EXPECT_EQ(100 - 15, delegate()->available_space());
166 reset_results();
168 EXPECT_EQ(15, GetPlatformFileSize());
169 ReadPlatformFile(&read_buffer);
170 EXPECT_EQ("123455559012345", read_buffer);
172 // Write 2 bytes at offset 2 (-> length=15).
173 data = "33";
174 Write(2, data);
175 base::MessageLoop::current()->RunUntilIdle();
176 ASSERT_EQ(1U, num_results());
177 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
178 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
179 EXPECT_EQ(100 - 15, delegate()->available_space());
180 reset_results();
182 EXPECT_EQ(15, GetPlatformFileSize());
183 ReadPlatformFile(&read_buffer);
184 EXPECT_EQ("123355559012345", read_buffer);
186 // Write 4 bytes at offset 20 (-> length=24).
187 data = "XXXX";
188 Write(20, data);
189 base::MessageLoop::current()->RunUntilIdle();
190 ASSERT_EQ(1U, num_results());
191 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
192 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
193 EXPECT_EQ(100 - 24, delegate()->available_space());
194 reset_results();
196 EXPECT_EQ(24, GetPlatformFileSize());
197 ReadPlatformFile(&read_buffer);
198 EXPECT_EQ(std::string("123355559012345\0\0\0\0\0XXXX", 24), read_buffer);
200 delegate()->set_available_space(5);
202 // Quota error case. Write 7 bytes at offset 23 (-> length is unchanged)
203 data = "ABCDEFG";
204 Write(23, data);
205 base::MessageLoop::current()->RunUntilIdle();
206 ASSERT_EQ(1U, num_results());
207 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status().front());
208 EXPECT_EQ(5, delegate()->available_space());
209 reset_results();
211 // Overlapping write. Write 6 bytes at offset 2 (-> length is unchanged)
212 data = "ABCDEF";
213 Write(2, data);
214 base::MessageLoop::current()->RunUntilIdle();
215 ASSERT_EQ(1U, num_results());
216 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
217 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
218 EXPECT_EQ(5, delegate()->available_space());
219 reset_results();
221 // Overlapping + extending the file size, but within the quota.
222 // Write 6 bytes at offset 23 (-> length=29).
223 Write(23, data);
224 base::MessageLoop::current()->RunUntilIdle();
225 ASSERT_EQ(1U, num_results());
226 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
227 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
228 EXPECT_EQ(0, delegate()->available_space());
229 reset_results();
231 EXPECT_EQ(29, GetPlatformFileSize());
232 ReadPlatformFile(&read_buffer);
233 EXPECT_EQ(std::string("12ABCDEF9012345\0\0\0\0\0XXXABCDEF", 29),
234 read_buffer);
237 void SetLengthTestBody() {
238 delegate()->set_available_space(100);
240 SetLength(0);
241 base::MessageLoop::current()->RunUntilIdle();
242 ASSERT_EQ(1U, num_results());
243 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
244 EXPECT_EQ(0, GetPlatformFileSize());
245 EXPECT_EQ(100, delegate()->available_space());
246 reset_results();
248 SetLength(8);
249 base::MessageLoop::current()->RunUntilIdle();
250 ASSERT_EQ(1U, num_results());
251 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
252 EXPECT_EQ(100 - 8, delegate()->available_space());
253 reset_results();
255 EXPECT_EQ(8, GetPlatformFileSize());
257 SetLength(16);
258 base::MessageLoop::current()->RunUntilIdle();
259 ASSERT_EQ(1U, num_results());
260 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
261 EXPECT_EQ(100 - 16, delegate()->available_space());
262 reset_results();
264 EXPECT_EQ(16, GetPlatformFileSize());
266 SetLength(4);
267 base::MessageLoop::current()->RunUntilIdle();
268 ASSERT_EQ(1U, num_results());
269 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
270 EXPECT_EQ(100 - 4, delegate()->available_space());
271 reset_results();
273 EXPECT_EQ(4, GetPlatformFileSize());
275 SetLength(0);
276 base::MessageLoop::current()->RunUntilIdle();
277 ASSERT_EQ(1U, num_results());
278 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
279 EXPECT_EQ(100, delegate()->available_space());
280 reset_results();
282 EXPECT_EQ(0, GetPlatformFileSize());
284 delegate()->set_available_space(5);
286 // Quota error case.
287 SetLength(7);
288 base::MessageLoop::current()->RunUntilIdle();
289 ASSERT_EQ(1U, num_results());
290 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status().front());
291 EXPECT_EQ(5, delegate()->available_space());
292 reset_results();
295 QuotaMockDelegate* delegate() {
296 return delegate_;
299 void Write(int64_t offset, const std::string& data) {
300 ASSERT_TRUE(quota_file_io_->Write(
301 offset, data.c_str(), data.size(),
302 base::Bind(&QuotaFileIOTest::DidWrite, weak_factory_.GetWeakPtr())));
305 void SetLength(int64_t length) {
306 ASSERT_TRUE(quota_file_io_->SetLength(
307 length,
308 base::Bind(&QuotaFileIOTest::DidSetLength,
309 weak_factory_.GetWeakPtr())));
312 void DidWrite(PlatformFileError status, int bytes_written) {
313 status_.push_back(status);
314 bytes_written_.push_back(bytes_written);
317 void DidSetLength(PlatformFileError status) {
318 status_.push_back(status);
321 size_t num_results() const { return status_.size(); }
322 const std::deque<int>& bytes_written() const { return bytes_written_; }
323 const std::deque<PlatformFileError>& status() const { return status_; }
325 void reset_results() {
326 bytes_written_.clear();
327 status_.clear();
330 void pop_result() {
331 bytes_written_.pop_front();
332 status_.pop_front();
335 void ReadPlatformFile(std::string* data) {
336 data->clear();
337 char buf[256];
338 int32_t read_offset = 0;
339 for (;;) {
340 int rv = base::ReadPlatformFile(file_, read_offset, buf, sizeof(buf));
341 ASSERT_GE(rv, 0);
342 if (rv == 0)
343 break;
344 read_offset += rv;
345 data->append(buf, rv);
349 int64_t GetPlatformFileSize() {
350 base::PlatformFileInfo info;
351 EXPECT_TRUE(base::GetPlatformFileInfo(file_, &info));
352 return info.size;
355 void SetPlatformFileSize(int64_t length) {
356 EXPECT_TRUE(base::TruncatePlatformFile(file_, length));
359 private:
360 base::ScopedTempDir dir_;
361 PlatformFile file_;
362 scoped_ptr<QuotaFileIO> quota_file_io_;
363 std::deque<int> bytes_written_;
364 std::deque<PlatformFileError> status_;
365 QuotaMockDelegate* delegate_;
366 base::WeakPtrFactory<QuotaFileIOTest> weak_factory_;
369 TEST_F(QuotaFileIOTest, Write) {
370 WriteTestBody();
373 TEST_F(QuotaFileIOTest, SetLength) {
374 SetLengthTestBody();
377 TEST_F(QuotaFileIOTest, ParallelWrites) {
378 delegate()->set_available_space(22);
379 std::string read_buffer;
381 const std::string data1[] = {
382 std::string("12345678"),
383 std::string("55555"),
384 std::string("9012345"),
386 Write(0, data1[0]);
387 Write(5, data1[1]);
388 Write(8, data1[2]);
389 base::MessageLoop::current()->RunUntilIdle();
391 ASSERT_EQ(ARRAYSIZE_UNSAFE(data1), num_results());
392 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data1); ++i) {
393 EXPECT_EQ(static_cast<int>(data1[i].size()), bytes_written().front());
394 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
395 pop_result();
398 EXPECT_EQ(22 - 15, delegate()->available_space());
399 EXPECT_EQ(15, GetPlatformFileSize());
400 ReadPlatformFile(&read_buffer);
401 EXPECT_EQ("123455559012345", read_buffer);
403 // The second write will fail for quota error.
404 const std::string data2[] = {
405 std::string("33"),
406 std::string("XXXX"),
408 Write(2, data2[0]);
409 Write(20, data2[1]);
410 base::MessageLoop::current()->RunUntilIdle();
412 ASSERT_EQ(ARRAYSIZE_UNSAFE(data2), num_results());
413 EXPECT_EQ(static_cast<int>(data2[0].size()), bytes_written().front());
414 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
415 pop_result();
416 EXPECT_EQ(0, bytes_written().front());
417 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status().front());
418 pop_result();
420 EXPECT_EQ(22 - 15, delegate()->available_space());
421 EXPECT_EQ(15, GetPlatformFileSize());
422 ReadPlatformFile(&read_buffer);
423 EXPECT_EQ("123355559012345", read_buffer);
426 } // namespace content