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

Side by Side Diff: webkit/appcache/appcache_response_unittest.cc

Issue 269062: AppCacheResponse storage implementation (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 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
« no previous file with comments | « webkit/appcache/appcache_response.cc ('k') | webkit/appcache/appcache_service.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authos. 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/compiler_specific.h"
6 #include "base/pickle.h"
7 #include "base/thread.h"
8 #include "base/waitable_event.h"
9 #include "net/base/io_buffer.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "webkit/appcache/appcache_response.h"
12 #include "webkit/appcache/mock_appcache_service.h"
13
14 using net::IOBuffer;
15
16 namespace appcache {
17
18 class AppCacheResponseTest : public testing::Test {
19 public:
20
21 // Test Harness -------------------------------------------------------------
22
23 // Helper class used to verify test results
24 class MockStorageDelegate : public AppCacheStorage::Delegate {
25 public:
26 explicit MockStorageDelegate(AppCacheResponseTest* test)
27 : loaded_info_id_(0), test_(test) {
28 }
29
30 virtual void OnResponseInfoLoaded(AppCacheResponseInfo* info,
31 int64 response_id) {
32 loaded_info_ = info;
33 loaded_info_id_ = response_id;
34 test_->ScheduleNextTask();
35 }
36
37 scoped_refptr<AppCacheResponseInfo> loaded_info_;
38 int64 loaded_info_id_;
39 AppCacheResponseTest* test_;
40 };
41
42 // Helper class run a test on our io_thread. The io_thread
43 // is spun up once and reused for all tests.
44 template <class Method>
45 class WrapperTask : public Task {
46 public:
47 WrapperTask(AppCacheResponseTest* test, Method method)
48 : test_(test), method_(method) {
49 }
50
51 virtual void Run() {
52 test_->SetUpTest();
53 (test_->*method_)();
54 }
55
56 private:
57 AppCacheResponseTest* test_;
58 Method method_;
59 };
60
61 static void SetUpTestCase() {
62 io_thread_.reset(new base::Thread("AppCacheResponseTest Thread"));
63 base::Thread::Options options(MessageLoop::TYPE_IO, 0);
64 io_thread_->StartWithOptions(options);
65 }
66
67 static void TearDownTestCase() {
68 io_thread_.reset(NULL);
69 }
70
71 AppCacheResponseTest()
72 : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
73 ALLOW_THIS_IN_INITIALIZER_LIST(read_callback_(
74 this, &AppCacheResponseTest::OnReadComplete)),
75 ALLOW_THIS_IN_INITIALIZER_LIST(read_info_callback_(
76 this, &AppCacheResponseTest::OnReadInfoComplete)),
77 ALLOW_THIS_IN_INITIALIZER_LIST(write_callback_(
78 this, &AppCacheResponseTest::OnWriteComplete)),
79 ALLOW_THIS_IN_INITIALIZER_LIST(write_info_callback_(
80 this, &AppCacheResponseTest::OnWriteInfoComplete)) {
81 }
82
83 template <class Method>
84 void RunTestOnIOThread(Method method) {
85 test_finished_event_ .reset(new base::WaitableEvent(false, false));
86 io_thread_->message_loop()->PostTask(
87 FROM_HERE, new WrapperTask<Method>(this, method));
88 test_finished_event_->Wait();
89 }
90
91 void SetUpTest() {
92 DCHECK(MessageLoop::current() == io_thread_->message_loop());
93 DCHECK(task_stack_.empty());
94 storage_delegate_.reset(new MockStorageDelegate(this));
95 service_.reset(new MockAppCacheService());
96 expected_read_result_ = 0;
97 expected_write_result_ = 0;
98 written_response_id_ = 0;
99 should_delete_reader_in_completion_callback_ = false;
100 should_delete_writer_in_completion_callback_ = false;
101 reader_deletion_count_down_ = 0;
102 writer_deletion_count_down_ = 0;
103 read_callback_was_called_ = false;
104 write_callback_was_called_ = false;
105 }
106
107 void TearDownTest() {
108 DCHECK(MessageLoop::current() == io_thread_->message_loop());
109 while (!task_stack_.empty()) {
110 delete task_stack_.top().first;
111 task_stack_.pop();
112 }
113 reader_.reset();
114 read_buffer_ = NULL;
115 read_info_buffer_ = NULL;
116 writer_.reset();
117 write_buffer_ = NULL;
118 write_info_buffer_ = NULL;
119 storage_delegate_.reset();
120 service_.reset();
121 }
122
123 void TestFinished() {
124 // We unwind the stack prior to finishing up to let stack
125 // based objects get deleted.
126 DCHECK(MessageLoop::current() == io_thread_->message_loop());
127 MessageLoop::current()->PostTask(FROM_HERE,
128 method_factory_.NewRunnableMethod(
129 &AppCacheResponseTest::TestFinishedUnwound));
130 }
131
132 void TestFinishedUnwound() {
133 TearDownTest();
134 test_finished_event_->Signal();
135 }
136
137 void PushNextTask(Task* task) {
138 task_stack_.push(std::pair<Task*, bool>(task, false));
139 }
140
141 void PushNextTaskAsImmediate(Task* task) {
142 task_stack_.push(std::pair<Task*, bool>(task, true));
143 }
144
145 void ScheduleNextTask() {
146 DCHECK(MessageLoop::current() == io_thread_->message_loop());
147 if (task_stack_.empty()) {
148 TestFinished();
149 return;
150 }
151 scoped_ptr<Task> task(task_stack_.top().first);
152 bool immediate = task_stack_.top().second;
153 task_stack_.pop();
154 if (immediate)
155 task->Run();
156 else
157 MessageLoop::current()->PostTask(FROM_HERE, task.release());
158 }
159
160 // Wrappers to call AppCacheResponseReader/Writer Read and Write methods
161
162 void WriteBasicResponse() {
163 static const char* kRawHttpHeaders =
164 "HTTP/1.0 200 OK\r\nContent-Length: 5\r\n\r\n";
165 static const char* kRawHttpBody = "Hello";
166 WriteResponse(MakeHttpResponseInfo(kRawHttpHeaders), kRawHttpBody);
167 }
168
169 void WriteResponse(net::HttpResponseInfo* head, const char* body) {
170 PushNextTask(method_factory_.NewRunnableMethod(
171 &AppCacheResponseTest::WriteResponseBody,
172 new net::WrappedIOBuffer(body), strlen(body)));
173 WriteResponseHead(head);
174 }
175
176 void WriteResponseHead(net::HttpResponseInfo* head) {
177 EXPECT_FALSE(writer_->IsWritePending());
178 expected_write_result_ = GetHttpResponseInfoSize(head);
179 write_info_buffer_ = new HttpResponseInfoIOBuffer(head);
180 writer_->WriteInfo(write_info_buffer_, &write_info_callback_);
181 }
182
183 void WriteResponseBody(scoped_refptr<IOBuffer> io_buffer, int buf_len) {
184 EXPECT_FALSE(writer_->IsWritePending());
185 write_buffer_ = io_buffer;
186 expected_write_result_ = buf_len;
187 writer_->WriteData(
188 write_buffer_, buf_len, &write_callback_);
189 }
190
191 void ReadResponseBody(scoped_refptr<IOBuffer> io_buffer, int buf_len) {
192 EXPECT_FALSE(reader_->IsReadPending());
193 read_buffer_ = io_buffer;
194 expected_read_result_ = buf_len;
195 reader_->ReadData(
196 read_buffer_, buf_len, &read_callback_);
197 }
198
199 // AppCacheResponseReader / Writer completion callbacks
200
201 void OnWriteInfoComplete(int result) {
202 EXPECT_FALSE(writer_->IsWritePending());
203 EXPECT_EQ(expected_write_result_, result);
204 ScheduleNextTask();
205 }
206
207 void OnWriteComplete(int result) {
208 EXPECT_FALSE(writer_->IsWritePending());
209 write_callback_was_called_ = true;
210 EXPECT_EQ(expected_write_result_, result);
211 if (should_delete_writer_in_completion_callback_ &&
212 --writer_deletion_count_down_ == 0) {
213 writer_.reset();
214 }
215 ScheduleNextTask();
216 }
217
218 void OnReadInfoComplete(int result) {
219 EXPECT_FALSE(reader_->IsReadPending());
220 EXPECT_EQ(expected_read_result_, result);
221 ScheduleNextTask();
222 }
223
224 void OnReadComplete(int result) {
225 EXPECT_FALSE(reader_->IsReadPending());
226 read_callback_was_called_ = true;
227 EXPECT_EQ(expected_read_result_, result);
228 if (should_delete_reader_in_completion_callback_ &&
229 --reader_deletion_count_down_ == 0) {
230 reader_.reset();
231 }
232 ScheduleNextTask();
233 }
234
235 // Helpers to work with HttpResponseInfo objects
236
237 net::HttpResponseInfo* MakeHttpResponseInfo(const char* raw_headers) {
238 net::HttpResponseInfo* info = new net::HttpResponseInfo;
239 info->request_time = base::Time::Now();
240 info->response_time = base::Time::Now();
241 info->was_cached = false;
242 info->headers = new net::HttpResponseHeaders(raw_headers);
243 return info;
244 }
245
246 int GetHttpResponseInfoSize(const net::HttpResponseInfo* info) {
247 Pickle pickle;
248 return PickleHttpResonseInfo(&pickle, info);
249 }
250
251 bool CompareHttpResponseInfos(const net::HttpResponseInfo* info1,
252 const net::HttpResponseInfo* info2) {
253 Pickle pickle1;
254 Pickle pickle2;
255 PickleHttpResonseInfo(&pickle1, info1);
256 PickleHttpResonseInfo(&pickle2, info2);
257 return (pickle1.size() == pickle2.size()) &&
258 (0 == memcmp(pickle1.data(), pickle2.data(), pickle1.size()));
259 }
260
261 int PickleHttpResonseInfo(Pickle* pickle, const net::HttpResponseInfo* info) {
262 const bool kSkipTransientHeaders = true;
263 const bool kTruncated = false;
264 info->Persist(pickle, kSkipTransientHeaders, kTruncated);
265 return pickle->size();
266 }
267
268 // Helpers to fill and verify blocks of memory with a value
269
270 void FillData(char value, char* data, int data_len) {
271 memset(data, value, data_len);
272 }
273
274 bool CheckData(char value, const char* data, int data_len) {
275 for (int i = 0; i < data_len; ++i, ++data) {
276 if (*data != value)
277 return false;
278 }
279 return true;
280 }
281
282 // Individual Tests ---------------------------------------------------------
283 // Most of the individual tests involve multiple async steps. Each test
284 // is delineated with a section header.
285
286 // DelegateReferences -------------------------------------------------------
287 // TODO(michaeln): maybe this one belongs in appcache_storage_unittest.cc
288 void DelegateReferences() {
289 typedef scoped_refptr<AppCacheStorage::DelegateReference>
290 ScopedDelegateReference;
291 MockStorageDelegate delegate(this);
292 ScopedDelegateReference delegate_reference1;
293 ScopedDelegateReference delegate_reference2;
294
295 EXPECT_FALSE(service_->storage()->GetDelegateReference(&delegate));
296
297 delegate_reference1 =
298 service_->storage()->GetOrCreateDelegateReference(&delegate);
299 EXPECT_TRUE(delegate_reference1.get());
300 EXPECT_TRUE(delegate_reference1->HasOneRef());
301 EXPECT_TRUE(service_->storage()->GetDelegateReference(&delegate));
302 EXPECT_EQ(&delegate,
303 service_->storage()->GetDelegateReference(&delegate)->delegate);
304 EXPECT_EQ(service_->storage()->GetDelegateReference(&delegate),
305 service_->storage()->GetOrCreateDelegateReference(&delegate));
306 delegate_reference1 = NULL;
307 EXPECT_FALSE(service_->storage()->GetDelegateReference(&delegate));
308
309 delegate_reference1 =
310 service_->storage()->GetOrCreateDelegateReference(&delegate);
311 service_->storage()->CancelDelegateCallbacks(&delegate);
312 EXPECT_TRUE(delegate_reference1.get());
313 EXPECT_TRUE(delegate_reference1->HasOneRef());
314 EXPECT_FALSE(delegate_reference1->delegate);
315 EXPECT_FALSE(service_->storage()->GetDelegateReference(&delegate));
316
317 delegate_reference2 =
318 service_->storage()->GetOrCreateDelegateReference(&delegate);
319 EXPECT_TRUE(delegate_reference2.get());
320 EXPECT_TRUE(delegate_reference2->HasOneRef());
321 EXPECT_EQ(&delegate, delegate_reference2->delegate);
322 EXPECT_NE(delegate_reference1.get(), delegate_reference2.get());
323
324 TestFinished();
325 }
326
327 // ReadNonExistentResponse -------------------------------------------
328 static const int64 kNoSuchResponseId = 123;
329
330 void ReadNonExistentResponse() {
331 // 1. Attempt to ReadInfo
332 // 2. Attempt to ReadData
333
334 reader_.reset(service_->storage()->CreateResponseReader(
335 GURL(), kNoSuchResponseId));
336
337 // Push tasks in reverse order
338 PushNextTask(method_factory_.NewRunnableMethod(
339 &AppCacheResponseTest::ReadNonExistentData));
340 PushNextTask(method_factory_.NewRunnableMethod(
341 &AppCacheResponseTest::ReadNonExistentInfo));
342 ScheduleNextTask();
343 }
344
345 void ReadNonExistentInfo() {
346 EXPECT_FALSE(reader_->IsReadPending());
347 read_info_buffer_ = new HttpResponseInfoIOBuffer();
348 reader_->ReadInfo(read_info_buffer_, &read_info_callback_);
349 EXPECT_TRUE(reader_->IsReadPending());
350 expected_read_result_ = net::ERR_CACHE_MISS;
351 }
352
353 void ReadNonExistentData() {
354 EXPECT_FALSE(reader_->IsReadPending());
355 read_buffer_ = new IOBuffer(kBlockSize);
356 reader_->ReadData(read_buffer_, kBlockSize, &read_callback_);
357 EXPECT_TRUE(reader_->IsReadPending());
358 expected_read_result_ = net::ERR_CACHE_MISS;
359 }
360
361 // LoadResponseInfo_Miss ----------------------------------------------------
362 void LoadResponseInfo_Miss() {
363 PushNextTask(method_factory_.NewRunnableMethod(
364 &AppCacheResponseTest::LoadResponseInfo_Miss_Verify));
365 service_->storage()->LoadResponseInfo(GURL(), kNoSuchResponseId,
366 storage_delegate_.get());
367 }
368
369 void LoadResponseInfo_Miss_Verify() {
370 EXPECT_EQ(kNoSuchResponseId, storage_delegate_->loaded_info_id_);
371 EXPECT_TRUE(!storage_delegate_->loaded_info_.get());
372 TestFinished();
373 }
374
375 // LoadResponseInfo_Hit ----------------------------------------------------
376 void LoadResponseInfo_Hit() {
377 // This tests involves multiple async steps.
378 // 1. Write a response headers and body to storage
379 // a. headers
380 // b. body
381 // 2. Use LoadResponseInfo to read the response headers back out
382 PushNextTask(method_factory_.NewRunnableMethod(
383 &AppCacheResponseTest::LoadResponseInfo_Hit_Step2));
384 writer_.reset(service_->storage()->CreateResponseWriter(GURL()));
385 written_response_id_ = writer_->response_id();
386 WriteBasicResponse();
387 }
388
389 void LoadResponseInfo_Hit_Step2() {
390 writer_.reset();
391 PushNextTask(method_factory_.NewRunnableMethod(
392 &AppCacheResponseTest::LoadResponseInfo_Hit_Verify));
393 service_->storage()->LoadResponseInfo(GURL(), written_response_id_,
394 storage_delegate_.get());
395 }
396
397 void LoadResponseInfo_Hit_Verify() {
398 EXPECT_EQ(written_response_id_, storage_delegate_->loaded_info_id_);
399 EXPECT_TRUE(storage_delegate_->loaded_info_.get());
400 EXPECT_TRUE(CompareHttpResponseInfos(
401 write_info_buffer_->http_info.get(),
402 storage_delegate_->loaded_info_->http_response_info()));
403 TestFinished();
404 }
405
406 // WriteThenVariouslyReadResponse -------------------------------------------
407 static const int kNumBlocks = 4;
408 static const int kBlockSize = 1024;
409
410 void WriteThenVariouslyReadResponse() {
411 // This tests involves multiple async steps.
412 // 1. First, write a large body using multiple writes, we don't bother
413 // with a response head for this test.
414 // 2. Read the entire body, using multiple reads
415 // 3. Read the entire body, using one read.
416 // 4. Attempt to read beyond the EOF.
417 // 5. Read just a range.
418 // 6. Attempt to read beyond EOF of a range.
419
420 // Push tasks in reverse order
421 PushNextTask(method_factory_.NewRunnableMethod(
422 &AppCacheResponseTest::ReadRangeFullyBeyondEOF));
423 PushNextTask(method_factory_.NewRunnableMethod(
424 &AppCacheResponseTest::ReadRangePartiallyBeyondEOF));
425 PushNextTask(method_factory_.NewRunnableMethod(
426 &AppCacheResponseTest::ReadPastEOF));
427 PushNextTask(method_factory_.NewRunnableMethod(
428 &AppCacheResponseTest::ReadRange));
429 PushNextTask(method_factory_.NewRunnableMethod(
430 &AppCacheResponseTest::ReadPastEOF));
431 PushNextTask(method_factory_.NewRunnableMethod(
432 &AppCacheResponseTest::ReadAllAtOnce));
433 PushNextTask(method_factory_.NewRunnableMethod(
434 &AppCacheResponseTest::ReadInBlocks));
435 PushNextTask(method_factory_.NewRunnableMethod(
436 &AppCacheResponseTest::WriteOutBlocks));
437
438 // Get them going.
439 ScheduleNextTask();
440 }
441
442 void WriteOutBlocks() {
443 writer_.reset(service_->storage()->CreateResponseWriter(GURL()));
444 written_response_id_ = writer_->response_id();
445 for (int i = 0; i < kNumBlocks; ++i) {
446 PushNextTask(method_factory_.NewRunnableMethod(
447 &AppCacheResponseTest::WriteOneBlock, kNumBlocks - i));
448 }
449 ScheduleNextTask();
450 }
451
452 void WriteOneBlock(int block_number) {
453 scoped_refptr<IOBuffer> io_buffer =
454 new IOBuffer(kBlockSize);
455 FillData(block_number, io_buffer->data(), kBlockSize);
456 WriteResponseBody(io_buffer, kBlockSize);
457 }
458
459 void ReadInBlocks() {
460 writer_.reset();
461 reader_.reset(service_->storage()->CreateResponseReader(
462 GURL(), written_response_id_));
463 for (int i = 0; i < kNumBlocks; ++i) {
464 PushNextTask(method_factory_.NewRunnableMethod(
465 &AppCacheResponseTest::ReadOneBlock, kNumBlocks - i));
466 }
467 ScheduleNextTask();
468 }
469
470 void ReadOneBlock(int block_number) {
471 PushNextTask(method_factory_.NewRunnableMethod(
472 &AppCacheResponseTest::VerifyOneBlock, block_number));
473 ReadResponseBody(new IOBuffer(kBlockSize), kBlockSize);
474 }
475
476 void VerifyOneBlock(int block_number) {
477 EXPECT_TRUE(CheckData(block_number, read_buffer_->data(), kBlockSize));
478 ScheduleNextTask();
479 }
480
481 void ReadAllAtOnce() {
482 PushNextTask(method_factory_.NewRunnableMethod(
483 &AppCacheResponseTest::VerifyAllAtOnce));
484 reader_.reset(service_->storage()->CreateResponseReader(
485 GURL(), written_response_id_));
486 int big_size = kNumBlocks * kBlockSize;
487 ReadResponseBody(new IOBuffer(big_size), big_size);
488 }
489
490 void VerifyAllAtOnce() {
491 char* p = read_buffer_->data();
492 for (int i = 0; i < kNumBlocks; ++i, p += kBlockSize)
493 EXPECT_TRUE(CheckData(i + 1, p, kBlockSize));
494 ScheduleNextTask();
495 }
496
497 void ReadPastEOF() {
498 EXPECT_FALSE(reader_->IsReadPending());
499 read_buffer_ = new IOBuffer(kBlockSize);
500 expected_read_result_ = 0;
501 reader_->ReadData(
502 read_buffer_, kBlockSize, &read_callback_);
503 }
504
505 void ReadRange() {
506 PushNextTask(method_factory_.NewRunnableMethod(
507 &AppCacheResponseTest::VerifyRange));
508 reader_.reset(service_->storage()->CreateResponseReader(
509 GURL(), written_response_id_));
510 reader_->SetReadRange(kBlockSize, kBlockSize);
511 ReadResponseBody(new IOBuffer(kBlockSize), kBlockSize);
512 }
513
514 void VerifyRange() {
515 EXPECT_TRUE(CheckData(2, read_buffer_->data(), kBlockSize));
516 ScheduleNextTask(); // ReadPastEOF is scheduled next
517 }
518
519 void ReadRangePartiallyBeyondEOF() {
520 PushNextTask(method_factory_.NewRunnableMethod(
521 &AppCacheResponseTest::VerifyRangeBeyondEOF));
522 reader_.reset(service_->storage()->CreateResponseReader(
523 GURL(), written_response_id_));
524 reader_->SetReadRange(kBlockSize, kNumBlocks * kBlockSize);
525 ReadResponseBody(new IOBuffer(kNumBlocks * kBlockSize),
526 kNumBlocks * kBlockSize);
527 expected_read_result_ = (kNumBlocks - 1) * kBlockSize;
528 }
529
530 void VerifyRangeBeyondEOF() {
531 // Just verify the first 1k
532 VerifyRange();
533 }
534
535 void ReadRangeFullyBeyondEOF() {
536 reader_.reset(service_->storage()->CreateResponseReader(
537 GURL(), written_response_id_));
538 reader_->SetReadRange((kNumBlocks * kBlockSize) + 1, kBlockSize);
539 ReadResponseBody(new IOBuffer(kBlockSize), kBlockSize);
540 expected_read_result_ = 0;
541 }
542
543 // IOChaining -------------------------------------------
544 void IOChaining() {
545 // 1. Write several blocks out initiating the subsequent write
546 // from within the completion callback of the previous write.
547 // 2. Read and verify several blocks in similarly chaining reads.
548
549 // Push tasks in reverse order
550 PushNextTaskAsImmediate(method_factory_.NewRunnableMethod(
551 &AppCacheResponseTest::ReadInBlocksImmediately));
552 PushNextTaskAsImmediate(method_factory_.NewRunnableMethod(
553 &AppCacheResponseTest::WriteOutBlocksImmediately));
554
555 // Get them going.
556 ScheduleNextTask();
557 }
558
559 void WriteOutBlocksImmediately() {
560 writer_.reset(service_->storage()->CreateResponseWriter(GURL()));
561 written_response_id_ = writer_->response_id();
562 for (int i = 0; i < kNumBlocks; ++i) {
563 PushNextTaskAsImmediate(method_factory_.NewRunnableMethod(
564 &AppCacheResponseTest::WriteOneBlock, kNumBlocks - i));
565 }
566 ScheduleNextTask();
567 }
568
569 void ReadInBlocksImmediately() {
570 writer_.reset();
571 reader_.reset(service_->storage()->CreateResponseReader(
572 GURL(), written_response_id_));
573 for (int i = 0; i < kNumBlocks; ++i) {
574 PushNextTaskAsImmediate(method_factory_.NewRunnableMethod(
575 &AppCacheResponseTest::ReadOneBlockImmediately, kNumBlocks - i));
576 }
577 ScheduleNextTask();
578 }
579
580 void ReadOneBlockImmediately(int block_number) {
581 PushNextTaskAsImmediate(method_factory_.NewRunnableMethod(
582 &AppCacheResponseTest::VerifyOneBlock, block_number));
583 ReadResponseBody(new IOBuffer(kBlockSize), kBlockSize);
584 }
585
586 // DeleteWithinCallbacks -------------------------------------------
587 void DeleteWithinCallbacks() {
588 // 1. Write out a few blocks normally, and upon
589 // completion of the last write, delete the writer.
590 // 2. Read in a few blocks normally, and upon completion
591 // of the last read, delete the reader.
592
593 should_delete_reader_in_completion_callback_ = true;
594 reader_deletion_count_down_ = kNumBlocks;
595 should_delete_writer_in_completion_callback_ = true;
596 writer_deletion_count_down_ = kNumBlocks;
597
598 PushNextTask(method_factory_.NewRunnableMethod(
599 &AppCacheResponseTest::ReadInBlocks));
600 PushNextTask(method_factory_.NewRunnableMethod(
601 &AppCacheResponseTest::WriteOutBlocks));
602 ScheduleNextTask();
603 }
604
605 // DeleteWithIOPending -------------------------------------------
606 void DeleteWithIOPending() {
607 // 1. Write a few blocks normally.
608 // 2. Start a write, delete with it pending.
609 // 3. Start a read, delete with it pending.
610 PushNextTask(method_factory_.NewRunnableMethod(
611 &AppCacheResponseTest::ReadThenDelete));
612 PushNextTask(method_factory_.NewRunnableMethod(
613 &AppCacheResponseTest::WriteThenDelete));
614 PushNextTask(method_factory_.NewRunnableMethod(
615 &AppCacheResponseTest::WriteOutBlocks));
616 ScheduleNextTask();
617 }
618
619 void WriteThenDelete() {
620 write_callback_was_called_ = false;
621 WriteOneBlock(5);
622 EXPECT_TRUE(writer_->IsWritePending());
623 writer_.reset();
624 ScheduleNextTask();
625 }
626
627 void ReadThenDelete() {
628 read_callback_was_called_ = false;
629 reader_.reset(service_->storage()->CreateResponseReader(
630 GURL(), written_response_id_));
631 ReadResponseBody(new IOBuffer(kBlockSize), kBlockSize);
632 EXPECT_TRUE(reader_->IsReadPending());
633 reader_.reset();
634
635 // wait a moment to verify no callbacks
rvargas (doing something else) 2009/10/21 17:40:59 nit: Capitalize wait and end with period.
636 MessageLoop::current()->PostDelayedTask(FROM_HERE,
637 method_factory_.NewRunnableMethod(
638 &AppCacheResponseTest::VerifyNoCallbacks),
639 10);
640 }
641
642 void VerifyNoCallbacks() {
643 EXPECT_TRUE(!write_callback_was_called_);
644 EXPECT_TRUE(!read_callback_was_called_);
645 TestFinished();
646 }
647
648 // Data members
649
650 ScopedRunnableMethodFactory<AppCacheResponseTest> method_factory_;
651 scoped_ptr<base::WaitableEvent> test_finished_event_;
652 scoped_ptr<MockStorageDelegate> storage_delegate_;
653 scoped_ptr<MockAppCacheService> service_;
654 std::stack<std::pair<Task*, bool> > task_stack_;
655
656 scoped_ptr<AppCacheResponseReader> reader_;
657 scoped_refptr<HttpResponseInfoIOBuffer> read_info_buffer_;
658 scoped_refptr<IOBuffer> read_buffer_;
659 int expected_read_result_;
660 net::CompletionCallbackImpl<AppCacheResponseTest> read_callback_;
661 net::CompletionCallbackImpl<AppCacheResponseTest> read_info_callback_;
662 bool should_delete_reader_in_completion_callback_;
663 int reader_deletion_count_down_;
664 bool read_callback_was_called_;
665
666 int64 written_response_id_;
667 scoped_ptr<AppCacheResponseWriter> writer_;
668 scoped_refptr<HttpResponseInfoIOBuffer> write_info_buffer_;
669 scoped_refptr<IOBuffer> write_buffer_;
670 int expected_write_result_;
671 net::CompletionCallbackImpl<AppCacheResponseTest> write_callback_;
672 net::CompletionCallbackImpl<AppCacheResponseTest> write_info_callback_;
673 bool should_delete_writer_in_completion_callback_;
674 int writer_deletion_count_down_;
675 bool write_callback_was_called_;
676
677 static scoped_ptr<base::Thread> io_thread_;
678 };
679
680 // static
681 scoped_ptr<base::Thread> AppCacheResponseTest::io_thread_;
682
683 TEST_F(AppCacheResponseTest, DelegateReferences) {
684 RunTestOnIOThread(&AppCacheResponseTest::DelegateReferences);
685 }
686
687 TEST_F(AppCacheResponseTest, ReadNonExistentResponse) {
688 RunTestOnIOThread(&AppCacheResponseTest::ReadNonExistentResponse);
689 }
690
691 TEST_F(AppCacheResponseTest, LoadResponseInfo_Miss) {
692 RunTestOnIOThread(&AppCacheResponseTest::LoadResponseInfo_Miss);
693 }
694
695 TEST_F(AppCacheResponseTest, LoadResponseInfo_Hit) {
696 RunTestOnIOThread(&AppCacheResponseTest::LoadResponseInfo_Hit);
697 }
698
699 TEST_F(AppCacheResponseTest, WriteThenVariouslyReadResponse) {
700 RunTestOnIOThread(&AppCacheResponseTest::WriteThenVariouslyReadResponse);
701 }
702
703 TEST_F(AppCacheResponseTest, IOChaining) {
704 RunTestOnIOThread(&AppCacheResponseTest::IOChaining);
705 }
706
707 TEST_F(AppCacheResponseTest, DeleteWithinCallbacks) {
708 RunTestOnIOThread(&AppCacheResponseTest::DeleteWithinCallbacks);
709 }
710
711 TEST_F(AppCacheResponseTest, DeleteWithIOPending) {
712 RunTestOnIOThread(&AppCacheResponseTest::DeleteWithIOPending);
713 }
714
715 } // namespace appcache
716
OLDNEW
« no previous file with comments | « webkit/appcache/appcache_response.cc ('k') | webkit/appcache/appcache_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698