Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: webkit/plugins/ppapi/quota_file_io_unittest.cc

Issue 7433006: Pepper quota support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: '' Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include <deque>
6
7 #include "base/basictypes.h"
8 #include "base/task.h"
yzshen1 2011/07/28 17:40:52 Please arrange includes alphabetically.
kinuko 2011/07/29 08:39:51 Done.
9 #include "base/memory/scoped_callback_factory.h"
10 #include "base/memory/scoped_callback_factory.h"
yzshen1 2011/07/28 17:40:52 You have redundant includes.
kinuko 2011/07/29 08:39:51 Done.
11 #include "base/message_loop.h"
12 #include "base/platform_file.h"
13 #include "base/scoped_temp_dir.h"
14 #include "webkit/plugins/ppapi/mock_plugin_delegate.h"
15 #include "webkit/plugins/ppapi/ppapi_unittest.h"
16 #include "webkit/plugins/ppapi/quota_file_io.h"
17
18 using base::MessageLoopProxy;
19 using base::PlatformFile;
20 using base::PlatformFileError;
21
22 namespace webkit {
23 namespace ppapi {
24
25 namespace {
26 class QuotaMockPluginDelegate : public MockPluginDelegate {
27 public:
28 typedef PluginDelegate::AvailableSpaceCallback Callback;
29
30 QuotaMockPluginDelegate()
31 : available_space_(0),
32 will_update_count_(0),
33 file_thread_(MessageLoopProxy::CreateForCurrentThread()),
34 runnable_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
35 }
36 virtual ~QuotaMockPluginDelegate() {}
37
38 virtual scoped_refptr<MessageLoopProxy> GetFileThreadMessageLoopProxy() {
39 return file_thread_;
40 }
41
42 virtual void QueryAvailableSpace(
43 const GURL& origin,
44 quota::StorageType type,
45 Callback* callback) OVERRIDE {
46 DCHECK(callback);
47 MessageLoopProxy::CreateForCurrentThread()->PostTask(
48 FROM_HERE, runnable_factory_.NewRunnableMethod(
49 &QuotaMockPluginDelegate::RunAvailableSpaceCallback, callback));
50 }
51
52 virtual void WillUpdateFile(const GURL& file_path) OVERRIDE {
53 file_path_ = file_path;
54 ++will_update_count_;
55 }
56
57 virtual void DidUpdateFile(const GURL& file_path, int64_t delta) OVERRIDE {
58 ASSERT_EQ(file_path_, file_path);
59 ASSERT_GT(will_update_count_, 0);
60 --will_update_count_;
61 available_space_ -= delta;
62 }
63
64 void set_available_space(int64 available) { available_space_ = available; }
65 int64_t available_space() const { return available_space_; }
66
67 private:
68 void RunAvailableSpaceCallback(Callback* callback) {
69 callback->Run(available_space_);
70 delete callback;
71 }
72
73 int64_t available_space_;
74 int will_update_count_;
75 GURL file_path_;
76 scoped_refptr<MessageLoopProxy> file_thread_;
77 ScopedRunnableMethodFactory<QuotaMockPluginDelegate> runnable_factory_;
78 };
79 } // namespace
80
81 class QuotaFileIOTest : public PpapiUnittest {
82 public:
83 QuotaFileIOTest()
84 : callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}
85
86 virtual void SetUp() OVERRIDE {
87 PpapiUnittest::SetUp();
88 ASSERT_TRUE(dir_.CreateUniqueTempDir());
89 FilePath path;
90 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(dir_.path(), &path));
91 int file_flags = base::PLATFORM_FILE_OPEN |
92 base::PLATFORM_FILE_READ |
93 base::PLATFORM_FILE_WRITE |
94 base::PLATFORM_FILE_WRITE_ATTRIBUTES;
95 bool created = false;
96 file_ = base::kInvalidPlatformFileValue;
97 PlatformFileError error = base::PLATFORM_FILE_OK;
98 file_ = base::CreatePlatformFile(path, file_flags, &created, &error);
99 ASSERT_EQ(base::PLATFORM_FILE_OK, error);
100 ASSERT_NE(base::kInvalidPlatformFileValue, file_);
101 ASSERT_FALSE(created);
102 quota_file_io_.reset(new QuotaFileIO(
103 instance(), file_, GURL(), PP_FILESYSTEMTYPE_LOCALTEMPORARY));
104 }
105
106 virtual void TearDown() OVERRIDE {
107 quota_file_io_.reset();
108 if (file_ != base::kInvalidPlatformFileValue)
109 base::ClosePlatformFile(file_);
110 PpapiUnittest::TearDown();
111 }
112
113 protected:
114 virtual MockPluginDelegate* NewPluginDelegate() OVERRIDE {
115 return static_cast<MockPluginDelegate*>(new QuotaMockPluginDelegate);
116 }
117
118 void WriteTestBody(bool will_operation) {
119 quota_plugin_delegate()->set_available_space(100);
120 std::string read_buffer;
121
122 // Write 8 bytes at offset 0 (-> length=8).
123 std::string data("12345678");
124 Write(0, data, will_operation);
125 MessageLoop::current()->RunAllPending();
126 ASSERT_EQ(1U, num_results());
127 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
128 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
129 EXPECT_EQ(100 - 8, quota_plugin_delegate()->available_space());
130 reset_results();
131
132 if (will_operation) {
133 // WillWrite doesn't actually write.
134 EXPECT_EQ(0, GetPlatformFileSize());
135 // Adjust the actual file size to 'fake' write to proceed testing.
136 SetPlatformFileSize(8);
137 } else {
138 EXPECT_EQ(8, GetPlatformFileSize());
139 ReadPlatformFile(&read_buffer);
140 EXPECT_EQ(data, read_buffer);
141 }
142
143 // Write 5 bytes at offset 5 (-> length=10).
144 data = "55555";
145 Write(5, data, will_operation);
146 MessageLoop::current()->RunAllPending();
147 ASSERT_EQ(1U, num_results());
148 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
149 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
150 EXPECT_EQ(100 - 10, quota_plugin_delegate()->available_space());
151 reset_results();
152
153 if (will_operation) {
154 EXPECT_EQ(8, GetPlatformFileSize());
155 SetPlatformFileSize(10);
156 } else {
157 EXPECT_EQ(10, GetPlatformFileSize());
158 ReadPlatformFile(&read_buffer);
159 EXPECT_EQ("1234555555", read_buffer);
160 }
161
162 // Write 7 bytes at offset 8 (-> length=15).
163 data = "9012345";
164 Write(8, data, will_operation);
165 MessageLoop::current()->RunAllPending();
166 ASSERT_EQ(1U, num_results());
167 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
168 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
169 EXPECT_EQ(100 - 15, quota_plugin_delegate()->available_space());
170 reset_results();
171
172 if (will_operation) {
173 EXPECT_EQ(10, GetPlatformFileSize());
174 SetPlatformFileSize(15);
175 } else {
176 EXPECT_EQ(15, GetPlatformFileSize());
177 ReadPlatformFile(&read_buffer);
178 EXPECT_EQ("123455559012345", read_buffer);
179 }
180
181 // Write 2 bytes at offset 2 (-> length=15).
182 data = "33";
183 Write(2, data, will_operation);
184 MessageLoop::current()->RunAllPending();
185 ASSERT_EQ(1U, num_results());
186 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
187 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
188 EXPECT_EQ(100 - 15, quota_plugin_delegate()->available_space());
189 reset_results();
190
191 if (will_operation) {
192 EXPECT_EQ(15, GetPlatformFileSize());
193 } else {
194 EXPECT_EQ(15, GetPlatformFileSize());
195 ReadPlatformFile(&read_buffer);
196 EXPECT_EQ("123355559012345", read_buffer);
197 }
198
199 // Write 4 bytes at offset 20 (-> length=24).
200 data = "XXXX";
201 Write(20, data, will_operation);
202 MessageLoop::current()->RunAllPending();
203 ASSERT_EQ(1U, num_results());
204 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
205 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
206 EXPECT_EQ(100 - 24, quota_plugin_delegate()->available_space());
207 reset_results();
208
209 if (will_operation) {
210 EXPECT_EQ(15, GetPlatformFileSize());
211 SetPlatformFileSize(24);
212 } else {
213 EXPECT_EQ(24, GetPlatformFileSize());
214 ReadPlatformFile(&read_buffer);
215 EXPECT_EQ(std::string("123355559012345\0\0\0\0\0XXXX", 24), read_buffer);
216 }
217
218 quota_plugin_delegate()->set_available_space(5);
219
220 // Quota error case. Write 7 bytes at offset 23 (-> length is unchanged)
221 data = "ABCDEFG";
222 Write(23, data, will_operation);
223 MessageLoop::current()->RunAllPending();
224 ASSERT_EQ(1U, num_results());
225 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status().front());
226 EXPECT_EQ(5, quota_plugin_delegate()->available_space());
227 reset_results();
228
229 // Overlapping write. Write 6 bytes at offset 2 (-> length is unchanged)
230 data = "ABCDEF";
231 Write(2, data, will_operation);
232 MessageLoop::current()->RunAllPending();
233 ASSERT_EQ(1U, num_results());
234 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
235 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
236 EXPECT_EQ(5, quota_plugin_delegate()->available_space());
237 reset_results();
238
239 // Overlapping + extending the file size, but within the quota.
240 // Write 6 bytes at offset 23 (-> length=29).
241 Write(23, data, will_operation);
242 MessageLoop::current()->RunAllPending();
243 ASSERT_EQ(1U, num_results());
244 EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
245 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
246 EXPECT_EQ(0, quota_plugin_delegate()->available_space());
247 reset_results();
248
249 if (!will_operation) {
250 EXPECT_EQ(29, GetPlatformFileSize());
251 ReadPlatformFile(&read_buffer);
252 EXPECT_EQ(std::string("12ABCDEF9012345\0\0\0\0\0XXXABCDEF", 29),
253 read_buffer);
254 }
255 }
256
257 void SetLengthTestBody(bool will_operation) {
258 quota_plugin_delegate()->set_available_space(100);
259
260 SetLength(0, will_operation);
261 MessageLoop::current()->RunAllPending();
262 ASSERT_EQ(1U, num_results());
263 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
264 EXPECT_EQ(0, GetPlatformFileSize());
265 EXPECT_EQ(100, quota_plugin_delegate()->available_space());
266 reset_results();
267
268 SetLength(8, will_operation);
269 MessageLoop::current()->RunAllPending();
270 ASSERT_EQ(1U, num_results());
271 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
272 EXPECT_EQ(100 - 8, quota_plugin_delegate()->available_space());
273 reset_results();
274
275 if (will_operation) {
276 EXPECT_EQ(0, GetPlatformFileSize());
277 SetPlatformFileSize(8);
278 } else {
279 EXPECT_EQ(8, GetPlatformFileSize());
280 }
281
282 SetLength(16, will_operation);
283 MessageLoop::current()->RunAllPending();
284 ASSERT_EQ(1U, num_results());
285 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
286 EXPECT_EQ(100 - 16, quota_plugin_delegate()->available_space());
287 reset_results();
288
289 if (will_operation) {
290 EXPECT_EQ(8, GetPlatformFileSize());
291 SetPlatformFileSize(16);
292 } else {
293 EXPECT_EQ(16, GetPlatformFileSize());
294 }
295
296 SetLength(4, will_operation);
297 MessageLoop::current()->RunAllPending();
298 ASSERT_EQ(1U, num_results());
299 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
300 EXPECT_EQ(100 - 4, quota_plugin_delegate()->available_space());
301 reset_results();
302
303 if (will_operation) {
304 EXPECT_EQ(16, GetPlatformFileSize());
305 SetPlatformFileSize(4);
306 } else {
307 EXPECT_EQ(4, GetPlatformFileSize());
308 }
309
310 SetLength(0, will_operation);
311 MessageLoop::current()->RunAllPending();
312 ASSERT_EQ(1U, num_results());
313 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
314 EXPECT_EQ(100, quota_plugin_delegate()->available_space());
315 reset_results();
316
317 if (will_operation) {
318 EXPECT_EQ(4, GetPlatformFileSize());
319 SetPlatformFileSize(0);
320 } else {
321 EXPECT_EQ(0, GetPlatformFileSize());
322 }
323
324 quota_plugin_delegate()->set_available_space(5);
325
326 // Quota error case.
327 SetLength(7, will_operation);
328 MessageLoop::current()->RunAllPending();
329 ASSERT_EQ(1U, num_results());
330 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status().front());
331 EXPECT_EQ(5, quota_plugin_delegate()->available_space());
332 reset_results();
333 }
334
335 QuotaMockPluginDelegate* quota_plugin_delegate() {
336 return static_cast<QuotaMockPluginDelegate*>(delegate());
337 }
338
339 void Write(int64_t offset, const std::string& data, bool will_operation) {
340 if (will_operation) {
341 ASSERT_TRUE(quota_file_io_->WillWrite(
342 offset, data.size(),
343 callback_factory_.NewCallback(
344 &QuotaFileIOTest::DidWrite)));
345 } else {
346 ASSERT_TRUE(quota_file_io_->Write(
347 offset, data.c_str(), data.size(),
348 callback_factory_.NewCallback(
349 &QuotaFileIOTest::DidWrite)));
350 }
351 }
352
353 void SetLength(int64_t length, bool will_operation) {
354 if (will_operation) {
355 ASSERT_TRUE(quota_file_io_->WillSetLength(
356 length,
357 callback_factory_.NewCallback(
358 &QuotaFileIOTest::DidSetLength)));
359 } else {
360 ASSERT_TRUE(quota_file_io_->SetLength(
361 length,
362 callback_factory_.NewCallback(
363 &QuotaFileIOTest::DidSetLength)));
364 }
365 }
366
367 void DidWrite(PlatformFileError status, int bytes_written) {
368 status_.push_back(status);
369 bytes_written_.push_back(bytes_written);
370 }
371
372 void DidSetLength(PlatformFileError status) {
373 status_.push_back(status);
374 }
375
376 size_t num_results() const { return status_.size(); }
377 const std::deque<int>& bytes_written() const { return bytes_written_; }
378 const std::deque<PlatformFileError>& status() const { return status_; }
379
380 void reset_results() {
381 bytes_written_.clear();
382 status_.clear();
383 }
384
385 void pop_result() {
386 bytes_written_.pop_front();
387 status_.pop_front();
388 }
389
390 void ReadPlatformFile(std::string* data) {
391 data->clear();
392 char buf[256];
393 int32_t read_offset = 0;
394 for (;;) {
395 int rv = base::ReadPlatformFile(file_, read_offset, buf, sizeof(buf));
396 ASSERT_GE(rv, 0);
397 if (rv == 0)
398 break;
399 read_offset += rv;
400 data->append(buf, rv);
401 }
402 }
403
404 int64_t GetPlatformFileSize() {
405 base::PlatformFileInfo info;
406 EXPECT_TRUE(base::GetPlatformFileInfo(file_, &info));
407 return info.size;
408 }
409
410 void SetPlatformFileSize(int64_t length) {
411 EXPECT_TRUE(base::TruncatePlatformFile(file_, length));
412 }
413
414 private:
415 ScopedTempDir dir_;
416 PlatformFile file_;
417 scoped_ptr<QuotaFileIO> quota_file_io_;
418 std::deque<int> bytes_written_;
419 std::deque<PlatformFileError> status_;
420 base::ScopedCallbackFactory<QuotaFileIOTest> callback_factory_;
421 };
422
423 TEST_F(QuotaFileIOTest, Write) {
424 WriteTestBody(false);
425 }
426
427 TEST_F(QuotaFileIOTest, WillWrite) {
428 WriteTestBody(true);
429 }
430
431 TEST_F(QuotaFileIOTest, SetLength) {
432 SetLengthTestBody(false);
433 }
434
435 TEST_F(QuotaFileIOTest, WillSetLength) {
436 SetLengthTestBody(true);
437 }
438
439 TEST_F(QuotaFileIOTest, ParallelWrites) {
440 quota_plugin_delegate()->set_available_space(22);
441 std::string read_buffer;
442
443 const std::string data1[] = {
444 std::string("12345678"),
445 std::string("55555"),
446 std::string("9012345"),
447 };
448 Write(0, data1[0], false);
449 Write(5, data1[1], false);
450 Write(8, data1[2], false);
451 MessageLoop::current()->RunAllPending();
452
453 ASSERT_EQ(ARRAYSIZE_UNSAFE(data1), num_results());
454 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data1); ++i) {
455 EXPECT_EQ(static_cast<int>(data1[i].size()), bytes_written().front());
456 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
457 pop_result();
458 }
459
460 EXPECT_EQ(22 - 15, quota_plugin_delegate()->available_space());
461 EXPECT_EQ(15, GetPlatformFileSize());
462 ReadPlatformFile(&read_buffer);
463 EXPECT_EQ("123455559012345", read_buffer);
464
465 // The second write will fail for quota error.
466 const std::string data2[] = {
467 std::string("33"),
468 std::string("XXXX"),
469 };
470 Write(2, data2[0], false);
471 Write(20, data2[1], false);
472 MessageLoop::current()->RunAllPending();
473
474 ASSERT_EQ(ARRAYSIZE_UNSAFE(data2), num_results());
475 EXPECT_EQ(static_cast<int>(data2[0].size()), bytes_written().front());
476 EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
477 pop_result();
478 EXPECT_EQ(0, bytes_written().front());
479 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status().front());
480 pop_result();
481
482 EXPECT_EQ(22 - 15, quota_plugin_delegate()->available_space());
483 EXPECT_EQ(15, GetPlatformFileSize());
484 ReadPlatformFile(&read_buffer);
485 EXPECT_EQ("123355559012345", read_buffer);
486 }
487
488 } // namespace ppapi
489 } // namespace webkit
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698