Update V8 to version 4.6.55.
[chromium-blink-merge.git] / net / url_request / url_request_simple_job_unittest.cc
blob439995a3b8ebdc0121e81462025d83d9d1181c79
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
3 // found in the LICENSE file.
5 #include "base/bind_helpers.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/run_loop.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/threading/sequenced_worker_pool.h"
10 #include "base/threading/worker_pool.h"
11 #include "net/base/request_priority.h"
12 #include "net/url_request/url_request_job.h"
13 #include "net/url_request/url_request_job_factory.h"
14 #include "net/url_request/url_request_job_factory_impl.h"
15 #include "net/url_request/url_request_simple_job.h"
16 #include "net/url_request/url_request_test_util.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 namespace net {
21 namespace {
23 const char kTestData[] = "Huge data array";
24 const int kRangeFirstPosition = 5;
25 const int kRangeLastPosition = 8;
26 static_assert(kRangeFirstPosition > 0 &&
27 kRangeFirstPosition < kRangeLastPosition &&
28 kRangeLastPosition <
29 static_cast<int>(arraysize(kTestData) - 1),
30 "invalid range");
32 class MockSimpleJob : public URLRequestSimpleJob {
33 public:
34 MockSimpleJob(URLRequest* request,
35 NetworkDelegate* network_delegate,
36 scoped_refptr<base::TaskRunner> task_runner,
37 std::string data)
38 : URLRequestSimpleJob(request, network_delegate),
39 data_(data),
40 task_runner_(task_runner) {}
42 protected:
43 // URLRequestSimpleJob implementation:
44 int GetData(std::string* mime_type,
45 std::string* charset,
46 std::string* data,
47 const CompletionCallback& callback) const override {
48 mime_type->assign("text/plain");
49 charset->assign("US-ASCII");
50 data->assign(data_);
51 return OK;
54 base::TaskRunner* GetTaskRunner() const override {
55 return task_runner_.get();
58 private:
59 ~MockSimpleJob() override {}
61 const std::string data_;
63 scoped_refptr<base::TaskRunner> task_runner_;
65 DISALLOW_COPY_AND_ASSIGN(MockSimpleJob);
68 class CancelURLRequestDelegate : public URLRequest::Delegate {
69 public:
70 CancelURLRequestDelegate()
71 : buf_(new IOBuffer(kBufferSize)), run_loop_(new base::RunLoop) {}
73 void OnResponseStarted(URLRequest* request) override {
74 int bytes_read = 0;
75 EXPECT_FALSE(request->Read(buf_.get(), kBufferSize, &bytes_read));
76 EXPECT_TRUE(request->status().is_io_pending());
77 request->Cancel();
78 run_loop_->Quit();
81 void OnReadCompleted(URLRequest* request, int bytes_read) override {}
83 void WaitUntilHeadersReceived() const { run_loop_->Run(); }
85 private:
86 static const int kBufferSize = 4096;
87 scoped_refptr<IOBuffer> buf_;
88 scoped_ptr<base::RunLoop> run_loop_;
91 class SimpleJobProtocolHandler :
92 public URLRequestJobFactory::ProtocolHandler {
93 public:
94 SimpleJobProtocolHandler(scoped_refptr<base::TaskRunner> task_runner)
95 : task_runner_(task_runner) {}
96 URLRequestJob* MaybeCreateJob(
97 URLRequest* request,
98 NetworkDelegate* network_delegate) const override {
99 if (request->url().spec() == "data:empty")
100 return new MockSimpleJob(request, network_delegate, task_runner_, "");
101 return new MockSimpleJob(request, network_delegate, task_runner_,
102 kTestData);
105 private:
106 scoped_refptr<base::TaskRunner> task_runner_;
108 ~SimpleJobProtocolHandler() override {}
111 class URLRequestSimpleJobTest : public ::testing::Test {
112 public:
113 URLRequestSimpleJobTest()
114 : worker_pool_(
115 new base::SequencedWorkerPool(1, "URLRequestSimpleJobTest")),
116 task_runner_(worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior(
117 worker_pool_->GetSequenceToken(),
118 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
119 context_(true) {
120 job_factory_.SetProtocolHandler("data",
121 new SimpleJobProtocolHandler(task_runner_));
122 context_.set_job_factory(&job_factory_);
123 context_.Init();
125 request_ =
126 context_.CreateRequest(GURL("data:test"), DEFAULT_PRIORITY, &delegate_);
129 ~URLRequestSimpleJobTest() override { worker_pool_->Shutdown(); }
131 void StartRequest(const HttpRequestHeaders* headers) {
132 if (headers)
133 request_->SetExtraRequestHeaders(*headers);
134 request_->Start();
136 EXPECT_TRUE(request_->is_pending());
137 base::RunLoop().Run();
138 EXPECT_FALSE(request_->is_pending());
141 void TearDown() override { worker_pool_->Shutdown(); }
143 protected:
144 scoped_refptr<base::SequencedWorkerPool> worker_pool_;
145 scoped_refptr<base::SequencedTaskRunner> task_runner_;
146 TestURLRequestContext context_;
147 URLRequestJobFactoryImpl job_factory_;
148 TestDelegate delegate_;
149 scoped_ptr<URLRequest> request_;
152 } // namespace
154 TEST_F(URLRequestSimpleJobTest, SimpleRequest) {
155 StartRequest(NULL);
156 ASSERT_TRUE(request_->status().is_success());
157 EXPECT_EQ(kTestData, delegate_.data_received());
160 TEST_F(URLRequestSimpleJobTest, RangeRequest) {
161 const std::string kExpectedBody = std::string(
162 kTestData + kRangeFirstPosition, kTestData + kRangeLastPosition + 1);
163 HttpRequestHeaders headers;
164 headers.SetHeader(
165 HttpRequestHeaders::kRange,
166 HttpByteRange::Bounded(kRangeFirstPosition, kRangeLastPosition)
167 .GetHeaderValue());
169 StartRequest(&headers);
171 ASSERT_TRUE(request_->status().is_success());
172 EXPECT_EQ(kExpectedBody, delegate_.data_received());
175 TEST_F(URLRequestSimpleJobTest, MultipleRangeRequest) {
176 HttpRequestHeaders headers;
177 int middle_pos = (kRangeFirstPosition + kRangeLastPosition)/2;
178 std::string range = base::StringPrintf("bytes=%d-%d,%d-%d",
179 kRangeFirstPosition,
180 middle_pos,
181 middle_pos + 1,
182 kRangeLastPosition);
183 headers.SetHeader(HttpRequestHeaders::kRange, range);
185 StartRequest(&headers);
187 EXPECT_TRUE(delegate_.request_failed());
188 EXPECT_EQ(ERR_REQUEST_RANGE_NOT_SATISFIABLE, request_->status().error());
191 TEST_F(URLRequestSimpleJobTest, InvalidRangeRequest) {
192 HttpRequestHeaders headers;
193 std::string range = base::StringPrintf(
194 "bytes=%d-%d", kRangeLastPosition, kRangeFirstPosition);
195 headers.SetHeader(HttpRequestHeaders::kRange, range);
197 StartRequest(&headers);
199 ASSERT_TRUE(request_->status().is_success());
200 EXPECT_EQ(kTestData, delegate_.data_received());
203 TEST_F(URLRequestSimpleJobTest, EmptyDataRequest) {
204 request_ =
205 context_.CreateRequest(GURL("data:empty"), DEFAULT_PRIORITY, &delegate_);
206 StartRequest(nullptr);
207 ASSERT_TRUE(request_->status().is_success());
208 EXPECT_EQ("", delegate_.data_received());
211 TEST_F(URLRequestSimpleJobTest, CancelAfterFirstRead) {
212 scoped_ptr<CancelURLRequestDelegate> cancel_delegate(
213 new CancelURLRequestDelegate());
214 request_ = context_.CreateRequest(GURL("data:cancel"), DEFAULT_PRIORITY,
215 cancel_delegate.get());
216 request_->Start();
217 cancel_delegate->WaitUntilHeadersReceived();
219 // Feed a dummy task to the SequencedTaskRunner to make sure that the
220 // callbacks which are invoked in ReadRawData have completed safely.
221 base::RunLoop run_loop;
222 EXPECT_TRUE(task_runner_->PostTaskAndReply(
223 FROM_HERE, base::Bind(&base::DoNothing), run_loop.QuitClosure()));
224 run_loop.Run();
227 } // namespace net