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 "net/url_request/url_request_simple_job.h" | 5 #include "net/url_request/url_request_simple_job.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
13 #include "base/message_loop/message_loop.h" | |
13 #include "base/run_loop.h" | 14 #include "base/run_loop.h" |
14 #include "base/sequenced_task_runner.h" | 15 #include "base/sequenced_task_runner.h" |
15 #include "base/strings/string_piece.h" | 16 #include "base/strings/string_piece.h" |
16 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
17 #include "base/threading/thread.h" | 18 #include "base/test/scoped_task_scheduler.h" |
18 #include "net/base/request_priority.h" | 19 #include "net/base/request_priority.h" |
19 #include "net/test/gtest_util.h" | 20 #include "net/test/gtest_util.h" |
20 #include "net/url_request/url_request_job.h" | 21 #include "net/url_request/url_request_job.h" |
21 #include "net/url_request/url_request_job_factory.h" | 22 #include "net/url_request/url_request_job_factory.h" |
22 #include "net/url_request/url_request_job_factory_impl.h" | 23 #include "net/url_request/url_request_job_factory_impl.h" |
23 #include "net/url_request/url_request_test_util.h" | 24 #include "net/url_request/url_request_test_util.h" |
24 #include "testing/gmock/include/gmock/gmock.h" | 25 #include "testing/gmock/include/gmock/gmock.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
26 | 27 |
27 using net::test::IsError; | 28 using net::test::IsError; |
28 using net::test::IsOk; | 29 using net::test::IsOk; |
29 | 30 |
30 namespace net { | 31 namespace net { |
31 | 32 |
32 namespace { | 33 namespace { |
33 | 34 |
34 const char kTestData[] = "Huge data array"; | 35 const char kTestData[] = "Huge data array"; |
35 const int kRangeFirstPosition = 5; | 36 const int kRangeFirstPosition = 5; |
36 const int kRangeLastPosition = 8; | 37 const int kRangeLastPosition = 8; |
37 static_assert(kRangeFirstPosition > 0 && | 38 static_assert(kRangeFirstPosition > 0 && |
38 kRangeFirstPosition < kRangeLastPosition && | 39 kRangeFirstPosition < kRangeLastPosition && |
39 kRangeLastPosition < | 40 kRangeLastPosition < |
40 static_cast<int>(arraysize(kTestData) - 1), | 41 static_cast<int>(arraysize(kTestData) - 1), |
41 "invalid range"); | 42 "invalid range"); |
42 | 43 |
43 class MockSimpleJob : public URLRequestSimpleJob { | 44 class MockSimpleJob : public URLRequestSimpleJob { |
44 public: | 45 public: |
45 MockSimpleJob(URLRequest* request, | 46 MockSimpleJob(URLRequest* request, |
46 NetworkDelegate* network_delegate, | 47 NetworkDelegate* network_delegate, |
47 scoped_refptr<base::TaskRunner> task_runner, | |
48 base::StringPiece data) | 48 base::StringPiece data) |
49 : URLRequestSimpleJob(request, network_delegate), | 49 : URLRequestSimpleJob(request, network_delegate), |
50 data_(data.as_string()), | 50 data_(data.as_string()) {} |
51 task_runner_(std::move(task_runner)) {} | |
52 | 51 |
53 protected: | 52 protected: |
54 // URLRequestSimpleJob implementation: | 53 // URLRequestSimpleJob implementation: |
55 int GetData(std::string* mime_type, | 54 int GetData(std::string* mime_type, |
56 std::string* charset, | 55 std::string* charset, |
57 std::string* data, | 56 std::string* data, |
58 const CompletionCallback& callback) const override { | 57 const CompletionCallback& callback) const override { |
59 mime_type->assign("text/plain"); | 58 mime_type->assign("text/plain"); |
60 charset->assign("US-ASCII"); | 59 charset->assign("US-ASCII"); |
61 data->assign(data_); | 60 data->assign(data_); |
62 return OK; | 61 return OK; |
63 } | 62 } |
64 | 63 |
65 base::TaskRunner* GetTaskRunner() const override { | |
66 return task_runner_.get(); | |
67 } | |
68 | |
69 private: | 64 private: |
70 ~MockSimpleJob() override {} | 65 ~MockSimpleJob() override {} |
71 | 66 |
72 const std::string data_; | 67 const std::string data_; |
73 | 68 |
74 const scoped_refptr<base::TaskRunner> task_runner_; | |
75 | |
76 DISALLOW_COPY_AND_ASSIGN(MockSimpleJob); | 69 DISALLOW_COPY_AND_ASSIGN(MockSimpleJob); |
77 }; | 70 }; |
78 | 71 |
79 class CancelAfterFirstReadURLRequestDelegate : public TestDelegate { | 72 class CancelAfterFirstReadURLRequestDelegate : public TestDelegate { |
80 public: | 73 public: |
81 CancelAfterFirstReadURLRequestDelegate() : run_loop_(new base::RunLoop) {} | 74 CancelAfterFirstReadURLRequestDelegate() : run_loop_(new base::RunLoop) {} |
82 | 75 |
83 ~CancelAfterFirstReadURLRequestDelegate() override {} | 76 ~CancelAfterFirstReadURLRequestDelegate() override {} |
84 | 77 |
85 void OnResponseStarted(URLRequest* request, int net_error) override { | 78 void OnResponseStarted(URLRequest* request, int net_error) override { |
86 DCHECK_NE(ERR_IO_PENDING, net_error); | 79 DCHECK_NE(ERR_IO_PENDING, net_error); |
87 // net::TestDelegate will start the first read. | 80 // net::TestDelegate will start the first read. |
88 TestDelegate::OnResponseStarted(request, net_error); | 81 TestDelegate::OnResponseStarted(request, net_error); |
89 request->Cancel(); | 82 request->Cancel(); |
90 run_loop_->Quit(); | 83 run_loop_->Quit(); |
91 } | 84 } |
92 | 85 |
93 void WaitUntilHeadersReceived() const { run_loop_->Run(); } | 86 void WaitUntilHeadersReceived() const { run_loop_->Run(); } |
94 | 87 |
95 private: | 88 private: |
96 std::unique_ptr<base::RunLoop> run_loop_; | 89 std::unique_ptr<base::RunLoop> run_loop_; |
97 | 90 |
98 DISALLOW_COPY_AND_ASSIGN(CancelAfterFirstReadURLRequestDelegate); | 91 DISALLOW_COPY_AND_ASSIGN(CancelAfterFirstReadURLRequestDelegate); |
99 }; | 92 }; |
100 | 93 |
101 class SimpleJobProtocolHandler : | 94 class SimpleJobProtocolHandler : |
102 public URLRequestJobFactory::ProtocolHandler { | 95 public URLRequestJobFactory::ProtocolHandler { |
103 public: | 96 public: |
104 SimpleJobProtocolHandler(scoped_refptr<base::TaskRunner> task_runner) | 97 SimpleJobProtocolHandler() = default; |
105 : task_runner_(std::move(task_runner)) {} | |
106 URLRequestJob* MaybeCreateJob( | 98 URLRequestJob* MaybeCreateJob( |
107 URLRequest* request, | 99 URLRequest* request, |
108 NetworkDelegate* network_delegate) const override { | 100 NetworkDelegate* network_delegate) const override { |
109 if (request->url().spec() == "data:empty") | 101 if (request->url().spec() == "data:empty") |
110 return new MockSimpleJob(request, network_delegate, task_runner_, ""); | 102 return new MockSimpleJob(request, network_delegate, ""); |
111 return new MockSimpleJob(request, network_delegate, task_runner_, | 103 return new MockSimpleJob(request, network_delegate, kTestData); |
112 kTestData); | |
113 } | 104 } |
114 | 105 |
115 ~SimpleJobProtocolHandler() override {} | 106 ~SimpleJobProtocolHandler() override {} |
116 | 107 |
117 private: | 108 private: |
118 const scoped_refptr<base::TaskRunner> task_runner_; | |
119 | |
120 DISALLOW_COPY_AND_ASSIGN(SimpleJobProtocolHandler); | 109 DISALLOW_COPY_AND_ASSIGN(SimpleJobProtocolHandler); |
121 }; | 110 }; |
122 | 111 |
123 class URLRequestSimpleJobTest : public ::testing::Test { | 112 class URLRequestSimpleJobTest : public ::testing::Test { |
124 public: | 113 public: |
125 URLRequestSimpleJobTest() | 114 URLRequestSimpleJobTest() |
126 : worker_thread_("URLRequestSimpleJobTest"), context_(true) { | 115 : scoped_task_scheduler_(base::MessageLoop::current()), context_(true) { |
127 EXPECT_TRUE(worker_thread_.Start()); | |
128 | |
129 job_factory_.SetProtocolHandler( | 116 job_factory_.SetProtocolHandler( |
130 "data", base::MakeUnique<SimpleJobProtocolHandler>(task_runner())); | 117 "data", base::MakeUnique<SimpleJobProtocolHandler>()); |
131 context_.set_job_factory(&job_factory_); | 118 context_.set_job_factory(&job_factory_); |
132 context_.Init(); | 119 context_.Init(); |
133 | 120 |
134 request_ = | 121 request_ = |
135 context_.CreateRequest(GURL("data:test"), DEFAULT_PRIORITY, &delegate_); | 122 context_.CreateRequest(GURL("data:test"), DEFAULT_PRIORITY, &delegate_); |
136 } | 123 } |
137 | 124 |
138 void StartRequest(const HttpRequestHeaders* headers) { | 125 void StartRequest(const HttpRequestHeaders* headers) { |
139 if (headers) | 126 if (headers) |
140 request_->SetExtraRequestHeaders(*headers); | 127 request_->SetExtraRequestHeaders(*headers); |
141 request_->Start(); | 128 request_->Start(); |
142 | 129 |
143 EXPECT_TRUE(request_->is_pending()); | 130 EXPECT_TRUE(request_->is_pending()); |
144 base::RunLoop().Run(); | 131 base::RunLoop().Run(); |
145 EXPECT_FALSE(request_->is_pending()); | 132 EXPECT_FALSE(request_->is_pending()); |
146 } | 133 } |
147 | 134 |
148 scoped_refptr<base::SequencedTaskRunner> task_runner() { | 135 private: |
xunjieli
2017/02/09 16:43:08
nit: private after protected
fdoray
2017/02/10 16:08:50
We recommend keeping ScopedTaskScheduler first bec
xunjieli
2017/02/10 16:15:06
Acknowledged. Please add a one-line comment here a
fdoray
2017/02/10 16:17:24
After reflection, I decided to move it to the end
| |
149 return worker_thread_.task_runner(); | 136 base::test::ScopedTaskScheduler scoped_task_scheduler_; |
150 } | |
151 | 137 |
152 protected: | 138 protected: |
153 base::Thread worker_thread_; | |
154 TestURLRequestContext context_; | 139 TestURLRequestContext context_; |
155 URLRequestJobFactoryImpl job_factory_; | 140 URLRequestJobFactoryImpl job_factory_; |
156 TestDelegate delegate_; | 141 TestDelegate delegate_; |
157 std::unique_ptr<URLRequest> request_; | 142 std::unique_ptr<URLRequest> request_; |
158 | 143 |
159 DISALLOW_COPY_AND_ASSIGN(URLRequestSimpleJobTest); | 144 DISALLOW_COPY_AND_ASSIGN(URLRequestSimpleJobTest); |
160 }; | 145 }; |
161 | 146 |
162 } // namespace | 147 } // namespace |
163 | 148 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 EXPECT_EQ(1, delegate_.response_started_count()); | 214 EXPECT_EQ(1, delegate_.response_started_count()); |
230 } | 215 } |
231 | 216 |
232 TEST_F(URLRequestSimpleJobTest, CancelAfterFirstReadStarted) { | 217 TEST_F(URLRequestSimpleJobTest, CancelAfterFirstReadStarted) { |
233 CancelAfterFirstReadURLRequestDelegate cancel_delegate; | 218 CancelAfterFirstReadURLRequestDelegate cancel_delegate; |
234 request_ = context_.CreateRequest(GURL("data:cancel"), DEFAULT_PRIORITY, | 219 request_ = context_.CreateRequest(GURL("data:cancel"), DEFAULT_PRIORITY, |
235 &cancel_delegate); | 220 &cancel_delegate); |
236 request_->Start(); | 221 request_->Start(); |
237 cancel_delegate.WaitUntilHeadersReceived(); | 222 cancel_delegate.WaitUntilHeadersReceived(); |
238 | 223 |
239 // Feed a dummy task to the SequencedTaskRunner to make sure that the | 224 // Run ScopedTaskScheduler tasks. |
240 // callbacks which are invoked in ReadRawData have completed safely. | 225 base::RunLoop().RunUntilIdle(); |
241 base::RunLoop run_loop; | |
242 EXPECT_TRUE(task_runner()->PostTaskAndReply( | |
243 FROM_HERE, base::Bind(&base::DoNothing), run_loop.QuitClosure())); | |
244 run_loop.Run(); | |
245 | 226 |
246 EXPECT_THAT(cancel_delegate.request_status(), IsError(ERR_ABORTED)); | 227 EXPECT_THAT(cancel_delegate.request_status(), IsError(ERR_ABORTED)); |
247 EXPECT_EQ(1, cancel_delegate.response_started_count()); | 228 EXPECT_EQ(1, cancel_delegate.response_started_count()); |
248 EXPECT_EQ("", cancel_delegate.data_received()); | 229 EXPECT_EQ("", cancel_delegate.data_received()); |
249 // Destroy the request so it doesn't outlive its delegate. | 230 // Destroy the request so it doesn't outlive its delegate. |
250 request_.reset(); | 231 request_.reset(); |
251 } | 232 } |
252 | 233 |
253 } // namespace net | 234 } // namespace net |
OLD | NEW |