Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / mojo / services / network / url_loader_impl_apptest.cc
blob872485e775f3889e7e26a71f8ce6471988be7593
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.h"
6 #include "base/lazy_instance.h"
7 #include "base/memory/weak_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "mojo/application/public/cpp/application_test_base.h"
11 #include "mojo/common/message_pump_mojo.h"
12 #include "mojo/services/network/network_context.h"
13 #include "mojo/services/network/url_loader_impl.h"
14 #include "net/url_request/url_request_job.h"
15 #include "net/url_request/url_request_job_factory_impl.h"
16 #include "net/url_request/url_request_test_util.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
20 namespace mojo {
22 class TestURLRequestJob;
24 TestURLRequestJob* g_current_job = nullptr;
26 template <class A>
27 void PassA(A* destination, A value) {
28 *destination = value.Pass();
31 class TestURLRequestJob : public net::URLRequestJob {
32 public:
33 enum Status { CREATED, STARTED, READING, COMPLETED };
35 TestURLRequestJob(net::URLRequest* request,
36 net::NetworkDelegate* network_delegate)
37 : net::URLRequestJob(request, network_delegate),
38 status_(CREATED),
39 buf_size_(0) {
40 CHECK(!g_current_job);
41 g_current_job = this;
44 Status status() { return status_; }
46 int buf_size() { return buf_size_; }
48 void Start() override { status_ = STARTED; }
50 bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) override {
51 status_ = READING;
52 buf_size_ = buf_size;
53 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
54 return false;
57 void NotifyHeadersComplete() { net::URLRequestJob::NotifyHeadersComplete(); }
59 void NotifyReadComplete(int bytes_read) {
60 if (bytes_read < 0) {
61 status_ = COMPLETED;
62 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, 0));
63 net::URLRequestJob::NotifyReadComplete(0);
64 } else if (bytes_read == 0) {
65 status_ = COMPLETED;
66 NotifyDone(net::URLRequestStatus());
67 net::URLRequestJob::NotifyReadComplete(bytes_read);
68 } else {
69 status_ = STARTED;
70 SetStatus(net::URLRequestStatus());
71 net::URLRequestJob::NotifyReadComplete(bytes_read);
75 private:
76 ~TestURLRequestJob() override {
77 CHECK(g_current_job == this);
78 g_current_job = nullptr;
81 Status status_;
82 int buf_size_;
85 class TestProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
86 public:
87 net::URLRequestJob* MaybeCreateJob(
88 net::URLRequest* request,
89 net::NetworkDelegate* network_delegate) const override {
90 return new TestURLRequestJob(request, network_delegate);
93 private:
94 ~TestProtocolHandler() override {}
97 class UrlLoaderImplTest : public test::ApplicationTestBase {
98 public:
99 UrlLoaderImplTest() : message_loop_(common::MessagePumpMojo::Create()) {}
101 protected:
102 bool ShouldCreateDefaultRunLoop() override {
103 return false;
106 void SetUp() override {
107 ApplicationTestBase::SetUp();
109 scoped_ptr<net::TestURLRequestContext> url_request_context(
110 new net::TestURLRequestContext(true));
111 ASSERT_TRUE(url_request_job_factory_.SetProtocolHandler(
112 "http", new TestProtocolHandler()));
113 url_request_context->set_job_factory(&url_request_job_factory_);
114 url_request_context->Init();
115 network_context_.reset(new NetworkContext(url_request_context.Pass()));
116 MessagePipe pipe;
117 new URLLoaderImpl(network_context_.get(),
118 GetProxy(&url_loader_proxy_),
119 make_scoped_ptr<mojo::AppRefCount>(nullptr));
120 EXPECT_TRUE(IsUrlLoaderValid());
123 bool IsUrlLoaderValid() {
124 return network_context_->GetURLLoaderCountForTesting() > 0u;
127 base::MessageLoop message_loop_;
128 net::TestJobInterceptor* job_interceptor_;
129 net::URLRequestJobFactoryImpl url_request_job_factory_;
130 scoped_ptr<NetworkContext> network_context_;
131 URLLoaderPtr url_loader_proxy_;
134 TEST_F(UrlLoaderImplTest, ClosedBeforeAnyCall) {
135 url_loader_proxy_.reset();
136 base::RunLoop().RunUntilIdle();
138 EXPECT_FALSE(IsUrlLoaderValid());
141 TEST_F(UrlLoaderImplTest, ClosedWhileWaitingOnTheNetwork) {
142 URLRequestPtr request(URLRequest::New());
143 request->url = "http://example.com";
145 URLResponsePtr response;
146 url_loader_proxy_->Start(request.Pass(),
147 base::Bind(&PassA<URLResponsePtr>, &response));
148 base::RunLoop().RunUntilIdle();
150 EXPECT_TRUE(IsUrlLoaderValid());
151 EXPECT_FALSE(response);
152 ASSERT_TRUE(g_current_job);
154 g_current_job->NotifyHeadersComplete();
155 base::RunLoop().RunUntilIdle();
157 EXPECT_TRUE(IsUrlLoaderValid());
158 EXPECT_TRUE(response);
159 EXPECT_EQ(TestURLRequestJob::READING, g_current_job->status());
161 url_loader_proxy_.reset();
162 base::RunLoop().RunUntilIdle();
164 EXPECT_TRUE(IsUrlLoaderValid());
166 response.reset();
167 base::RunLoop().RunUntilIdle();
169 EXPECT_FALSE(IsUrlLoaderValid());
172 TEST_F(UrlLoaderImplTest, ClosedWhileWaitingOnThePipeToBeWriteable) {
173 URLRequestPtr request(URLRequest::New());
174 request->url = "http://example.com";
176 URLResponsePtr response;
177 url_loader_proxy_->Start(request.Pass(),
178 base::Bind(&PassA<URLResponsePtr>, &response));
179 base::RunLoop().RunUntilIdle();
181 EXPECT_TRUE(IsUrlLoaderValid());
182 EXPECT_FALSE(response);
183 ASSERT_TRUE(g_current_job);
185 g_current_job->NotifyHeadersComplete();
186 base::RunLoop().RunUntilIdle();
188 EXPECT_TRUE(IsUrlLoaderValid());
189 EXPECT_TRUE(response);
190 EXPECT_EQ(TestURLRequestJob::READING, g_current_job->status());
192 while (g_current_job->status() == TestURLRequestJob::READING) {
193 g_current_job->NotifyReadComplete(g_current_job->buf_size());
194 base::RunLoop().RunUntilIdle();
197 EXPECT_EQ(TestURLRequestJob::STARTED, g_current_job->status());
199 url_loader_proxy_.reset();
200 base::RunLoop().RunUntilIdle();
202 EXPECT_TRUE(IsUrlLoaderValid());
204 response.reset();
205 base::RunLoop().RunUntilIdle();
207 EXPECT_FALSE(IsUrlLoaderValid());
210 TEST_F(UrlLoaderImplTest, RequestCompleted) {
211 URLRequestPtr request(URLRequest::New());
212 request->url = "http://example.com";
214 URLResponsePtr response;
215 url_loader_proxy_->Start(request.Pass(),
216 base::Bind(&PassA<URLResponsePtr>, &response));
217 base::RunLoop().RunUntilIdle();
219 EXPECT_TRUE(IsUrlLoaderValid());
220 EXPECT_FALSE(response);
221 ASSERT_TRUE(g_current_job);
223 g_current_job->NotifyHeadersComplete();
224 base::RunLoop().RunUntilIdle();
226 EXPECT_TRUE(IsUrlLoaderValid());
227 EXPECT_TRUE(response);
228 EXPECT_EQ(TestURLRequestJob::READING, g_current_job->status());
230 url_loader_proxy_.reset();
231 base::RunLoop().RunUntilIdle();
233 EXPECT_TRUE(IsUrlLoaderValid());
235 g_current_job->NotifyReadComplete(0);
236 base::RunLoop().RunUntilIdle();
238 EXPECT_FALSE(IsUrlLoaderValid());
241 TEST_F(UrlLoaderImplTest, RequestFailed) {
242 URLRequestPtr request(URLRequest::New());
243 request->url = "http://example.com";
245 URLResponsePtr response;
246 url_loader_proxy_->Start(request.Pass(),
247 base::Bind(&PassA<URLResponsePtr>, &response));
248 base::RunLoop().RunUntilIdle();
250 EXPECT_TRUE(IsUrlLoaderValid());
251 EXPECT_FALSE(response);
252 ASSERT_TRUE(g_current_job);
254 g_current_job->NotifyHeadersComplete();
255 base::RunLoop().RunUntilIdle();
257 EXPECT_TRUE(IsUrlLoaderValid());
258 EXPECT_TRUE(response);
259 EXPECT_EQ(TestURLRequestJob::READING, g_current_job->status());
261 url_loader_proxy_.reset();
262 base::RunLoop().RunUntilIdle();
264 EXPECT_TRUE(IsUrlLoaderValid());
266 g_current_job->NotifyReadComplete(-1);
267 base::RunLoop().RunUntilIdle();
269 EXPECT_FALSE(IsUrlLoaderValid());
272 } // namespace mojo