OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/memory/scoped_ptr.h" | 5 #include "base/memory/scoped_ptr.h" |
6 #include "base/run_loop.h" | 6 #include "base/run_loop.h" |
7 #include "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
| 8 #include "base/threading/sequenced_worker_pool.h" |
| 9 #include "base/threading/worker_pool.h" |
8 #include "net/base/request_priority.h" | 10 #include "net/base/request_priority.h" |
9 #include "net/url_request/url_request_job.h" | 11 #include "net/url_request/url_request_job.h" |
10 #include "net/url_request/url_request_job_factory.h" | 12 #include "net/url_request/url_request_job_factory.h" |
11 #include "net/url_request/url_request_job_factory_impl.h" | 13 #include "net/url_request/url_request_job_factory_impl.h" |
12 #include "net/url_request/url_request_simple_job.h" | 14 #include "net/url_request/url_request_simple_job.h" |
13 #include "net/url_request/url_request_test_util.h" | 15 #include "net/url_request/url_request_test_util.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
15 | 17 |
16 namespace net { | 18 namespace net { |
17 | 19 |
18 namespace { | 20 namespace { |
19 | 21 |
20 const char kTestData[] = "Huge data array"; | 22 const char kTestData[] = "Huge data array"; |
21 const int kRangeFirstPosition = 5; | 23 const int kRangeFirstPosition = 5; |
22 const int kRangeLastPosition = 8; | 24 const int kRangeLastPosition = 8; |
23 static_assert(kRangeFirstPosition > 0 && | 25 static_assert(kRangeFirstPosition > 0 && |
24 kRangeFirstPosition < kRangeLastPosition && | 26 kRangeFirstPosition < kRangeLastPosition && |
25 kRangeLastPosition < | 27 kRangeLastPosition < |
26 static_cast<int>(arraysize(kTestData) - 1), | 28 static_cast<int>(arraysize(kTestData) - 1), |
27 "invalid range"); | 29 "invalid range"); |
28 | 30 |
| 31 // This function does nothing. |
| 32 void DoNothing() { |
| 33 } |
| 34 |
29 class MockSimpleJob : public URLRequestSimpleJob { | 35 class MockSimpleJob : public URLRequestSimpleJob { |
30 public: | 36 public: |
31 MockSimpleJob(URLRequest* request, NetworkDelegate* network_delegate) | 37 MockSimpleJob(URLRequest* request, |
32 : URLRequestSimpleJob(request, network_delegate) { | 38 NetworkDelegate* network_delegate, |
33 } | 39 scoped_refptr<base::TaskRunner> task_runner, |
| 40 std::string data) |
| 41 : URLRequestSimpleJob(request, network_delegate), |
| 42 data_(data), |
| 43 task_runner_(task_runner) {} |
34 | 44 |
35 protected: | 45 protected: |
| 46 // URLRequestSimpleJob implementation: |
36 int GetData(std::string* mime_type, | 47 int GetData(std::string* mime_type, |
37 std::string* charset, | 48 std::string* charset, |
38 std::string* data, | 49 std::string* data, |
39 const CompletionCallback& callback) const override { | 50 const CompletionCallback& callback) const override { |
40 mime_type->assign("text/plain"); | 51 mime_type->assign("text/plain"); |
41 charset->assign("US-ASCII"); | 52 charset->assign("US-ASCII"); |
42 data->assign(kTestData); | 53 data->assign(data_); |
43 return OK; | 54 return OK; |
44 } | 55 } |
45 | 56 |
| 57 base::TaskRunner* GetTaskRunner() const override { |
| 58 return task_runner_.get(); |
| 59 } |
| 60 |
46 private: | 61 private: |
47 ~MockSimpleJob() override {} | 62 ~MockSimpleJob() override {} |
48 | 63 |
49 std::string data_; | 64 const std::string data_; |
| 65 |
| 66 scoped_refptr<base::TaskRunner> task_runner_; |
50 | 67 |
51 DISALLOW_COPY_AND_ASSIGN(MockSimpleJob); | 68 DISALLOW_COPY_AND_ASSIGN(MockSimpleJob); |
52 }; | 69 }; |
53 | 70 |
| 71 class CancelURLRequestDelegate : public net::URLRequest::Delegate { |
| 72 public: |
| 73 explicit CancelURLRequestDelegate() |
| 74 : buf_(new IOBuffer(kBufferSize)), run_loop_(new base::RunLoop) {} |
| 75 |
| 76 void OnResponseStarted(net::URLRequest* request) override { |
| 77 int bytes_read = 0; |
| 78 EXPECT_FALSE(request->Read(buf_.get(), kBufferSize, &bytes_read)); |
| 79 EXPECT_TRUE(request->status().is_io_pending()); |
| 80 request->Cancel(); |
| 81 run_loop_->Quit(); |
| 82 } |
| 83 |
| 84 void OnReadCompleted(URLRequest* request, int bytes_read) override {} |
| 85 |
| 86 void WaitUntilHeadersReceived() const { run_loop_->Run(); } |
| 87 |
| 88 private: |
| 89 static const int kBufferSize = 4096; |
| 90 scoped_refptr<IOBuffer> buf_; |
| 91 scoped_ptr<base::RunLoop> run_loop_; |
| 92 }; |
| 93 |
54 class SimpleJobProtocolHandler : | 94 class SimpleJobProtocolHandler : |
55 public URLRequestJobFactory::ProtocolHandler { | 95 public URLRequestJobFactory::ProtocolHandler { |
56 public: | 96 public: |
| 97 SimpleJobProtocolHandler(scoped_refptr<base::TaskRunner> task_runner) |
| 98 : task_runner_(task_runner) {} |
57 URLRequestJob* MaybeCreateJob( | 99 URLRequestJob* MaybeCreateJob( |
58 URLRequest* request, | 100 URLRequest* request, |
59 NetworkDelegate* network_delegate) const override { | 101 NetworkDelegate* network_delegate) const override { |
60 return new MockSimpleJob(request, network_delegate); | 102 if (request->url().spec() == "data:empty") |
| 103 return new MockSimpleJob(request, network_delegate, task_runner_, ""); |
| 104 return new MockSimpleJob(request, network_delegate, task_runner_, |
| 105 kTestData); |
61 } | 106 } |
| 107 |
| 108 private: |
| 109 scoped_refptr<base::TaskRunner> task_runner_; |
| 110 |
| 111 ~SimpleJobProtocolHandler() override {} |
62 }; | 112 }; |
63 | 113 |
64 class URLRequestSimpleJobTest : public ::testing::Test { | 114 class URLRequestSimpleJobTest : public ::testing::Test { |
65 public: | 115 public: |
66 URLRequestSimpleJobTest() : context_(true) { | 116 URLRequestSimpleJobTest() |
67 job_factory_.SetProtocolHandler("data", new SimpleJobProtocolHandler()); | 117 : worker_pool_( |
| 118 new base::SequencedWorkerPool(1, "URLRequestSimpleJobTest")), |
| 119 task_runner_(worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior( |
| 120 worker_pool_->GetSequenceToken(), |
| 121 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), |
| 122 context_(true) { |
| 123 job_factory_.SetProtocolHandler("data", |
| 124 new SimpleJobProtocolHandler(task_runner_)); |
68 context_.set_job_factory(&job_factory_); | 125 context_.set_job_factory(&job_factory_); |
69 context_.Init(); | 126 context_.Init(); |
70 | 127 |
71 request_ = context_.CreateRequest( | 128 request_ = context_.CreateRequest( |
72 GURL("data:test"), DEFAULT_PRIORITY, &delegate_, NULL); | 129 GURL("data:test"), DEFAULT_PRIORITY, &delegate_, NULL); |
73 } | 130 } |
74 | 131 |
| 132 ~URLRequestSimpleJobTest() override { worker_pool_->Shutdown(); } |
| 133 |
75 void StartRequest(const HttpRequestHeaders* headers) { | 134 void StartRequest(const HttpRequestHeaders* headers) { |
76 if (headers) | 135 if (headers) |
77 request_->SetExtraRequestHeaders(*headers); | 136 request_->SetExtraRequestHeaders(*headers); |
78 request_->Start(); | 137 request_->Start(); |
79 | 138 |
80 EXPECT_TRUE(request_->is_pending()); | 139 EXPECT_TRUE(request_->is_pending()); |
81 base::RunLoop().Run(); | 140 base::RunLoop().Run(); |
82 EXPECT_FALSE(request_->is_pending()); | 141 EXPECT_FALSE(request_->is_pending()); |
83 } | 142 } |
84 | 143 |
| 144 void TearDown() override { worker_pool_->Shutdown(); } |
| 145 |
85 protected: | 146 protected: |
| 147 scoped_refptr<base::SequencedWorkerPool> worker_pool_; |
| 148 scoped_refptr<base::SequencedTaskRunner> task_runner_; |
| 149 TestURLRequestContext context_; |
86 URLRequestJobFactoryImpl job_factory_; | 150 URLRequestJobFactoryImpl job_factory_; |
87 TestURLRequestContext context_; | |
88 TestDelegate delegate_; | 151 TestDelegate delegate_; |
89 scoped_ptr<URLRequest> request_; | 152 scoped_ptr<URLRequest> request_; |
90 }; | 153 }; |
91 | 154 |
92 } // namespace | 155 } // namespace |
93 | 156 |
94 TEST_F(URLRequestSimpleJobTest, SimpleRequest) { | 157 TEST_F(URLRequestSimpleJobTest, SimpleRequest) { |
95 StartRequest(NULL); | 158 StartRequest(NULL); |
96 ASSERT_TRUE(request_->status().is_success()); | 159 ASSERT_TRUE(request_->status().is_success()); |
97 EXPECT_EQ(kTestData, delegate_.data_received()); | 160 EXPECT_EQ(kTestData, delegate_.data_received()); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 std::string range = base::StringPrintf( | 196 std::string range = base::StringPrintf( |
134 "bytes=%d-%d", kRangeLastPosition, kRangeFirstPosition); | 197 "bytes=%d-%d", kRangeLastPosition, kRangeFirstPosition); |
135 headers.SetHeader(HttpRequestHeaders::kRange, range); | 198 headers.SetHeader(HttpRequestHeaders::kRange, range); |
136 | 199 |
137 StartRequest(&headers); | 200 StartRequest(&headers); |
138 | 201 |
139 ASSERT_TRUE(request_->status().is_success()); | 202 ASSERT_TRUE(request_->status().is_success()); |
140 EXPECT_EQ(kTestData, delegate_.data_received()); | 203 EXPECT_EQ(kTestData, delegate_.data_received()); |
141 } | 204 } |
142 | 205 |
| 206 TEST_F(URLRequestSimpleJobTest, EmptyDataRequest) { |
| 207 request_ = context_.CreateRequest(GURL("data:empty"), DEFAULT_PRIORITY, |
| 208 &delegate_, NULL); |
| 209 StartRequest(nullptr); |
| 210 ASSERT_TRUE(request_->status().is_success()); |
| 211 EXPECT_EQ("", delegate_.data_received()); |
| 212 } |
| 213 |
| 214 TEST_F(URLRequestSimpleJobTest, CancelAfterFirstRead) { |
| 215 scoped_ptr<CancelURLRequestDelegate> cancel_delegate( |
| 216 new CancelURLRequestDelegate()); |
| 217 request_ = context_.CreateRequest(GURL("data:cancel"), DEFAULT_PRIORITY, |
| 218 cancel_delegate.get(), NULL); |
| 219 request_->Start(); |
| 220 cancel_delegate->WaitUntilHeadersReceived(); |
| 221 |
| 222 // Feed a dummy task to the SequencedTaskRunner to make sure that the |
| 223 // callbacks which are invoked in ReadRawData have completed safely. |
| 224 base::RunLoop run_loop; |
| 225 EXPECT_TRUE(task_runner_->PostTaskAndReply(FROM_HERE, base::Bind(&DoNothing), |
| 226 run_loop.QuitClosure())); |
| 227 run_loop.Run(); |
| 228 } |
| 229 |
143 } // namespace net | 230 } // namespace net |
OLD | NEW |