Index: net/url_request/url_request_simple_job_unittest.cc |
diff --git a/net/url_request/url_request_simple_job_unittest.cc b/net/url_request/url_request_simple_job_unittest.cc |
index 7fbdefb4e887aa1984e85bba8ba64adad9189f1c..4be4c428912b37996fcf377aa79e663575fc86b4 100644 |
--- a/net/url_request/url_request_simple_job_unittest.cc |
+++ b/net/url_request/url_request_simple_job_unittest.cc |
@@ -5,6 +5,8 @@ |
#include "base/memory/scoped_ptr.h" |
#include "base/run_loop.h" |
#include "base/strings/stringprintf.h" |
+#include "base/threading/sequenced_worker_pool.h" |
+#include "base/threading/worker_pool.h" |
#include "net/base/request_priority.h" |
#include "net/url_request/url_request_job.h" |
#include "net/url_request/url_request_job_factory.h" |
@@ -26,45 +28,100 @@ static_assert(kRangeFirstPosition > 0 && |
static_cast<int>(arraysize(kTestData) - 1), |
"invalid range"); |
+// This function does nothing. |
+void DoNothing() { |
+} |
+ |
class MockSimpleJob : public URLRequestSimpleJob { |
public: |
- MockSimpleJob(URLRequest* request, NetworkDelegate* network_delegate) |
- : URLRequestSimpleJob(request, network_delegate) { |
- } |
+ MockSimpleJob(URLRequest* request, |
+ NetworkDelegate* network_delegate, |
+ scoped_refptr<base::TaskRunner> task_runner, |
+ std::string data) |
+ : URLRequestSimpleJob(request, network_delegate), |
+ data_(data), |
+ task_runner_(task_runner) {} |
protected: |
+ // URLRequestSimpleJob implementation: |
int GetData(std::string* mime_type, |
std::string* charset, |
std::string* data, |
const CompletionCallback& callback) const override { |
mime_type->assign("text/plain"); |
charset->assign("US-ASCII"); |
- data->assign(kTestData); |
+ data->assign(data_); |
return OK; |
} |
+ base::TaskRunner* GetTaskRunner() const override { |
+ return task_runner_.get(); |
+ } |
+ |
private: |
~MockSimpleJob() override {} |
- std::string data_; |
+ const std::string data_; |
+ |
+ scoped_refptr<base::TaskRunner> task_runner_; |
DISALLOW_COPY_AND_ASSIGN(MockSimpleJob); |
}; |
+class CancelURLRequestDelegate : public net::URLRequest::Delegate { |
+ public: |
+ explicit CancelURLRequestDelegate() |
+ : buf_(new IOBuffer(kBufferSize)), run_loop_(new base::RunLoop) {} |
+ |
+ void OnResponseStarted(net::URLRequest* request) override { |
+ int bytes_read = 0; |
+ EXPECT_FALSE(request->Read(buf_.get(), kBufferSize, &bytes_read)); |
+ EXPECT_TRUE(request->status().is_io_pending()); |
+ request->Cancel(); |
+ run_loop_->Quit(); |
+ } |
+ |
+ void OnReadCompleted(URLRequest* request, int bytes_read) override {} |
+ |
+ void WaitUntilHeadersReceived() const { run_loop_->Run(); } |
+ |
+ private: |
+ static const int kBufferSize = 4096; |
+ scoped_refptr<IOBuffer> buf_; |
+ scoped_ptr<base::RunLoop> run_loop_; |
+}; |
+ |
class SimpleJobProtocolHandler : |
public URLRequestJobFactory::ProtocolHandler { |
public: |
+ SimpleJobProtocolHandler(scoped_refptr<base::TaskRunner> task_runner) |
+ : task_runner_(task_runner) {} |
URLRequestJob* MaybeCreateJob( |
URLRequest* request, |
NetworkDelegate* network_delegate) const override { |
- return new MockSimpleJob(request, network_delegate); |
+ if (request->url().spec() == "data:empty") |
+ return new MockSimpleJob(request, network_delegate, task_runner_, ""); |
+ return new MockSimpleJob(request, network_delegate, task_runner_, |
+ kTestData); |
} |
+ |
+ private: |
+ scoped_refptr<base::TaskRunner> task_runner_; |
+ |
+ ~SimpleJobProtocolHandler() override {} |
}; |
class URLRequestSimpleJobTest : public ::testing::Test { |
public: |
- URLRequestSimpleJobTest() : context_(true) { |
- job_factory_.SetProtocolHandler("data", new SimpleJobProtocolHandler()); |
+ URLRequestSimpleJobTest() |
+ : worker_pool_( |
+ new base::SequencedWorkerPool(1, "URLRequestSimpleJobTest")), |
+ task_runner_(worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior( |
+ worker_pool_->GetSequenceToken(), |
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), |
+ context_(true) { |
+ job_factory_.SetProtocolHandler("data", |
+ new SimpleJobProtocolHandler(task_runner_)); |
context_.set_job_factory(&job_factory_); |
context_.Init(); |
@@ -72,6 +129,8 @@ class URLRequestSimpleJobTest : public ::testing::Test { |
GURL("data:test"), DEFAULT_PRIORITY, &delegate_, NULL); |
} |
+ ~URLRequestSimpleJobTest() override { worker_pool_->Shutdown(); } |
+ |
void StartRequest(const HttpRequestHeaders* headers) { |
if (headers) |
request_->SetExtraRequestHeaders(*headers); |
@@ -82,9 +141,13 @@ class URLRequestSimpleJobTest : public ::testing::Test { |
EXPECT_FALSE(request_->is_pending()); |
} |
+ void TearDown() override { worker_pool_->Shutdown(); } |
+ |
protected: |
- URLRequestJobFactoryImpl job_factory_; |
+ scoped_refptr<base::SequencedWorkerPool> worker_pool_; |
+ scoped_refptr<base::SequencedTaskRunner> task_runner_; |
TestURLRequestContext context_; |
+ URLRequestJobFactoryImpl job_factory_; |
TestDelegate delegate_; |
scoped_ptr<URLRequest> request_; |
}; |
@@ -140,4 +203,28 @@ TEST_F(URLRequestSimpleJobTest, InvalidRangeRequest) { |
EXPECT_EQ(kTestData, delegate_.data_received()); |
} |
+TEST_F(URLRequestSimpleJobTest, EmptyDataRequest) { |
+ request_ = context_.CreateRequest(GURL("data:empty"), DEFAULT_PRIORITY, |
+ &delegate_, NULL); |
+ StartRequest(nullptr); |
+ ASSERT_TRUE(request_->status().is_success()); |
+ EXPECT_EQ("", delegate_.data_received()); |
+} |
+ |
+TEST_F(URLRequestSimpleJobTest, CancelAfterFirstRead) { |
+ scoped_ptr<CancelURLRequestDelegate> cancel_delegate( |
+ new CancelURLRequestDelegate()); |
+ request_ = context_.CreateRequest(GURL("data:cancel"), DEFAULT_PRIORITY, |
+ cancel_delegate.get(), NULL); |
+ request_->Start(); |
+ cancel_delegate->WaitUntilHeadersReceived(); |
+ |
+ // Feed a dummy task to the SequencedTaskRunner to make sure that the |
+ // callbacks which are invoked in ReadRawData have completed safely. |
+ base::RunLoop run_loop; |
+ EXPECT_TRUE(task_runner_->PostTaskAndReply(FROM_HERE, base::Bind(&DoNothing), |
+ run_loop.QuitClosure())); |
+ run_loop.Run(); |
+} |
+ |
} // namespace net |