diff options
author | michaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-09 00:09:21 +0000 |
---|---|---|
committer | michaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-09 00:09:21 +0000 |
commit | 3367fc1dd134eeaf9ab6e62397f05ad3964319fe (patch) | |
tree | 78fb4d7ac912bbaf47b64f0aaefef331906b5fca /webkit/appcache/appcache_url_request_job_unittest.cc | |
parent | 9f9e1fcbbd52267fa657b3b0b80ece683ceb6dd6 (diff) | |
download | chromium_src-3367fc1dd134eeaf9ab6e62397f05ad3964319fe.zip chromium_src-3367fc1dd134eeaf9ab6e62397f05ad3964319fe.tar.gz chromium_src-3367fc1dd134eeaf9ab6e62397f05ad3964319fe.tar.bz2 |
AppCache changes to the networking model. Added new classes AppCacheRequestHandler and AppCacheURLRequestJob.
TEST=appcache_url_request_job_unittest.cc, appcache_request_handler_unittest.cc
BUG=none
Review URL: http://codereview.chromium.org/338034
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31411 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/appcache/appcache_url_request_job_unittest.cc')
-rw-r--r-- | webkit/appcache/appcache_url_request_job_unittest.cc | 745 |
1 files changed, 745 insertions, 0 deletions
diff --git a/webkit/appcache/appcache_url_request_job_unittest.cc b/webkit/appcache/appcache_url_request_job_unittest.cc new file mode 100644 index 0000000..b7b452f --- /dev/null +++ b/webkit/appcache/appcache_url_request_job_unittest.cc @@ -0,0 +1,745 @@ +// Copyright (c) 2009 The Chromium Authos. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/compiler_specific.h" +#include "base/pickle.h" +#include "base/thread.h" +#include "base/waitable_event.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_error_job.h" +#include "net/base/io_buffer.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webkit/appcache/appcache_response.h" +#include "webkit/appcache/appcache_url_request_job.h" +#include "webkit/appcache/mock_appcache_service.h" + +using net::IOBuffer; +using net::WrappedIOBuffer; + +namespace appcache { + +static const char kHttpBasicHeaders[] = + "HTTP/1.0 200 OK\0Content-Length: 5\0\0"; +static const char kHttpBasicBody[] = "Hello"; + +static const int kNumBlocks = 4; +static const int kBlockSize = 1024; +static const int kNoSuchResponseId = 123; + +class AppCacheURLRequestJobTest : public testing::Test { + public: + + // Test Harness ------------------------------------------------------------- + // TODO(michaeln): share this test harness with AppCacheResponseTest + + class MockStorageDelegate : public AppCacheStorage::Delegate { + public: + explicit MockStorageDelegate(AppCacheURLRequestJobTest* test) + : loaded_info_id_(0), test_(test) { + } + + virtual void OnResponseInfoLoaded(AppCacheResponseInfo* info, + int64 response_id) { + loaded_info_ = info; + loaded_info_id_ = response_id; + test_->ScheduleNextTask(); + } + + scoped_refptr<AppCacheResponseInfo> loaded_info_; + int64 loaded_info_id_; + AppCacheURLRequestJobTest* test_; + }; + + class MockURLRequestDelegate : public URLRequest::Delegate { + public: + explicit MockURLRequestDelegate(AppCacheURLRequestJobTest* test) + : test_(test), + received_data_(new net::IOBuffer(kNumBlocks * kBlockSize)), + did_receive_headers_(false), amount_received_(0), + kill_after_amount_received_(0), kill_with_io_pending_(false) { + } + + virtual void OnResponseStarted(URLRequest* request) { + amount_received_ = 0; + did_receive_headers_ = false; + if (request->status().is_success()) { + EXPECT_TRUE(request->response_headers()); + did_receive_headers_ = true; + received_info_ = request->response_info(); + ReadSome(request); + } else { + RequestComplete(); + } + } + + virtual void OnReadCompleted(URLRequest* request, int bytes_read) { + if (bytes_read > 0) { + amount_received_ += bytes_read; + + if (kill_after_amount_received_ && !kill_with_io_pending_) { + if (amount_received_ >= kill_after_amount_received_) { + request->Cancel(); + return; + } + } + + ReadSome(request); + + if (kill_after_amount_received_ && kill_with_io_pending_) { + if (amount_received_ >= kill_after_amount_received_) { + request->Cancel(); + return; + } + } + } else { + RequestComplete(); + } + } + + void ReadSome(URLRequest* request) { + DCHECK(amount_received_ + kBlockSize <= kNumBlocks * kBlockSize); + scoped_refptr<IOBuffer> wrapped_buffer = + new net::WrappedIOBuffer(received_data_->data() + amount_received_); + int bytes_read = 0; + EXPECT_FALSE(request->Read(wrapped_buffer, kBlockSize, &bytes_read)); + EXPECT_EQ(0, bytes_read); + } + + void RequestComplete() { + test_->ScheduleNextTask(); + } + + AppCacheURLRequestJobTest* test_; + net::HttpResponseInfo received_info_; + scoped_refptr<net::IOBuffer> received_data_; + bool did_receive_headers_; + int amount_received_; + int kill_after_amount_received_; + bool kill_with_io_pending_; + }; + + static URLRequestJob* MockHttpJobFactory(URLRequest* request, + const std::string& scheme) { + if (mock_factory_job_) { + URLRequestJob* temp = mock_factory_job_; + mock_factory_job_ = NULL; + return temp; + } else { + return new URLRequestErrorJob(request, net::ERR_INTERNET_DISCONNECTED); + } + } + + // Helper class run a test on our io_thread. The io_thread + // is spun up once and reused for all tests. + template <class Method> + class WrapperTask : public Task { + public: + WrapperTask(AppCacheURLRequestJobTest* test, Method method) + : test_(test), method_(method) { + } + + virtual void Run() { + test_->SetUpTest(); + (test_->*method_)(); + } + + private: + AppCacheURLRequestJobTest* test_; + Method method_; + }; + + static void SetUpTestCase() { + io_thread_.reset(new base::Thread("AppCacheURLRequestJobTest Thread")); + base::Thread::Options options(MessageLoop::TYPE_IO, 0); + io_thread_->StartWithOptions(options); + } + + static void TearDownTestCase() { + io_thread_.reset(NULL); + } + + AppCacheURLRequestJobTest() + : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), + ALLOW_THIS_IN_INITIALIZER_LIST(read_callback_( + this, &AppCacheURLRequestJobTest::OnReadComplete)), + ALLOW_THIS_IN_INITIALIZER_LIST(read_info_callback_( + this, &AppCacheURLRequestJobTest::OnReadInfoComplete)), + ALLOW_THIS_IN_INITIALIZER_LIST(write_callback_( + this, &AppCacheURLRequestJobTest::OnWriteComplete)), + ALLOW_THIS_IN_INITIALIZER_LIST(write_info_callback_( + this, &AppCacheURLRequestJobTest::OnWriteInfoComplete)) { + } + + template <class Method> + void RunTestOnIOThread(Method method) { + test_finished_event_ .reset(new base::WaitableEvent(false, false)); + io_thread_->message_loop()->PostTask( + FROM_HERE, new WrapperTask<Method>(this, method)); + test_finished_event_->Wait(); + } + + void SetUpTest() { + DCHECK(MessageLoop::current() == io_thread_->message_loop()); + DCHECK(task_stack_.empty()); + orig_http_factory_ = URLRequest::RegisterProtocolFactory( + "http", MockHttpJobFactory); + url_request_delegate_.reset(new MockURLRequestDelegate(this)); + storage_delegate_.reset(new MockStorageDelegate(this)); + service_.reset(new MockAppCacheService()); + expected_read_result_ = 0; + expected_write_result_ = 0; + written_response_id_ = 0; + should_delete_reader_in_completion_callback_ = false; + should_delete_writer_in_completion_callback_ = false; + reader_deletion_count_down_ = 0; + writer_deletion_count_down_ = 0; + read_callback_was_called_ = false; + write_callback_was_called_ = false; + } + + void TearDownTest() { + DCHECK(MessageLoop::current() == io_thread_->message_loop()); + URLRequest::RegisterProtocolFactory("http", orig_http_factory_); + orig_http_factory_ = NULL; + request_.reset(); + url_request_delegate_.reset(); + DCHECK(!mock_factory_job_); + + while (!task_stack_.empty()) { + delete task_stack_.top().first; + task_stack_.pop(); + } + reader_.reset(); + read_buffer_ = NULL; + read_info_buffer_ = NULL; + writer_.reset(); + write_buffer_ = NULL; + write_info_buffer_ = NULL; + storage_delegate_.reset(); + service_.reset(); + } + + void TestFinished() { + // We unwind the stack prior to finishing up to let stack + // based objects get deleted. + DCHECK(MessageLoop::current() == io_thread_->message_loop()); + MessageLoop::current()->PostTask(FROM_HERE, + method_factory_.NewRunnableMethod( + &AppCacheURLRequestJobTest::TestFinishedUnwound)); + } + + void TestFinishedUnwound() { + TearDownTest(); + test_finished_event_->Signal(); + } + + void PushNextTask(Task* task) { + task_stack_.push(std::pair<Task*, bool>(task, false)); + } + + void PushNextTaskAsImmediate(Task* task) { + task_stack_.push(std::pair<Task*, bool>(task, true)); + } + + void ScheduleNextTask() { + DCHECK(MessageLoop::current() == io_thread_->message_loop()); + if (task_stack_.empty()) { + TestFinished(); + return; + } + scoped_ptr<Task> task(task_stack_.top().first); + bool immediate = task_stack_.top().second; + task_stack_.pop(); + if (immediate) + task->Run(); + else + MessageLoop::current()->PostTask(FROM_HERE, task.release()); + } + + // Wrappers to call AppCacheResponseReader/Writer Read and Write methods + + void WriteBasicResponse() { + scoped_refptr<IOBuffer> body = new WrappedIOBuffer(kHttpBasicBody); + std::string raw_headers(kHttpBasicHeaders, arraysize(kHttpBasicHeaders)); + WriteResponse(MakeHttpResponseInfo(raw_headers), body, + strlen(kHttpBasicBody)); + } + + void WriteResponse(net::HttpResponseInfo* head, + IOBuffer* body, int body_len) { + DCHECK(body); + scoped_refptr<IOBuffer> body_ref(body); + PushNextTask(method_factory_.NewRunnableMethod( + &AppCacheURLRequestJobTest::WriteResponseBody, + body_ref, body_len)); + WriteResponseHead(head); + } + + void WriteResponseHead(net::HttpResponseInfo* head) { + EXPECT_FALSE(writer_->IsWritePending()); + expected_write_result_ = GetHttpResponseInfoSize(head); + write_info_buffer_ = new HttpResponseInfoIOBuffer(head); + writer_->WriteInfo(write_info_buffer_, &write_info_callback_); + } + + void WriteResponseBody(scoped_refptr<IOBuffer> io_buffer, int buf_len) { + EXPECT_FALSE(writer_->IsWritePending()); + write_buffer_ = io_buffer; + expected_write_result_ = buf_len; + writer_->WriteData( + write_buffer_, buf_len, &write_callback_); + } + + void ReadResponseBody(scoped_refptr<IOBuffer> io_buffer, int buf_len) { + EXPECT_FALSE(reader_->IsReadPending()); + read_buffer_ = io_buffer; + expected_read_result_ = buf_len; + reader_->ReadData( + read_buffer_, buf_len, &read_callback_); + } + + // AppCacheResponseReader / Writer completion callbacks + + void OnWriteInfoComplete(int result) { + EXPECT_FALSE(writer_->IsWritePending()); + EXPECT_EQ(expected_write_result_, result); + ScheduleNextTask(); + } + + void OnWriteComplete(int result) { + EXPECT_FALSE(writer_->IsWritePending()); + write_callback_was_called_ = true; + EXPECT_EQ(expected_write_result_, result); + if (should_delete_writer_in_completion_callback_ && + --writer_deletion_count_down_ == 0) { + writer_.reset(); + } + ScheduleNextTask(); + } + + void OnReadInfoComplete(int result) { + EXPECT_FALSE(reader_->IsReadPending()); + EXPECT_EQ(expected_read_result_, result); + ScheduleNextTask(); + } + + void OnReadComplete(int result) { + EXPECT_FALSE(reader_->IsReadPending()); + read_callback_was_called_ = true; + EXPECT_EQ(expected_read_result_, result); + if (should_delete_reader_in_completion_callback_ && + --reader_deletion_count_down_ == 0) { + reader_.reset(); + } + ScheduleNextTask(); + } + + // Helpers to work with HttpResponseInfo objects + + net::HttpResponseInfo* MakeHttpResponseInfo(const std::string& raw_headers) { + net::HttpResponseInfo* info = new net::HttpResponseInfo; + info->request_time = base::Time::Now(); + info->response_time = base::Time::Now(); + info->was_cached = false; + info->headers = new net::HttpResponseHeaders(raw_headers); + return info; + } + + int GetHttpResponseInfoSize(const net::HttpResponseInfo* info) { + Pickle pickle; + return PickleHttpResonseInfo(&pickle, info); + } + + bool CompareHttpResponseInfos(const net::HttpResponseInfo* info1, + const net::HttpResponseInfo* info2) { + Pickle pickle1; + Pickle pickle2; + PickleHttpResonseInfo(&pickle1, info1); + PickleHttpResonseInfo(&pickle2, info2); + return (pickle1.size() == pickle2.size()) && + (0 == memcmp(pickle1.data(), pickle2.data(), pickle1.size())); + } + + int PickleHttpResonseInfo(Pickle* pickle, const net::HttpResponseInfo* info) { + const bool kSkipTransientHeaders = true; + const bool kTruncated = false; + info->Persist(pickle, kSkipTransientHeaders, kTruncated); + return pickle->size(); + } + + // Helpers to fill and verify blocks of memory with a value + + void FillData(char value, char* data, int data_len) { + memset(data, value, data_len); + } + + bool CheckData(char value, const char* data, int data_len) { + for (int i = 0; i < data_len; ++i, ++data) { + if (*data != value) + return false; + } + return true; + } + + // Individual Tests --------------------------------------------------------- + // Some of the individual tests involve multiple async steps. Each test + // is delineated with a section header. + + // Basic ------------------------------------------------------------------- + void Basic() { + AppCacheStorage* storage = service_->storage(); + URLRequest request(GURL("http://blah/"), NULL); + scoped_refptr<AppCacheURLRequestJob> job; + + // Create an instance and see that it looks as expected. + + job = new AppCacheURLRequestJob(&request, storage); + EXPECT_TRUE(job->is_waiting()); + EXPECT_FALSE(job->is_delivering_appcache_response()); + EXPECT_FALSE(job->is_delivering_network_response()); + EXPECT_FALSE(job->is_delivering_error_response()); + EXPECT_FALSE(job->has_been_started()); + EXPECT_FALSE(job->has_been_killed()); + EXPECT_EQ(GURL::EmptyGURL(), job->manifest_url()); + EXPECT_EQ(kNoCacheId, job->cache_id()); + EXPECT_FALSE(job->entry().has_response_id()); + + TestFinished(); + } + + // DeliveryOrders ----------------------------------------------------- + void DeliveryOrders() { + AppCacheStorage* storage = service_->storage(); + URLRequest request(GURL("http://blah/"), NULL); + scoped_refptr<AppCacheURLRequestJob> job; + + // Create an instance, give it a delivery order and see that + // it looks as expected. + + job = new AppCacheURLRequestJob(&request, storage); + job->DeliverErrorResponse(); + EXPECT_TRUE(job->is_delivering_error_response()); + EXPECT_FALSE(job->has_been_started()); + + job = new AppCacheURLRequestJob(&request, storage); + job->DeliverNetworkResponse(); + EXPECT_TRUE(job->is_delivering_network_response()); + EXPECT_FALSE(job->has_been_started()); + + job = new AppCacheURLRequestJob(&request, storage); + const GURL kManifestUrl("http://blah/"); + const int64 kCacheId(1); + const AppCacheEntry kEntry(AppCacheEntry::EXPLICIT, 1); + job->DeliverAppCachedResponse(kManifestUrl, kCacheId, kEntry); + EXPECT_FALSE(job->is_waiting()); + EXPECT_TRUE(job->is_delivering_appcache_response()); + EXPECT_FALSE(job->has_been_started()); + EXPECT_EQ(kManifestUrl, job->manifest_url()); + EXPECT_EQ(kCacheId, job->cache_id()); + EXPECT_EQ(kEntry.types(), job->entry().types()); + EXPECT_EQ(kEntry.response_id(), job->entry().response_id()); + + TestFinished(); + } + + // DeliverNetworkResponse -------------------------------------------------- + + void DeliverNetworkResponse() { + // This test has async steps. + PushNextTask(method_factory_.NewRunnableMethod( + &AppCacheURLRequestJobTest::VerifyDeliverNetworkResponse)); + + AppCacheStorage* storage = service_->storage(); + request_.reset( + new URLRequest(GURL("http://blah/"), url_request_delegate_.get())); + + // Setup to create an AppCacheURLRequestJob with orders to deliver + // a network response. + mock_factory_job_ = new AppCacheURLRequestJob(request_.get(), storage); + mock_factory_job_->DeliverNetworkResponse(); + EXPECT_TRUE(mock_factory_job_->is_delivering_network_response()); + EXPECT_FALSE(mock_factory_job_->has_been_started()); + + // Start the request. + request_->Start(); + + // The job should have been picked up. + EXPECT_FALSE(mock_factory_job_); + // Completion is async. + } + + void VerifyDeliverNetworkResponse() { + EXPECT_EQ(request_->status().os_error(), + net::ERR_INTERNET_DISCONNECTED); + TestFinished(); + } + + // DeliverErrorResponse -------------------------------------------------- + + void DeliverErrorResponse() { + // This test has async steps. + PushNextTask(method_factory_.NewRunnableMethod( + &AppCacheURLRequestJobTest::VerifyDeliverErrorResponse)); + + AppCacheStorage* storage = service_->storage(); + request_.reset( + new URLRequest(GURL("http://blah/"), url_request_delegate_.get())); + + // Setup to create an AppCacheURLRequestJob with orders to deliver + // a network response. + mock_factory_job_ = new AppCacheURLRequestJob(request_.get(), storage); + mock_factory_job_->DeliverErrorResponse(); + EXPECT_TRUE(mock_factory_job_->is_delivering_error_response()); + EXPECT_FALSE(mock_factory_job_->has_been_started()); + + // Start the request. + request_->Start(); + + // The job should have been picked up. + EXPECT_FALSE(mock_factory_job_); + // Completion is async. + } + + void VerifyDeliverErrorResponse() { + EXPECT_EQ(request_->status().os_error(), net::ERR_FAILED); + TestFinished(); + } + + // DeliverSmallAppCachedResponse -------------------------------------- + // "Small" being small enough to read completely in a single + // request->Read call. + + void DeliverSmallAppCachedResponse() { + // This test has several async steps. + // 1. Write a small response to response storage. + // 2. Use URLRequest to retrieve it. + // 3. Verify we received what we expected to receive. + + PushNextTask(method_factory_.NewRunnableMethod( + &AppCacheURLRequestJobTest::VerifyDeliverSmallAppCachedResponse)); + PushNextTask(method_factory_.NewRunnableMethod( + &AppCacheURLRequestJobTest::RequestAppCachedResource, false)); + + writer_.reset(service_->storage()->CreateResponseWriter(GURL())); + written_response_id_ = writer_->response_id(); + WriteBasicResponse(); + // Continues async + } + + void RequestAppCachedResource(bool start_after_delivery_orders) { + AppCacheStorage* storage = service_->storage(); + request_.reset( + new URLRequest(GURL("http://blah/"), url_request_delegate_.get())); + + // Setup to create an AppCacheURLRequestJob with orders to deliver + // a network response. + scoped_refptr<AppCacheURLRequestJob> job( + new AppCacheURLRequestJob(request_.get(), storage)); + + if (start_after_delivery_orders) { + job->DeliverAppCachedResponse( + GURL(), 111, + AppCacheEntry(AppCacheEntry::EXPLICIT, written_response_id_)); + EXPECT_TRUE(job->is_delivering_appcache_response()); + } + + // Start the request. + EXPECT_FALSE(job->has_been_started()); + mock_factory_job_ = job; + request_->Start(); + EXPECT_FALSE(mock_factory_job_); + EXPECT_TRUE(job->has_been_started()); + + if (!start_after_delivery_orders) { + job->DeliverAppCachedResponse( + GURL(), 111, + AppCacheEntry(AppCacheEntry::EXPLICIT, written_response_id_)); + EXPECT_TRUE(job->is_delivering_appcache_response()); + } + + // Completion is async. + } + + void VerifyDeliverSmallAppCachedResponse() { + EXPECT_TRUE(request_->status().is_success()); + EXPECT_TRUE(CompareHttpResponseInfos( + write_info_buffer_->http_info.get(), + &url_request_delegate_->received_info_)); + EXPECT_EQ(5, url_request_delegate_->amount_received_); + EXPECT_EQ(0, memcmp(kHttpBasicBody, + url_request_delegate_->received_data_->data(), + strlen(kHttpBasicBody))); + TestFinished(); + } + + // DeliverLargeAppCachedResponse -------------------------------------- + // "Large" enough to require multiple calls to request->Read to complete. + + void DeliverLargeAppCachedResponse() { + // This test has several async steps. + // 1. Write a large response to response storage. + // 2. Use URLRequest to retrieve it. + // 3. Verify we received what we expected to receive. + + PushNextTask(method_factory_.NewRunnableMethod( + &AppCacheURLRequestJobTest::VerifyDeliverLargeAppCachedResponse)); + PushNextTask(method_factory_.NewRunnableMethod( + &AppCacheURLRequestJobTest::RequestAppCachedResource, true)); + + writer_.reset(service_->storage()->CreateResponseWriter(GURL())); + written_response_id_ = writer_->response_id(); + WriteLargeResponse(); + // Continues async + } + + void WriteLargeResponse() { + // 3, 1k blocks + static const char kHttpHeaders[] = + "HTTP/1.0 200 OK\0Content-Length: 3072\0\0"; + scoped_refptr<IOBuffer> body = new IOBuffer(kBlockSize * 3); + char* p = body->data(); + for (int i = 0; i < 3; ++i, p += kBlockSize) + FillData(i + 1, p, kBlockSize); + std::string raw_headers(kHttpHeaders, arraysize(kHttpHeaders)); + WriteResponse(MakeHttpResponseInfo(raw_headers), body, kBlockSize * 3); + } + + void VerifyDeliverLargeAppCachedResponse() { + EXPECT_TRUE(request_->status().is_success()); + EXPECT_TRUE(CompareHttpResponseInfos( + write_info_buffer_->http_info.get(), + &url_request_delegate_->received_info_)); + EXPECT_EQ(3072, url_request_delegate_->amount_received_); + char* p = url_request_delegate_->received_data_->data(); + for (int i = 0; i < 3; ++i, p += kBlockSize) + EXPECT_TRUE(CheckData(i + 1, p, kBlockSize)); + TestFinished(); + } + + // CancelRequest -------------------------------------- + + void CancelRequest() { + // This test has several async steps. + // 1. Write a large response to response storage. + // 2. Use URLRequest to retrieve it. + // 3. Cancel the request after data starts coming in. + + PushNextTask(method_factory_.NewRunnableMethod( + &AppCacheURLRequestJobTest::VerifyCancel)); + PushNextTask(method_factory_.NewRunnableMethod( + &AppCacheURLRequestJobTest::RequestAppCachedResource, true)); + + writer_.reset(service_->storage()->CreateResponseWriter(GURL())); + written_response_id_ = writer_->response_id(); + WriteLargeResponse(); + + url_request_delegate_->kill_after_amount_received_ = kBlockSize; + url_request_delegate_->kill_with_io_pending_ = false; + // Continues async + } + + void VerifyCancel() { + EXPECT_EQ(URLRequestStatus::CANCELED, + request_->status().status()); + TestFinished(); + } + + // CancelRequestWithIOPending -------------------------------------- + + void CancelRequestWithIOPending() { + // This test has several async steps. + // 1. Write a large response to response storage. + // 2. Use URLRequest to retrieve it. + // 3. Cancel the request after data starts coming in. + + PushNextTask(method_factory_.NewRunnableMethod( + &AppCacheURLRequestJobTest::VerifyCancel)); + PushNextTask(method_factory_.NewRunnableMethod( + &AppCacheURLRequestJobTest::RequestAppCachedResource, true)); + + writer_.reset(service_->storage()->CreateResponseWriter(GURL())); + written_response_id_ = writer_->response_id(); + WriteLargeResponse(); + + url_request_delegate_->kill_after_amount_received_ = kBlockSize; + url_request_delegate_->kill_with_io_pending_ = true; + // Continues async + } + + + // Data members -------------------------------------------------------- + + ScopedRunnableMethodFactory<AppCacheURLRequestJobTest> method_factory_; + scoped_ptr<base::WaitableEvent> test_finished_event_; + scoped_ptr<MockStorageDelegate> storage_delegate_; + scoped_ptr<MockAppCacheService> service_; + std::stack<std::pair<Task*, bool> > task_stack_; + + scoped_ptr<AppCacheResponseReader> reader_; + scoped_refptr<HttpResponseInfoIOBuffer> read_info_buffer_; + scoped_refptr<IOBuffer> read_buffer_; + int expected_read_result_; + net::CompletionCallbackImpl<AppCacheURLRequestJobTest> read_callback_; + net::CompletionCallbackImpl<AppCacheURLRequestJobTest> read_info_callback_; + bool should_delete_reader_in_completion_callback_; + int reader_deletion_count_down_; + bool read_callback_was_called_; + + int64 written_response_id_; + scoped_ptr<AppCacheResponseWriter> writer_; + scoped_refptr<HttpResponseInfoIOBuffer> write_info_buffer_; + scoped_refptr<IOBuffer> write_buffer_; + int expected_write_result_; + net::CompletionCallbackImpl<AppCacheURLRequestJobTest> write_callback_; + net::CompletionCallbackImpl<AppCacheURLRequestJobTest> write_info_callback_; + bool should_delete_writer_in_completion_callback_; + int writer_deletion_count_down_; + bool write_callback_was_called_; + + URLRequest::ProtocolFactory* orig_http_factory_; + scoped_ptr<URLRequest> request_; + scoped_ptr<MockURLRequestDelegate> url_request_delegate_; + + static scoped_ptr<base::Thread> io_thread_; + static AppCacheURLRequestJob* mock_factory_job_; +}; + +// static +scoped_ptr<base::Thread> AppCacheURLRequestJobTest::io_thread_; +AppCacheURLRequestJob* AppCacheURLRequestJobTest::mock_factory_job_ = NULL; + +TEST_F(AppCacheURLRequestJobTest, Basic) { + RunTestOnIOThread(&AppCacheURLRequestJobTest::Basic); +} + +TEST_F(AppCacheURLRequestJobTest, DeliveryOrders) { + RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliveryOrders); +} + +TEST_F(AppCacheURLRequestJobTest, DeliverNetworkResponse) { + RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverNetworkResponse); +} + +TEST_F(AppCacheURLRequestJobTest, DeliverErrorResponse) { + RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverErrorResponse); +} + +TEST_F(AppCacheURLRequestJobTest, DeliverSmallAppCachedResponse) { + RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverSmallAppCachedResponse); +} + +TEST_F(AppCacheURLRequestJobTest, DeliverLargeAppCachedResponse) { + RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverLargeAppCachedResponse); +} + +TEST_F(AppCacheURLRequestJobTest, CancelRequest) { + RunTestOnIOThread(&AppCacheURLRequestJobTest::CancelRequest); +} + +TEST_F(AppCacheURLRequestJobTest, CancelRequestWithIOPending) { + RunTestOnIOThread(&AppCacheURLRequestJobTest::CancelRequestWithIOPending); +} + +} // namespace appcache + |