We started redesigning GpuMemoryBuffer interface to handle multiple buffers [0].
[chromium-blink-merge.git] / net / url_request / url_request_simple_job_unittest.cc
blobcf8e34a0be11ab8eb7f635fc2f7c46756b0dca15
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/memory/scoped_ptr.h"
6 #include "base/run_loop.h"
7 #include "base/strings/stringprintf.h"
8 #include "base/threading/sequenced_worker_pool.h"
9 #include "base/threading/worker_pool.h"
10 #include "net/base/request_priority.h"
11 #include "net/url_request/url_request_job.h"
12 #include "net/url_request/url_request_job_factory.h"
13 #include "net/url_request/url_request_job_factory_impl.h"
14 #include "net/url_request/url_request_simple_job.h"
15 #include "net/url_request/url_request_test_util.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 namespace net {
20 namespace {
22 const char kTestData[] = "Huge data array";
23 const int kRangeFirstPosition = 5;
24 const int kRangeLastPosition = 8;
25 static_assert(kRangeFirstPosition > 0 &&
26 kRangeFirstPosition < kRangeLastPosition &&
27 kRangeLastPosition <
28 static_cast<int>(arraysize(kTestData) - 1),
29 "invalid range");
31 // This function does nothing.
32 void DoNothing() {
35 class MockSimpleJob : public URLRequestSimpleJob {
36 public:
37 MockSimpleJob(URLRequest* request,
38 NetworkDelegate* network_delegate,
39 scoped_refptr<base::TaskRunner> task_runner,
40 std::string data)
41 : URLRequestSimpleJob(request, network_delegate),
42 data_(data),
43 task_runner_(task_runner) {}
45 protected:
46 // URLRequestSimpleJob implementation:
47 int GetData(std::string* mime_type,
48 std::string* charset,
49 std::string* data,
50 const CompletionCallback& callback) const override {
51 mime_type->assign("text/plain");
52 charset->assign("US-ASCII");
53 data->assign(data_);
54 return OK;
57 base::TaskRunner* GetTaskRunner() const override {
58 return task_runner_.get();
61 private:
62 ~MockSimpleJob() override {}
64 const std::string data_;
66 scoped_refptr<base::TaskRunner> task_runner_;
68 DISALLOW_COPY_AND_ASSIGN(MockSimpleJob);
71 class CancelURLRequestDelegate : public net::URLRequest::Delegate {
72 public:
73 explicit CancelURLRequestDelegate()
74 : buf_(new IOBuffer(kBufferSize)), run_loop_(new base::RunLoop) {}
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();
84 void OnReadCompleted(URLRequest* request, int bytes_read) override {}
86 void WaitUntilHeadersReceived() const { run_loop_->Run(); }
88 private:
89 static const int kBufferSize = 4096;
90 scoped_refptr<IOBuffer> buf_;
91 scoped_ptr<base::RunLoop> run_loop_;
94 class SimpleJobProtocolHandler :
95 public URLRequestJobFactory::ProtocolHandler {
96 public:
97 SimpleJobProtocolHandler(scoped_refptr<base::TaskRunner> task_runner)
98 : task_runner_(task_runner) {}
99 URLRequestJob* MaybeCreateJob(
100 URLRequest* request,
101 NetworkDelegate* network_delegate) const override {
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);
108 private:
109 scoped_refptr<base::TaskRunner> task_runner_;
111 ~SimpleJobProtocolHandler() override {}
114 class URLRequestSimpleJobTest : public ::testing::Test {
115 public:
116 URLRequestSimpleJobTest()
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_));
125 context_.set_job_factory(&job_factory_);
126 context_.Init();
128 request_ =
129 context_.CreateRequest(GURL("data:test"), DEFAULT_PRIORITY, &delegate_);
132 ~URLRequestSimpleJobTest() override { worker_pool_->Shutdown(); }
134 void StartRequest(const HttpRequestHeaders* headers) {
135 if (headers)
136 request_->SetExtraRequestHeaders(*headers);
137 request_->Start();
139 EXPECT_TRUE(request_->is_pending());
140 base::RunLoop().Run();
141 EXPECT_FALSE(request_->is_pending());
144 void TearDown() override { worker_pool_->Shutdown(); }
146 protected:
147 scoped_refptr<base::SequencedWorkerPool> worker_pool_;
148 scoped_refptr<base::SequencedTaskRunner> task_runner_;
149 TestURLRequestContext context_;
150 URLRequestJobFactoryImpl job_factory_;
151 TestDelegate delegate_;
152 scoped_ptr<URLRequest> request_;
155 } // namespace
157 TEST_F(URLRequestSimpleJobTest, SimpleRequest) {
158 StartRequest(NULL);
159 ASSERT_TRUE(request_->status().is_success());
160 EXPECT_EQ(kTestData, delegate_.data_received());
163 TEST_F(URLRequestSimpleJobTest, RangeRequest) {
164 const std::string kExpectedBody = std::string(
165 kTestData + kRangeFirstPosition, kTestData + kRangeLastPosition + 1);
166 HttpRequestHeaders headers;
167 headers.SetHeader(
168 HttpRequestHeaders::kRange,
169 HttpByteRange::Bounded(kRangeFirstPosition, kRangeLastPosition)
170 .GetHeaderValue());
172 StartRequest(&headers);
174 ASSERT_TRUE(request_->status().is_success());
175 EXPECT_EQ(kExpectedBody, delegate_.data_received());
178 TEST_F(URLRequestSimpleJobTest, MultipleRangeRequest) {
179 HttpRequestHeaders headers;
180 int middle_pos = (kRangeFirstPosition + kRangeLastPosition)/2;
181 std::string range = base::StringPrintf("bytes=%d-%d,%d-%d",
182 kRangeFirstPosition,
183 middle_pos,
184 middle_pos + 1,
185 kRangeLastPosition);
186 headers.SetHeader(HttpRequestHeaders::kRange, range);
188 StartRequest(&headers);
190 EXPECT_TRUE(delegate_.request_failed());
191 EXPECT_EQ(ERR_REQUEST_RANGE_NOT_SATISFIABLE, request_->status().error());
194 TEST_F(URLRequestSimpleJobTest, InvalidRangeRequest) {
195 HttpRequestHeaders headers;
196 std::string range = base::StringPrintf(
197 "bytes=%d-%d", kRangeLastPosition, kRangeFirstPosition);
198 headers.SetHeader(HttpRequestHeaders::kRange, range);
200 StartRequest(&headers);
202 ASSERT_TRUE(request_->status().is_success());
203 EXPECT_EQ(kTestData, delegate_.data_received());
206 TEST_F(URLRequestSimpleJobTest, EmptyDataRequest) {
207 request_ =
208 context_.CreateRequest(GURL("data:empty"), DEFAULT_PRIORITY, &delegate_);
209 StartRequest(nullptr);
210 ASSERT_TRUE(request_->status().is_success());
211 EXPECT_EQ("", delegate_.data_received());
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());
219 request_->Start();
220 cancel_delegate->WaitUntilHeadersReceived();
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();
230 } // namespace net