blob: d1cda6dc4e582aaf9f1acb60912d2d5dae4f0879 [file] [log] [blame]
Julia Tuttle30b169652017-10-16 20:19:081// Copyright 2017 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.
4
5#include "components/domain_reliability/service.h"
6
7#include "base/logging.h"
8#include "base/message_loop/message_loop.h"
9#include "base/run_loop.h"
Gabriel Charette14520232018-04-30 23:27:2210#include "base/single_thread_task_runner.h"
Julia Tuttle30b169652017-10-16 20:19:0811#include "base/test/test_simple_task_runner.h"
12#include "base/time/time.h"
13#include "components/domain_reliability/monitor.h"
14#include "components/domain_reliability/test_util.h"
Lukasz Anforowicz58d0dac2018-03-23 15:48:1015#include "content/public/browser/browser_thread.h"
Julia Tuttle30b169652017-10-16 20:19:0816#include "content/public/browser/permission_manager.h"
Raymes Khoury4ead6c32018-03-07 04:43:4817#include "content/public/browser/web_contents.h"
Julia Tuttle30b169652017-10-16 20:19:0818#include "content/public/test/test_browser_context.h"
Lukasz Anforowicz58d0dac2018-03-23 15:48:1019#include "content/public/test/test_browser_thread_bundle.h"
20#include "content/public/test/test_utils.h"
Julia Tuttle30b169652017-10-16 20:19:0821#include "net/base/host_port_pair.h"
22#include "net/url_request/url_request_context_getter.h"
23#include "net/url_request/url_request_test_util.h"
24#include "testing/gtest/include/gtest/gtest.h"
Blink Reformata30d4232018-04-07 15:31:0625#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom.h"
Julia Tuttle30b169652017-10-16 20:19:0826
27namespace domain_reliability {
28
29namespace {
30
31class TestPermissionManager : public content::PermissionManager {
32 public:
33 TestPermissionManager() : get_permission_status_count_(0) {}
34
35 int get_permission_status_count() const {
36 return get_permission_status_count_;
37 }
38 content::PermissionType last_permission() const { return last_permission_; }
39 const GURL& last_requesting_origin() const { return last_requesting_origin_; }
40 const GURL& last_embedding_origin() const { return last_embedding_origin_; }
41
42 void set_permission_status(blink::mojom::PermissionStatus permission_status) {
43 permission_status_ = permission_status;
44 }
45
46 // content::PermissionManager:
47
48 ~TestPermissionManager() override {}
49
50 blink::mojom::PermissionStatus GetPermissionStatus(
51 content::PermissionType permission,
52 const GURL& requesting_origin,
53 const GURL& embedding_origin) override {
54 ++get_permission_status_count_;
55
56 last_permission_ = permission;
57 last_requesting_origin_ = requesting_origin;
58 last_embedding_origin_ = embedding_origin;
59
60 return permission_status_;
61 }
62
Raymes Khoury4ead6c32018-03-07 04:43:4863 blink::mojom::PermissionStatus GetPermissionStatusForFrame(
64 content::PermissionType permission,
65 content::RenderFrameHost* render_frame_host,
66 const GURL& requesting_origin) override {
67 return GetPermissionStatus(
68 permission, requesting_origin,
69 content::WebContents::FromRenderFrameHost(render_frame_host)
70 ->GetLastCommittedURL()
71 .GetOrigin());
72 }
73
Julia Tuttle30b169652017-10-16 20:19:0874 int RequestPermission(
75 content::PermissionType permission,
76 content::RenderFrameHost* render_frame_host,
77 const GURL& requesting_origin,
78 bool user_gesture,
79 const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
80 override {
81 NOTIMPLEMENTED();
82 return kNoPendingOperation;
83 }
84
85 int RequestPermissions(
86 const std::vector<content::PermissionType>& permission,
87 content::RenderFrameHost* render_frame_host,
88 const GURL& requesting_origin,
89 bool user_gesture,
90 const base::Callback<
91 void(const std::vector<blink::mojom::PermissionStatus>&)>& callback)
92 override {
93 NOTIMPLEMENTED();
94 return kNoPendingOperation;
95 }
96
Julia Tuttle30b169652017-10-16 20:19:0897 void ResetPermission(content::PermissionType permission,
98 const GURL& requesting_origin,
99 const GURL& embedding_origin) override {
100 NOTIMPLEMENTED();
101 }
102
103 int SubscribePermissionStatusChange(
104 content::PermissionType permission,
105 const GURL& requesting_origin,
106 const GURL& embedding_origin,
107 const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
108 override {
109 NOTIMPLEMENTED();
110 return 0;
111 }
112
113 void UnsubscribePermissionStatusChange(int subscription_id) override {
114 NOTIMPLEMENTED();
115 }
116
117 private:
118 // Number of calls made to GetPermissionStatus.
119 int get_permission_status_count_;
120
121 // Parameters to last call to GetPermissionStatus:
122
123 content::PermissionType last_permission_;
124 GURL last_requesting_origin_;
125 GURL last_embedding_origin_;
126
127 // Value to return from GetPermissionStatus.
128 blink::mojom::PermissionStatus permission_status_;
129
130 DISALLOW_COPY_AND_ASSIGN(TestPermissionManager);
131};
132
133} // namespace
134
135class DomainReliabilityServiceTest : public testing::Test {
136 protected:
137 using RequestInfo = DomainReliabilityMonitor::RequestInfo;
138
139 DomainReliabilityServiceTest()
140 : upload_reporter_string_("test"),
Lukasz Anforowicz58d0dac2018-03-23 15:48:10141 permission_manager_(new TestPermissionManager()) {
142 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner =
143 content::BrowserThread::GetTaskRunnerForThread(
144 content::BrowserThread::UI);
145 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner =
146 content::BrowserThread::GetTaskRunnerForThread(
147 content::BrowserThread::IO);
148 url_request_context_getter_ =
149 new net::TestURLRequestContextGetter(network_task_runner);
Julia Tuttle30b169652017-10-16 20:19:08150 browser_context_.SetPermissionManager(
151 base::WrapUnique(permission_manager_));
152 service_ = base::WrapUnique(DomainReliabilityService::Create(
153 upload_reporter_string_, &browser_context_));
Lukasz Anforowicz58d0dac2018-03-23 15:48:10154 monitor_ = service_->CreateMonitor(ui_task_runner, network_task_runner);
Julia Tuttle30b169652017-10-16 20:19:08155 monitor_->MoveToNetworkThread();
156 monitor_->InitURLRequestContext(url_request_context_getter_);
157 monitor_->SetDiscardUploads(true);
158 }
159
160 ~DomainReliabilityServiceTest() override {
161 if (monitor_)
162 monitor_->Shutdown();
163 }
164
165 void OnRequestLegComplete(RequestInfo request) {
166 monitor_->OnRequestLegComplete(request);
167 }
168
169 int GetDiscardedUploadCount() const {
170 return monitor_->uploader_->GetDiscardedUploadCount();
171 }
172
Lukasz Anforowicz58d0dac2018-03-23 15:48:10173 content::TestBrowserThreadBundle thread_bundle_;
Julia Tuttle30b169652017-10-16 20:19:08174
175 std::string upload_reporter_string_;
176
177 content::TestBrowserContext browser_context_;
178
179 // Owned by browser_context_, not the test class.
180 TestPermissionManager* permission_manager_;
181
182 std::unique_ptr<DomainReliabilityService> service_;
183
Julia Tuttle30b169652017-10-16 20:19:08184 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
185
186 std::unique_ptr<DomainReliabilityMonitor> monitor_;
187
188 private:
189 DISALLOW_COPY_AND_ASSIGN(DomainReliabilityServiceTest);
190};
191
192namespace {
193
194TEST_F(DomainReliabilityServiceTest, Create) {}
195
196TEST_F(DomainReliabilityServiceTest, UploadAllowed) {
197 permission_manager_->set_permission_status(
198 blink::mojom::PermissionStatus::GRANTED);
199
200 monitor_->AddContextForTesting(
201 MakeTestConfigWithOrigin(GURL("https://example/")));
202
203 RequestInfo request;
204 request.status =
205 net::URLRequestStatus::FromError(net::ERR_CONNECTION_REFUSED);
206 request.response_info.socket_address =
207 net::HostPortPair::FromString("1.2.3.4");
208 request.url = GURL("https://example/");
209 request.response_info.was_cached = false;
210 request.response_info.network_accessed = true;
211 request.response_info.was_fetched_via_proxy = false;
212 request.load_flags = 0;
213 request.load_timing_info.request_start = base::TimeTicks::Now();
214 request.upload_depth = 0;
215
216 OnRequestLegComplete(request);
217
218 monitor_->ForceUploadsForTesting();
219
Lukasz Anforowicz58d0dac2018-03-23 15:48:10220 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
Julia Tuttle30b169652017-10-16 20:19:08221 EXPECT_EQ(1, permission_manager_->get_permission_status_count());
222
Lukasz Anforowicz58d0dac2018-03-23 15:48:10223 content::RunAllPendingInMessageLoop(content::BrowserThread::IO);
Julia Tuttle30b169652017-10-16 20:19:08224 EXPECT_EQ(1, GetDiscardedUploadCount());
225}
226
227TEST_F(DomainReliabilityServiceTest, UploadForbidden) {
228 permission_manager_->set_permission_status(
229 blink::mojom::PermissionStatus::DENIED);
230
231 monitor_->AddContextForTesting(
232 MakeTestConfigWithOrigin(GURL("https://example/")));
233
234 RequestInfo request;
235 request.status =
236 net::URLRequestStatus::FromError(net::ERR_CONNECTION_REFUSED);
237 request.response_info.socket_address =
238 net::HostPortPair::FromString("1.2.3.4");
239 request.url = GURL("https://example/");
240 request.response_info.was_cached = false;
241 request.response_info.network_accessed = true;
242 request.response_info.was_fetched_via_proxy = false;
243 request.load_flags = 0;
244 request.load_timing_info.request_start = base::TimeTicks::Now();
245 request.upload_depth = 0;
246
247 OnRequestLegComplete(request);
248
249 monitor_->ForceUploadsForTesting();
250
Lukasz Anforowicz58d0dac2018-03-23 15:48:10251 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
Julia Tuttle30b169652017-10-16 20:19:08252 EXPECT_EQ(1, permission_manager_->get_permission_status_count());
253
Lukasz Anforowicz58d0dac2018-03-23 15:48:10254 content::RunAllPendingInMessageLoop(content::BrowserThread::IO);
Julia Tuttle30b169652017-10-16 20:19:08255 EXPECT_EQ(0, GetDiscardedUploadCount());
256}
257
258TEST_F(DomainReliabilityServiceTest, MonitorDestroyedBeforeCheckRuns) {
259 permission_manager_->set_permission_status(
260 blink::mojom::PermissionStatus::DENIED);
261
262 monitor_->AddContextForTesting(
263 MakeTestConfigWithOrigin(GURL("https://example/")));
264
265 RequestInfo request;
266 request.status =
267 net::URLRequestStatus::FromError(net::ERR_CONNECTION_REFUSED);
268 request.response_info.socket_address =
269 net::HostPortPair::FromString("1.2.3.4");
270 request.url = GURL("https://example/");
271 request.response_info.was_cached = false;
272 request.response_info.network_accessed = true;
273 request.response_info.was_fetched_via_proxy = false;
274 request.load_flags = 0;
275 request.load_timing_info.request_start = base::TimeTicks::Now();
276 request.upload_depth = 0;
277
278 OnRequestLegComplete(request);
279
280 monitor_->ForceUploadsForTesting();
281
282 monitor_->Shutdown();
283 monitor_.reset();
284
Lukasz Anforowicz58d0dac2018-03-23 15:48:10285 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
Julia Tuttle30b169652017-10-16 20:19:08286 EXPECT_EQ(1, permission_manager_->get_permission_status_count());
287
Lukasz Anforowicz58d0dac2018-03-23 15:48:10288 content::RunAllPendingInMessageLoop(content::BrowserThread::IO);
Julia Tuttle30b169652017-10-16 20:19:08289 // Makes no sense to check upload count, since monitor was destroyed.
290}
291
292TEST_F(DomainReliabilityServiceTest, MonitorDestroyedBeforeCheckReturns) {
293 permission_manager_->set_permission_status(
294 blink::mojom::PermissionStatus::DENIED);
295
296 monitor_->AddContextForTesting(
297 MakeTestConfigWithOrigin(GURL("https://example/")));
298
299 RequestInfo request;
300 request.status =
301 net::URLRequestStatus::FromError(net::ERR_CONNECTION_REFUSED);
302 request.response_info.socket_address =
303 net::HostPortPair::FromString("1.2.3.4");
304 request.url = GURL("https://example/");
305 request.response_info.was_cached = false;
306 request.response_info.network_accessed = true;
307 request.response_info.was_fetched_via_proxy = false;
308 request.load_flags = 0;
309 request.load_timing_info.request_start = base::TimeTicks::Now();
310 request.upload_depth = 0;
311
312 OnRequestLegComplete(request);
313
314 monitor_->ForceUploadsForTesting();
315
Lukasz Anforowicz58d0dac2018-03-23 15:48:10316 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
Julia Tuttle30b169652017-10-16 20:19:08317 EXPECT_EQ(1, permission_manager_->get_permission_status_count());
318
319 monitor_->Shutdown();
320 monitor_.reset();
321
Lukasz Anforowicz58d0dac2018-03-23 15:48:10322 content::RunAllPendingInMessageLoop(content::BrowserThread::IO);
Julia Tuttle30b169652017-10-16 20:19:08323 // Makes no sense to check upload count, since monitor was destroyed.
324}
325
326} // namespace
327
328} // namespace domain_reliability