blob: 065cd811b81306b25fbe03bc3181f1c6a9719485 [file] [log] [blame]
Chong Zhangc583e672017-11-08 16:34: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
Sebastien Marchandf8cbfab2019-01-25 16:02:305#include "base/bind.h"
Makoto Shimazu2075b0d2018-09-21 09:04:226#include "base/callback.h"
7#include "base/run_loop.h"
Christopher Thompson2a4c69e92019-08-21 16:29:118#include "base/strings/utf_string_conversions.h"
David Benjaminff93edd2019-06-19 22:51:589#include "base/synchronization/lock.h"
John Abd-El-Malek1f61a5fd2018-09-21 01:13:1410#include "base/test/bind_test_util.h"
Christopher Thompson2a4c69e92019-08-21 16:29:1111#include "base/test/metrics/histogram_tester.h"
12#include "base/test/scoped_command_line.h"
13#include "base/test/scoped_environment_variable_override.h"
Chong Zhang53047762018-05-02 21:24:0814#include "base/test/test_timeouts.h"
David Benjaminff93edd2019-06-19 22:51:5815#include "base/thread_annotations.h"
John Abd-El-Maleka7289152018-02-17 00:16:1916#include "base/threading/thread_restrictions.h"
Chong Zhangc583e672017-11-08 16:34:0817#include "build/build_config.h"
Chong Zhang7306b0b2018-01-24 05:59:2418#include "content/browser/frame_host/render_frame_host_impl.h"
John Abd-El-Malek1f61a5fd2018-09-21 01:13:1419#include "content/browser/frame_host/render_frame_message_filter.h"
John Abd-El-Malek984dc002019-05-29 01:26:5920#include "content/browser/network_service_instance_impl.h"
John Abd-El-Malek1f61a5fd2018-09-21 01:13:1421#include "content/browser/renderer_host/render_process_host_impl.h"
Makoto Shimazu2075b0d2018-09-21 09:04:2222#include "content/browser/service_worker/embedded_worker_instance.h"
23#include "content/browser/service_worker/embedded_worker_status.h"
24#include "content/browser/service_worker/service_worker_context_core_observer.h"
Chong Zhang5f468272017-12-07 23:59:1425#include "content/browser/storage_partition_impl.h"
Chong Zhangd4c923642018-01-03 21:22:2926#include "content/browser/url_loader_factory_getter.h"
Chong Zhang5f468272017-12-07 23:59:1427#include "content/public/browser/browser_context.h"
Gabriel Charette790754c2018-03-16 21:32:5928#include "content/public/browser/browser_thread.h"
Chong Zhangc583e672017-11-08 16:34:0829#include "content/public/browser/network_service_instance.h"
Ken Rockotfd03e682019-06-20 21:13:5430#include "content/public/browser/system_connector.h"
Chong Zhang5f468272017-12-07 23:59:1431#include "content/public/browser/web_contents.h"
Chong Zhang7306b0b2018-01-24 05:59:2432#include "content/public/common/content_switches.h"
Clark DuVall3290462e2019-02-16 02:19:5033#include "content/public/common/network_service_util.h"
Clark DuVallf742bcbd2018-11-07 17:16:2034#include "content/public/common/service_names.mojom.h"
Chong Zhangc40a6ce52017-12-10 03:00:2835#include "content/public/test/browser_test_utils.h"
Chong Zhangc583e672017-11-08 16:34:0836#include "content/public/test/content_browser_test.h"
37#include "content/public/test/content_browser_test_utils.h"
Chong Zhangd4c923642018-01-03 21:22:2938#include "content/public/test/simple_url_loader_test_helper.h"
Chong Zhang53047762018-05-02 21:24:0839#include "content/public/test/test_utils.h"
Chong Zhang5f468272017-12-07 23:59:1440#include "content/shell/browser/shell.h"
John Abd-El-Maleka7289152018-02-17 00:16:1941#include "content/shell/browser/shell_browser_context.h"
Chong Zhang83d0e4f2018-05-04 18:55:0942#include "content/test/storage_partition_test_utils.h"
Clark DuVallf742bcbd2018-11-07 17:16:2043#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
Chong Zhang7306b0b2018-01-24 05:59:2444#include "net/dns/mock_host_resolver.h"
45#include "net/test/embedded_test_server/http_request.h"
Chong Zhangd4c923642018-01-03 21:22:2946#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
John Abd-El-Malekbdafede2018-02-06 15:10:3647#include "services/network/public/cpp/simple_url_loader.h"
Ken Rockot54311e62018-02-10 19:01:5248#include "services/network/public/mojom/network_service.mojom.h"
Clark DuVallf742bcbd2018-11-07 17:16:2049#include "services/network/public/mojom/network_service_test.mojom.h"
50#include "services/service_manager/public/cpp/connector.h"
Chong Zhangc583e672017-11-08 16:34:0851
Lukasz Anforowiczce4487b72018-10-23 18:05:5352#if BUILDFLAG(ENABLE_PLUGINS)
53#include "content/public/test/ppapi_test_utils.h"
54#endif
55
Chong Zhangc583e672017-11-08 16:34:0856namespace content {
57
58namespace {
59
Chong Zhang4dd97ebf2018-03-07 04:48:4860using SharedURLLoaderFactoryGetterCallback =
Chong Zhangb7c8d1ce2018-03-13 19:14:1161 base::OnceCallback<scoped_refptr<network::SharedURLLoaderFactory>()>;
Chong Zhang4dd97ebf2018-03-07 04:48:4862
John Abd-El-Malek53670dd2018-01-18 22:07:2163network::mojom::NetworkContextPtr CreateNetworkContext() {
64 network::mojom::NetworkContextPtr network_context;
65 network::mojom::NetworkContextParamsPtr context_params =
66 network::mojom::NetworkContextParams::New();
Chong Zhangc583e672017-11-08 16:34:0867 GetNetworkService()->CreateNetworkContext(mojo::MakeRequest(&network_context),
68 std::move(context_params));
69 return network_context;
70}
71
John Abd-El-Maleka7289152018-02-17 00:16:1972int LoadBasicRequestOnUIThread(
73 network::mojom::URLLoaderFactory* url_loader_factory,
74 const GURL& url) {
75 DCHECK_CURRENTLY_ON(BrowserThread::UI);
76 auto request = std::make_unique<network::ResourceRequest>();
77 request->url = url;
78
79 SimpleURLLoaderTestHelper simple_loader_helper;
80 std::unique_ptr<network::SimpleURLLoader> simple_loader =
81 network::SimpleURLLoader::Create(std::move(request),
82 TRAFFIC_ANNOTATION_FOR_TESTS);
83 simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
84 url_loader_factory, simple_loader_helper.GetCallback());
85 simple_loader_helper.WaitForCallback();
86 return simple_loader->NetError();
87}
88
Chong Zhang53047762018-05-02 21:24:0889std::vector<network::mojom::NetworkUsagePtr> GetTotalNetworkUsages() {
90 std::vector<network::mojom::NetworkUsagePtr> network_usages;
91 base::RunLoop run_loop;
92 GetNetworkService()->GetTotalNetworkUsages(base::BindOnce(
93 [](std::vector<network::mojom::NetworkUsagePtr>* p_network_usages,
94 base::OnceClosure quit_closure,
95 std::vector<network::mojom::NetworkUsagePtr> returned_usages) {
96 *p_network_usages = std::move(returned_usages);
97 std::move(quit_closure).Run();
98 },
99 base::Unretained(&network_usages), run_loop.QuitClosure()));
100 run_loop.Run();
101 return network_usages;
102}
103
104bool CheckContainsProcessID(
105 const std::vector<network::mojom::NetworkUsagePtr>& usages,
106 int process_id) {
107 for (const auto& usage : usages) {
108 if ((int)usage->process_id == process_id)
109 return true;
110 }
111 return false;
112}
113
114// Wait until |condition| returns true.
115void WaitForCondition(base::RepeatingCallback<bool()> condition) {
116 while (!condition.Run()) {
117 base::RunLoop run_loop;
118 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
119 FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
120 run_loop.Run();
121 }
122}
123
Makoto Shimazu2075b0d2018-09-21 09:04:22124class ServiceWorkerStatusObserver : public ServiceWorkerContextCoreObserver {
125 public:
126 void WaitForState(EmbeddedWorkerStatus expected_status) {
Makoto Shimazu2540a642018-11-15 06:24:44127 for (const auto& status : statuses_in_past_) {
128 if (status == expected_status)
129 return;
130 }
Makoto Shimazu2075b0d2018-09-21 09:04:22131
132 expected_status_ = expected_status;
133 base::RunLoop loop;
134 callback_ = loop.QuitClosure();
135 loop.Run();
136 }
137
138 private:
139 void OnRunningStateChanged(int64_t version_id,
140 EmbeddedWorkerStatus running_status) override {
Makoto Shimazu2540a642018-11-15 06:24:44141 statuses_in_past_.push_back(running_status);
Makoto Shimazu2075b0d2018-09-21 09:04:22142 if (expected_status_.has_value() &&
143 running_status == expected_status_.value()) {
144 std::move(callback_).Run();
145 }
146 }
147
148 base::Optional<EmbeddedWorkerStatus> expected_status_;
Makoto Shimazu2540a642018-11-15 06:24:44149 std::vector<EmbeddedWorkerStatus> statuses_in_past_;
Makoto Shimazu2075b0d2018-09-21 09:04:22150 base::OnceClosure callback_;
151};
152
Chong Zhangc583e672017-11-08 16:34:08153} // namespace
154
Chong Zhangc583e672017-11-08 16:34:08155class NetworkServiceRestartBrowserTest : public ContentBrowserTest {
156 public:
John Abd-El-Malekc134dd82019-07-31 20:51:44157 NetworkServiceRestartBrowserTest() {}
Chong Zhang7306b0b2018-01-24 05:59:24158
Lukasz Anforowiczce4487b72018-10-23 18:05:53159 void SetUpCommandLine(base::CommandLine* command_line) override {
160#if BUILDFLAG(ENABLE_PLUGINS)
161 ASSERT_TRUE(ppapi::RegisterCorbTestPlugin(command_line));
162#endif
163 ContentBrowserTest::SetUpCommandLine(command_line);
164 }
165
Chong Zhang7306b0b2018-01-24 05:59:24166 void SetUpOnMainThread() override {
Chong Zhang5d9b34182018-01-30 16:20:57167 embedded_test_server()->RegisterRequestMonitor(
168 base::BindRepeating(&NetworkServiceRestartBrowserTest::MonitorRequest,
169 base::Unretained(this)));
Lukasz Anforowiczce4487b72018-10-23 18:05:53170 host_resolver()->AddRule("*", "127.0.0.1");
Chong Zhangc583e672017-11-08 16:34:08171 EXPECT_TRUE(embedded_test_server()->Start());
Chong Zhang7306b0b2018-01-24 05:59:24172 ContentBrowserTest::SetUpOnMainThread();
Chong Zhangc583e672017-11-08 16:34:08173 }
174
Chong Zhangc40a6ce52017-12-10 03:00:28175 GURL GetTestURL() const {
Chong Zhang5f468272017-12-07 23:59:14176 // Use '/echoheader' instead of '/echo' to avoid a disk_cache bug.
177 // See https://crbug.com/792255.
Chong Zhangc40a6ce52017-12-10 03:00:28178 return embedded_test_server()->GetURL("/echoheader");
Chong Zhangc583e672017-11-08 16:34:08179 }
180
Chong Zhangd4c923642018-01-03 21:22:29181 BrowserContext* browser_context() {
182 return shell()->web_contents()->GetBrowserContext();
183 }
184
Chong Zhang5d9b34182018-01-30 16:20:57185 RenderFrameHostImpl* main_frame() {
186 return static_cast<RenderFrameHostImpl*>(
187 shell()->web_contents()->GetMainFrame());
188 }
189
Chong Zhang53047762018-05-02 21:24:08190 bool CheckCanLoadHttp(Shell* shell, const std::string& relative_url) {
Chong Zhang5d9b34182018-01-30 16:20:57191 GURL test_url = embedded_test_server()->GetURL(relative_url);
192 std::string script(
193 "var xhr = new XMLHttpRequest();"
194 "xhr.open('GET', '");
195 script += test_url.spec() +
196 "', true);"
197 "xhr.onload = function (e) {"
198 " if (xhr.readyState === 4) {"
199 " window.domAutomationController.send(xhr.status === 200);"
200 " }"
201 "};"
202 "xhr.onerror = function () {"
203 " window.domAutomationController.send(false);"
204 "};"
205 "xhr.send(null)";
206 bool xhr_result = false;
207 // The JS call will fail if disallowed because the process will be killed.
208 bool execute_result =
Chong Zhang53047762018-05-02 21:24:08209 ExecuteScriptAndExtractBool(shell, script, &xhr_result);
Chong Zhang5d9b34182018-01-30 16:20:57210 return xhr_result && execute_result;
211 }
212
Chong Zhang4513fab2018-02-28 18:50:18213 // Will reuse the single opened windows through the test case.
214 bool CheckCanLoadHttpInWindowOpen(const std::string& relative_url) {
215 GURL test_url = embedded_test_server()->GetURL(relative_url);
216 std::string inject_script = base::StringPrintf(
217 "var xhr = new XMLHttpRequest();"
218 "xhr.open('GET', '%s', true);"
219 "xhr.onload = function (e) {"
220 " if (xhr.readyState === 4) {"
221 " window.opener.domAutomationController.send(xhr.status === 200);"
222 " }"
223 "};"
224 "xhr.onerror = function () {"
225 " window.opener.domAutomationController.send(false);"
226 "};"
227 "xhr.send(null)",
228 test_url.spec().c_str());
229 std::string window_open_script = base::StringPrintf(
230 "var new_window = new_window || window.open('');"
231 "var inject_script = document.createElement('script');"
232 "inject_script.innerHTML = \"%s\";"
233 "new_window.document.body.appendChild(inject_script);",
234 inject_script.c_str());
235
236 bool xhr_result = false;
237 // The JS call will fail if disallowed because the process will be killed.
238 bool execute_result =
239 ExecuteScriptAndExtractBool(shell(), window_open_script, &xhr_result);
240 return xhr_result && execute_result;
241 }
242
243 // Workers will live throughout the test case unless terminated.
244 bool CheckCanWorkerFetch(const std::string& worker_name,
245 const std::string& relative_url) {
246 GURL worker_url =
247 embedded_test_server()->GetURL("/workers/worker_common.js");
248 GURL fetch_url = embedded_test_server()->GetURL(relative_url);
249 std::string script = base::StringPrintf(
250 "var workers = workers || {};"
251 "var worker_name = '%s';"
252 "workers[worker_name] = workers[worker_name] || new Worker('%s');"
253 "workers[worker_name].onmessage = evt => {"
254 " if (evt.data != 'wait')"
255 " window.domAutomationController.send(evt.data === 200);"
256 "};"
257 "workers[worker_name].postMessage(\"eval "
258 " fetch(new Request('%s'))"
259 " .then(res => postMessage(res.status))"
260 " .catch(error => postMessage(error.toString()));"
261 " 'wait'"
262 "\");",
263 worker_name.c_str(), worker_url.spec().c_str(),
264 fetch_url.spec().c_str());
265 bool fetch_result = false;
266 // The JS call will fail if disallowed because the process will be killed.
267 bool execute_result =
268 ExecuteScriptAndExtractBool(shell(), script, &fetch_result);
269 return fetch_result && execute_result;
270 }
271
272 // Terminate and delete the worker.
273 bool TerminateWorker(const std::string& worker_name) {
274 std::string script = base::StringPrintf(
275 "var workers = workers || {};"
276 "var worker_name = '%s';"
277 "if (workers[worker_name]) {"
278 " workers[worker_name].terminate();"
279 " delete workers[worker_name];"
280 " window.domAutomationController.send(true);"
281 "} else {"
282 " window.domAutomationController.send(false);"
283 "}",
284 worker_name.c_str());
285 bool fetch_result = false;
286 // The JS call will fail if disallowed because the process will be killed.
287 bool execute_result =
288 ExecuteScriptAndExtractBool(shell(), script, &fetch_result);
289 return fetch_result && execute_result;
290 }
291
Chong Zhang5d9b34182018-01-30 16:20:57292 // Called by |embedded_test_server()|.
293 void MonitorRequest(const net::test_server::HttpRequest& request) {
David Benjaminff93edd2019-06-19 22:51:58294 base::AutoLock lock(last_request_lock_);
Chong Zhang5d9b34182018-01-30 16:20:57295 last_request_relative_url_ = request.relative_url;
296 }
297
298 std::string last_request_relative_url() const {
David Benjaminff93edd2019-06-19 22:51:58299 base::AutoLock lock(last_request_lock_);
Chong Zhang5d9b34182018-01-30 16:20:57300 return last_request_relative_url_;
301 }
302
Chong Zhangc583e672017-11-08 16:34:08303 private:
David Benjaminff93edd2019-06-19 22:51:58304 mutable base::Lock last_request_lock_;
305 std::string last_request_relative_url_ GUARDED_BY(last_request_lock_);
Chong Zhangc583e672017-11-08 16:34:08306
307 DISALLOW_COPY_AND_ASSIGN(NetworkServiceRestartBrowserTest);
308};
309
310IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
311 NetworkServiceProcessRecovery) {
Clark DuVall3290462e2019-02-16 02:19:50312 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36313 return;
John Abd-El-Malek53670dd2018-01-18 22:07:21314 network::mojom::NetworkContextPtr network_context = CreateNetworkContext();
Chong Zhangc40a6ce52017-12-10 03:00:28315 EXPECT_EQ(net::OK, LoadBasicRequest(network_context.get(), GetTestURL()));
Chong Zhangc583e672017-11-08 16:34:08316 EXPECT_TRUE(network_context.is_bound());
317 EXPECT_FALSE(network_context.encountered_error());
318
Chong Zhang5f468272017-12-07 23:59:14319 // Crash the NetworkService process. Existing interfaces should receive error
320 // notifications at some point.
Chong Zhangc583e672017-11-08 16:34:08321 SimulateNetworkServiceCrash();
Chong Zhang5f468272017-12-07 23:59:14322 // |network_context| will receive an error notification, but it's not
323 // guaranteed to have arrived at this point. Flush the pointer to make sure
324 // the notification has been received.
325 network_context.FlushForTesting();
Chong Zhangc583e672017-11-08 16:34:08326 EXPECT_TRUE(network_context.is_bound());
327 EXPECT_TRUE(network_context.encountered_error());
Chong Zhang5f468272017-12-07 23:59:14328 // Make sure we could get |net::ERR_FAILED| with an invalid |network_context|.
Chong Zhangc40a6ce52017-12-10 03:00:28329 EXPECT_EQ(net::ERR_FAILED,
330 LoadBasicRequest(network_context.get(), GetTestURL()));
Chong Zhangc583e672017-11-08 16:34:08331
332 // NetworkService should restart automatically and return valid interface.
John Abd-El-Malek53670dd2018-01-18 22:07:21333 network::mojom::NetworkContextPtr network_context2 = CreateNetworkContext();
Chong Zhangc40a6ce52017-12-10 03:00:28334 EXPECT_EQ(net::OK, LoadBasicRequest(network_context2.get(), GetTestURL()));
Chong Zhangc583e672017-11-08 16:34:08335 EXPECT_TRUE(network_context2.is_bound());
336 EXPECT_FALSE(network_context2.encountered_error());
337}
338
Lukasz Anforowiczce4487b72018-10-23 18:05:53339void IncrementInt(int* i) {
340 *i = *i + 1;
341}
342
343// This test verifies basic functionality of RegisterNetworkServiceCrashHandler
344// and UnregisterNetworkServiceCrashHandler.
345IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, CrashHandlers) {
Clark DuVall3290462e2019-02-16 02:19:50346 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36347 return;
Lukasz Anforowiczce4487b72018-10-23 18:05:53348 network::mojom::NetworkContextPtr network_context = CreateNetworkContext();
349 EXPECT_TRUE(network_context.is_bound());
350
351 // Register 2 crash handlers.
352 int counter1 = 0;
353 int counter2 = 0;
Lukasz Anforowiczc195e912018-10-30 16:20:54354 auto handler1 = RegisterNetworkServiceCrashHandler(
Lukasz Anforowiczce4487b72018-10-23 18:05:53355 base::BindRepeating(&IncrementInt, base::Unretained(&counter1)));
Lukasz Anforowiczc195e912018-10-30 16:20:54356 auto handler2 = RegisterNetworkServiceCrashHandler(
Lukasz Anforowiczce4487b72018-10-23 18:05:53357 base::BindRepeating(&IncrementInt, base::Unretained(&counter2)));
358
359 // Crash the NetworkService process.
360 SimulateNetworkServiceCrash();
361 // |network_context| will receive an error notification, but it's not
362 // guaranteed to have arrived at this point. Flush the pointer to make sure
363 // the notification has been received.
364 network_context.FlushForTesting();
365 EXPECT_TRUE(network_context.is_bound());
366 EXPECT_TRUE(network_context.encountered_error());
367
368 // Verify the crash handlers executed.
369 EXPECT_EQ(1, counter1);
370 EXPECT_EQ(1, counter2);
371
372 // Revive the NetworkService process.
373 network_context = CreateNetworkContext();
374 EXPECT_TRUE(network_context.is_bound());
375
376 // Unregister one of the handlers.
Lukasz Anforowiczc195e912018-10-30 16:20:54377 handler2.reset();
Lukasz Anforowiczce4487b72018-10-23 18:05:53378
379 // Crash the NetworkService process.
380 SimulateNetworkServiceCrash();
381 // |network_context| will receive an error notification, but it's not
382 // guaranteed to have arrived at this point. Flush the pointer to make sure
383 // the notification has been received.
384 network_context.FlushForTesting();
385 EXPECT_TRUE(network_context.is_bound());
386 EXPECT_TRUE(network_context.encountered_error());
387
388 // Verify only the first crash handler executed.
389 EXPECT_EQ(2, counter1);
390 EXPECT_EQ(1, counter2);
Lukasz Anforowiczce4487b72018-10-23 18:05:53391}
392
Chong Zhang5f468272017-12-07 23:59:14393// Make sure |StoragePartitionImpl::GetNetworkContext()| returns valid interface
394// after crash.
395IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
Chong Zhange0dfdb62017-12-09 18:25:14396 StoragePartitionImplGetNetworkContext) {
Clark DuVall3290462e2019-02-16 02:19:50397 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36398 return;
Chong Zhang5f468272017-12-07 23:59:14399 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
Chong Zhangd4c923642018-01-03 21:22:29400 BrowserContext::GetDefaultStoragePartition(browser_context()));
Chong Zhang5f468272017-12-07 23:59:14401
John Abd-El-Malek53670dd2018-01-18 22:07:21402 network::mojom::NetworkContext* old_network_context =
403 partition->GetNetworkContext();
Chong Zhangc40a6ce52017-12-10 03:00:28404 EXPECT_EQ(net::OK, LoadBasicRequest(old_network_context, GetTestURL()));
Chong Zhang5f468272017-12-07 23:59:14405
406 // Crash the NetworkService process. Existing interfaces should receive error
407 // notifications at some point.
408 SimulateNetworkServiceCrash();
409 // Flush the interface to make sure the error notification was received.
410 partition->FlushNetworkInterfaceForTesting();
411
412 // |partition->GetNetworkContext()| should return a valid new pointer after
413 // crash.
414 EXPECT_NE(old_network_context, partition->GetNetworkContext());
Chong Zhangc40a6ce52017-12-10 03:00:28415 EXPECT_EQ(net::OK,
416 LoadBasicRequest(partition->GetNetworkContext(), GetTestURL()));
Chong Zhang5f468272017-12-07 23:59:14417}
418
Chong Zhangd4c923642018-01-03 21:22:29419// Make sure |URLLoaderFactoryGetter| returns valid interface after crash.
420IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
421 URLLoaderFactoryGetterGetNetworkFactory) {
Clark DuVall3290462e2019-02-16 02:19:50422 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36423 return;
Chong Zhangd4c923642018-01-03 21:22:29424 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
425 BrowserContext::GetDefaultStoragePartition(browser_context()));
426 scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter =
427 partition->url_loader_factory_getter();
Chong Zhang5271432a2018-03-01 23:31:02428
Chong Zhang83d0e4f2018-05-04 18:55:09429 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
430 url_loader_factory_getter.get());
431 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02432
Chong Zhangd4c923642018-01-03 21:22:29433 // Crash the NetworkService process. Existing interfaces should receive error
434 // notifications at some point.
435 SimulateNetworkServiceCrash();
436 // Flush the interface to make sure the error notification was received.
437 partition->FlushNetworkInterfaceForTesting();
438 url_loader_factory_getter->FlushNetworkInterfaceOnIOThreadForTesting();
439
440 // |url_loader_factory_getter| should be able to get a valid new pointer after
441 // crash.
Chong Zhang83d0e4f2018-05-04 18:55:09442 factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
443 url_loader_factory_getter.get());
444 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02445}
446
447// Make sure the factory returned from
448// |URLLoaderFactoryGetter::GetNetworkFactory()| continues to work after
449// crashes.
450IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
451 BrowserIOSharedURLLoaderFactory) {
Clark DuVall3290462e2019-02-16 02:19:50452 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36453 return;
Chong Zhang5271432a2018-03-01 23:31:02454 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
455 BrowserContext::GetDefaultStoragePartition(browser_context()));
456
Chong Zhang83d0e4f2018-05-04 18:55:09457 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
458 partition->url_loader_factory_getter().get());
Chong Zhang5271432a2018-03-01 23:31:02459
Chong Zhang83d0e4f2018-05-04 18:55:09460 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02461
462 // Crash the NetworkService process. Existing interfaces should receive error
463 // notifications at some point.
464 SimulateNetworkServiceCrash();
465 // Flush the interface to make sure the error notification was received.
466 partition->FlushNetworkInterfaceForTesting();
467 partition->url_loader_factory_getter()
468 ->FlushNetworkInterfaceOnIOThreadForTesting();
469
470 // |shared_factory| should continue to work.
Chong Zhang83d0e4f2018-05-04 18:55:09471 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02472}
473
474// Make sure the factory returned from
475// |URLLoaderFactoryGetter::GetNetworkFactory()| doesn't crash if
476// it's called after the StoragePartition is deleted.
Chong Zhangf8572182018-03-16 23:10:18477IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
478 BrowserIOSharedFactoryAfterStoragePartitionGone) {
Clark DuVall3290462e2019-02-16 02:19:50479 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36480 return;
Chong Zhang5271432a2018-03-01 23:31:02481 base::ScopedAllowBlockingForTesting allow_blocking;
482 std::unique_ptr<ShellBrowserContext> browser_context =
Eric Romanb56d0ef2019-07-02 17:36:06483 std::make_unique<ShellBrowserContext>(true);
Chong Zhang5271432a2018-03-01 23:31:02484 auto* partition = static_cast<StoragePartitionImpl*>(
485 BrowserContext::GetDefaultStoragePartition(browser_context.get()));
Chong Zhang83d0e4f2018-05-04 18:55:09486 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
487 partition->url_loader_factory_getter().get());
Chong Zhang5271432a2018-03-01 23:31:02488
Chong Zhang83d0e4f2018-05-04 18:55:09489 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02490
491 browser_context.reset();
492
493 EXPECT_EQ(net::ERR_FAILED,
Chong Zhang83d0e4f2018-05-04 18:55:09494 factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhangd4c923642018-01-03 21:22:29495}
496
497// Make sure basic navigation works after crash.
498IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
499 NavigationURLLoaderBasic) {
Clark DuVall3290462e2019-02-16 02:19:50500 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36501 return;
Chong Zhangd4c923642018-01-03 21:22:29502 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
503 BrowserContext::GetDefaultStoragePartition(browser_context()));
504
505 EXPECT_TRUE(
506 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
507
508 // Crash the NetworkService process. Existing interfaces should receive error
509 // notifications at some point.
510 SimulateNetworkServiceCrash();
511 // Flush the interface to make sure the error notification was received.
512 partition->FlushNetworkInterfaceForTesting();
513 partition->url_loader_factory_getter()
514 ->FlushNetworkInterfaceOnIOThreadForTesting();
515
516 EXPECT_TRUE(
517 NavigateToURL(shell(), embedded_test_server()->GetURL("/title2.html")));
518}
519
Chong Zhang7306b0b2018-01-24 05:59:24520// Make sure basic XHR works after crash.
Chong Zhang5d9b34182018-01-30 16:20:57521IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BasicXHR) {
Clark DuVall3290462e2019-02-16 02:19:50522 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36523 return;
Chong Zhang7306b0b2018-01-24 05:59:24524 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
525 BrowserContext::GetDefaultStoragePartition(browser_context()));
526
Chong Zhang5d9b34182018-01-30 16:20:57527 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
Chong Zhang53047762018-05-02 21:24:08528 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title1.html"));
Chong Zhang7306b0b2018-01-24 05:59:24529 EXPECT_EQ(last_request_relative_url(), "/title1.html");
530
531 // Crash the NetworkService process. Existing interfaces should receive error
532 // notifications at some point.
533 SimulateNetworkServiceCrash();
534 // Flush the interface to make sure the error notification was received.
535 partition->FlushNetworkInterfaceForTesting();
536 // Flush the interface to make sure the frame host has received error
537 // notification and the new URLLoaderFactoryBundle has been received by the
538 // frame.
539 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
540
Chong Zhang53047762018-05-02 21:24:08541 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
Chong Zhang7306b0b2018-01-24 05:59:24542 EXPECT_EQ(last_request_relative_url(), "/title2.html");
543}
544
John Abd-El-Maleka7289152018-02-17 00:16:19545// Make sure the factory returned from
546// |StoragePartition::GetURLLoaderFactoryForBrowserProcess()| continues to work
547// after crashes.
548IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BrowserUIFactory) {
Clark DuVall3290462e2019-02-16 02:19:50549 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36550 return;
John Abd-El-Maleka7289152018-02-17 00:16:19551 auto* partition =
552 BrowserContext::GetDefaultStoragePartition(browser_context());
553 auto* factory = partition->GetURLLoaderFactoryForBrowserProcess().get();
554
555 EXPECT_EQ(net::OK, LoadBasicRequestOnUIThread(factory, GetTestURL()));
556
557 SimulateNetworkServiceCrash();
558 // Flush the interface to make sure the error notification was received.
559 partition->FlushNetworkInterfaceForTesting();
560
561 EXPECT_EQ(net::OK, LoadBasicRequestOnUIThread(factory, GetTestURL()));
562}
563
564// Make sure the factory returned from
565// |StoragePartition::GetURLLoaderFactoryForBrowserProcess()| doesn't crash if
566// it's called after the StoragePartition is deleted.
567IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
568 BrowserUIFactoryAfterStoragePartitionGone) {
Clark DuVall3290462e2019-02-16 02:19:50569 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36570 return;
John Abd-El-Maleka7289152018-02-17 00:16:19571 base::ScopedAllowBlockingForTesting allow_blocking;
572 std::unique_ptr<ShellBrowserContext> browser_context =
Eric Romanb56d0ef2019-07-02 17:36:06573 std::make_unique<ShellBrowserContext>(true);
John Abd-El-Maleka7289152018-02-17 00:16:19574 auto* partition =
575 BrowserContext::GetDefaultStoragePartition(browser_context.get());
Chong Zhangb7c8d1ce2018-03-13 19:14:11576 scoped_refptr<network::SharedURLLoaderFactory> factory(
John Abd-El-Maleka7289152018-02-17 00:16:19577 partition->GetURLLoaderFactoryForBrowserProcess());
578
579 EXPECT_EQ(net::OK, LoadBasicRequestOnUIThread(factory.get(), GetTestURL()));
580
581 browser_context.reset();
582
583 EXPECT_EQ(net::ERR_FAILED,
584 LoadBasicRequestOnUIThread(factory.get(), GetTestURL()));
585}
586
Chong Zhang83d0e4f2018-05-04 18:55:09587// Make sure the factory info returned from
588// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| can be
589// used after crashes.
Guido Urdaneta9cbbe382018-05-07 14:51:06590// Flaky on Windows. https://crbug.com/840127
591#if defined(OS_WIN)
592#define MAYBE_BrowserIOFactoryInfo DISABLED_BrowserIOFactoryInfo
593#else
594#define MAYBE_BrowserIOFactoryInfo BrowserIOFactoryInfo
595#endif
596IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
597 MAYBE_BrowserIOFactoryInfo) {
Clark DuVall3290462e2019-02-16 02:19:50598 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36599 return;
Chong Zhang4dd97ebf2018-03-07 04:48:48600 auto* partition =
601 BrowserContext::GetDefaultStoragePartition(browser_context());
Chong Zhang83d0e4f2018-05-04 18:55:09602 auto shared_url_loader_factory_info =
603 partition->GetURLLoaderFactoryForBrowserProcessIOThread();
Chong Zhang4dd97ebf2018-03-07 04:48:48604
605 SimulateNetworkServiceCrash();
606 // Flush the interface to make sure the error notification was received.
607 partition->FlushNetworkInterfaceForTesting();
608 static_cast<StoragePartitionImpl*>(partition)
609 ->url_loader_factory_getter()
610 ->FlushNetworkInterfaceOnIOThreadForTesting();
611
Chong Zhang83d0e4f2018-05-04 18:55:09612 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
613 std::move(shared_url_loader_factory_info));
614
615 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang4dd97ebf2018-03-07 04:48:48616}
617
Chong Zhang83d0e4f2018-05-04 18:55:09618// Make sure the factory constructed from
619// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| continues
620// to work after crashes.
621IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BrowserIOFactory) {
Clark DuVall3290462e2019-02-16 02:19:50622 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36623 return;
Chong Zhang4dd97ebf2018-03-07 04:48:48624 auto* partition =
Chong Zhang83d0e4f2018-05-04 18:55:09625 BrowserContext::GetDefaultStoragePartition(browser_context());
626 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
627 partition->GetURLLoaderFactoryForBrowserProcessIOThread());
Chong Zhang4dd97ebf2018-03-07 04:48:48628
Chong Zhang83d0e4f2018-05-04 18:55:09629 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang4dd97ebf2018-03-07 04:48:48630
Chong Zhang83d0e4f2018-05-04 18:55:09631 SimulateNetworkServiceCrash();
632 // Flush the interface to make sure the error notification was received.
633 partition->FlushNetworkInterfaceForTesting();
634 static_cast<StoragePartitionImpl*>(partition)
635 ->url_loader_factory_getter()
636 ->FlushNetworkInterfaceOnIOThreadForTesting();
Chong Zhang4dd97ebf2018-03-07 04:48:48637
Chong Zhang83d0e4f2018-05-04 18:55:09638 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang4dd97ebf2018-03-07 04:48:48639}
640
Chong Zhang4513fab2018-02-28 18:50:18641// Make sure the window from |window.open()| can load XHR after crash.
642IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, WindowOpenXHR) {
Clark DuVall3290462e2019-02-16 02:19:50643 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36644 return;
Chong Zhang4513fab2018-02-28 18:50:18645 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
646 BrowserContext::GetDefaultStoragePartition(browser_context()));
647
648 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
649 EXPECT_TRUE(CheckCanLoadHttpInWindowOpen("/title1.html"));
650 EXPECT_EQ(last_request_relative_url(), "/title1.html");
651
652 // Crash the NetworkService process. Existing interfaces should receive error
653 // notifications at some point.
654 SimulateNetworkServiceCrash();
655 // Flush the interface to make sure the error notification was received.
656 partition->FlushNetworkInterfaceForTesting();
657 // Flush the interface to make sure the frame host has received error
658 // notification and the new URLLoaderFactoryBundle has been received by the
659 // frame.
660 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
661
662 EXPECT_TRUE(CheckCanLoadHttpInWindowOpen("/title2.html"));
663 EXPECT_EQ(last_request_relative_url(), "/title2.html");
664}
665
666// Make sure worker fetch works after crash.
667IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, WorkerFetch) {
Clark DuVall3290462e2019-02-16 02:19:50668 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36669 return;
Chong Zhang4513fab2018-02-28 18:50:18670 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
671 BrowserContext::GetDefaultStoragePartition(browser_context()));
672
673 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
674 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title1.html"));
675 EXPECT_EQ(last_request_relative_url(), "/title1.html");
676
677 // Crash the NetworkService process. Existing interfaces should receive error
678 // notifications at some point.
679 SimulateNetworkServiceCrash();
680 // Flush the interface to make sure the error notification was received.
681 partition->FlushNetworkInterfaceForTesting();
682 // Flush the interface to make sure the frame host has received error
683 // notification and the new URLLoaderFactoryBundle has been received by the
684 // frame.
685 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
686
687 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title2.html"));
688 EXPECT_EQ(last_request_relative_url(), "/title2.html");
689}
690
691// Make sure multiple workers are tracked correctly and work after crash.
692IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, MultipleWorkerFetch) {
Clark DuVall3290462e2019-02-16 02:19:50693 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36694 return;
Chong Zhang4513fab2018-02-28 18:50:18695 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
696 BrowserContext::GetDefaultStoragePartition(browser_context()));
697
698 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
699 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title1.html"));
700 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title1.html"));
701 EXPECT_EQ(last_request_relative_url(), "/title1.html");
702
703 // Crash the NetworkService process. Existing interfaces should receive error
704 // notifications at some point.
705 SimulateNetworkServiceCrash();
706 // Flush the interface to make sure the error notification was received.
707 partition->FlushNetworkInterfaceForTesting();
708 // Flush the interface to make sure the frame host has received error
709 // notification and the new URLLoaderFactoryBundle has been received by the
710 // frame.
711 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
712
713 // Both workers should work after crash.
714 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title2.html"));
715 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title2.html"));
716 EXPECT_EQ(last_request_relative_url(), "/title2.html");
717
718 // Terminate "worker1". "worker2" shouldn't be affected.
719 EXPECT_TRUE(TerminateWorker("worker1"));
720 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title1.html"));
721 EXPECT_EQ(last_request_relative_url(), "/title1.html");
722
723 // Crash the NetworkService process again. "worker2" should still work.
724 SimulateNetworkServiceCrash();
725 partition->FlushNetworkInterfaceForTesting();
726 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
727
728 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title2.html"));
729 EXPECT_EQ(last_request_relative_url(), "/title2.html");
730}
731
Makoto Shimazu775101a52018-09-26 04:46:52732// Make sure fetch from a page controlled by a service worker which doesn't have
733// a fetch handler works after crash.
Makoto Shimazu2540a642018-11-15 06:24:44734IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
735 FetchFromServiceWorkerControlledPage_NoFetchHandler) {
Clark DuVall3290462e2019-02-16 02:19:50736 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36737 return;
Makoto Shimazu775101a52018-09-26 04:46:52738 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
739 BrowserContext::GetDefaultStoragePartition(browser_context()));
740 ServiceWorkerStatusObserver observer;
741 ServiceWorkerContextWrapper* service_worker_context =
742 partition->GetServiceWorkerContext();
743 service_worker_context->AddObserver(&observer);
744
745 // Register a service worker which controls /service_worker/.
746 EXPECT_TRUE(NavigateToURL(shell(),
747 embedded_test_server()->GetURL(
748 "/service_worker/create_service_worker.html")));
749 EXPECT_EQ("DONE", EvalJs(shell(), "register('empty.js')"));
750
751 // Navigate to a controlled page.
752 EXPECT_TRUE(NavigateToURL(
753 shell(),
754 embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
755
756 // Fetch from the controlled page.
757 const std::string script = "fetch_from_page('/echo');";
758 EXPECT_EQ("Echo", EvalJs(shell(), script));
759
760 // Crash the NetworkService process. Existing interfaces should receive error
761 // notifications at some point.
762 SimulateNetworkServiceCrash();
763 // Flush the interface to make sure the error notification was received.
764 partition->FlushNetworkInterfaceForTesting();
765
766 // Service worker should be stopped when network service crashes.
767 observer.WaitForState(EmbeddedWorkerStatus::STOPPED);
768
769 // Fetch from the controlled page again.
770 EXPECT_EQ("Echo", EvalJs(shell(), script));
771
772 service_worker_context->RemoveObserver(&observer);
773}
774
775// Make sure fetch from a page controlled by a service worker which has a fetch
776// handler but falls back to the network works after crash.
777IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
Makoto Shimazu2540a642018-11-15 06:24:44778 FetchFromServiceWorkerControlledPage_PassThrough) {
Clark DuVall3290462e2019-02-16 02:19:50779 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36780 return;
Makoto Shimazu775101a52018-09-26 04:46:52781 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
782 BrowserContext::GetDefaultStoragePartition(browser_context()));
783 ServiceWorkerStatusObserver observer;
784 ServiceWorkerContextWrapper* service_worker_context =
785 partition->GetServiceWorkerContext();
786 service_worker_context->AddObserver(&observer);
787
788 // Register a service worker which controls /service_worker/.
789 EXPECT_TRUE(NavigateToURL(shell(),
790 embedded_test_server()->GetURL(
791 "/service_worker/create_service_worker.html")));
792 EXPECT_EQ("DONE", EvalJs(shell(), "register('fetch_event_pass_through.js')"));
793
794 // Navigate to a controlled page.
795 EXPECT_TRUE(NavigateToURL(
796 shell(),
797 embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
798
799 // Fetch from the controlled page.
800 const std::string script = "fetch_from_page('/echo');";
801 EXPECT_EQ("Echo", EvalJs(shell(), script));
802
803 // Crash the NetworkService process. Existing interfaces should receive error
804 // notifications at some point.
805 SimulateNetworkServiceCrash();
806 // Flush the interface to make sure the error notification was received.
807 partition->FlushNetworkInterfaceForTesting();
808
809 // Service worker should be stopped when network service crashes.
810 observer.WaitForState(EmbeddedWorkerStatus::STOPPED);
811
812 // Fetch from the controlled page again.
813 EXPECT_EQ("Echo", EvalJs(shell(), script));
814
815 service_worker_context->RemoveObserver(&observer);
816}
817
818// Make sure fetch from a page controlled by a service worker which has a fetch
819// handler and responds with fetch() works after crash.
Makoto Shimazu2540a642018-11-15 06:24:44820IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
821 FetchFromServiceWorkerControlledPage_RespondWithFetch) {
Clark DuVall3290462e2019-02-16 02:19:50822 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36823 return;
Makoto Shimazu775101a52018-09-26 04:46:52824 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
825 BrowserContext::GetDefaultStoragePartition(browser_context()));
826 ServiceWorkerStatusObserver observer;
827 ServiceWorkerContextWrapper* service_worker_context =
828 partition->GetServiceWorkerContext();
829 service_worker_context->AddObserver(&observer);
830
831 // Register a service worker which controls /service_worker/.
832 EXPECT_TRUE(NavigateToURL(shell(),
833 embedded_test_server()->GetURL(
834 "/service_worker/create_service_worker.html")));
835 EXPECT_EQ("DONE",
836 EvalJs(shell(), "register('fetch_event_respond_with_fetch.js')"));
837
838 // Navigate to a controlled page.
839 EXPECT_TRUE(NavigateToURL(
840 shell(),
841 embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
842
843 // Fetch from the controlled page.
844 const std::string script = "fetch_from_page('/echo');";
845 EXPECT_EQ("Echo", EvalJs(shell(), script));
846
847 // Crash the NetworkService process. Existing interfaces should receive error
848 // notifications at some point.
849 SimulateNetworkServiceCrash();
850 // Flush the interface to make sure the error notification was received.
851 partition->FlushNetworkInterfaceForTesting();
852
853 // Service worker should be stopped when network service crashes.
854 observer.WaitForState(EmbeddedWorkerStatus::STOPPED);
855
856 // Fetch from the controlled page again.
857 EXPECT_EQ("Echo", EvalJs(shell(), script));
858
859 service_worker_context->RemoveObserver(&observer);
860}
861
Makoto Shimazu2075b0d2018-09-21 09:04:22862// Make sure fetch from service worker context works after crash.
Makoto Shimazu6a96cb62018-09-21 11:39:13863IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, ServiceWorkerFetch) {
Clark DuVall3290462e2019-02-16 02:19:50864 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36865 return;
Makoto Shimazu2075b0d2018-09-21 09:04:22866 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
867 BrowserContext::GetDefaultStoragePartition(browser_context()));
868 ServiceWorkerStatusObserver observer;
869 ServiceWorkerContextWrapper* service_worker_context =
870 partition->GetServiceWorkerContext();
871 service_worker_context->AddObserver(&observer);
872
873 const GURL page_url = embedded_test_server()->GetURL(
874 "/service_worker/fetch_from_service_worker.html");
875 const GURL fetch_url = embedded_test_server()->GetURL("/echo");
876
877 // Navigate to the page and register a service worker.
878 EXPECT_TRUE(NavigateToURL(shell(), page_url));
879 EXPECT_EQ("ready", EvalJs(shell(), "setup();"));
880
881 // Fetch from the service worker.
882 const std::string script =
883 "fetch_from_service_worker('" + fetch_url.spec() + "');";
884 EXPECT_EQ("Echo", EvalJs(shell(), script));
885
886 // Crash the NetworkService process. Existing interfaces should receive error
887 // notifications at some point.
888 SimulateNetworkServiceCrash();
889 // Flush the interface to make sure the error notification was received.
890 partition->FlushNetworkInterfaceForTesting();
891
892 // Service worker should be stopped when network service crashes.
893 observer.WaitForState(EmbeddedWorkerStatus::STOPPED);
894
895 // Fetch from the service worker again.
896 EXPECT_EQ("Echo", EvalJs(shell(), script));
897
898 service_worker_context->RemoveObserver(&observer);
899}
900
Clark DuVallf742bcbd2018-11-07 17:16:20901// TODO(crbug.com/154571): Shared workers are not available on Android.
902#if defined(OS_ANDROID)
903#define MAYBE_SharedWorker DISABLED_SharedWorker
904#else
905#define MAYBE_SharedWorker SharedWorker
906#endif
Matt Falkenhagene6721962018-10-05 10:17:05907// Make sure shared workers terminate after crash.
Clark DuVallf742bcbd2018-11-07 17:16:20908IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, MAYBE_SharedWorker) {
Clark DuVall3290462e2019-02-16 02:19:50909 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36910 return;
Makoto Shimazu2075b0d2018-09-21 09:04:22911 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
912 BrowserContext::GetDefaultStoragePartition(browser_context()));
913
914 const GURL page_url =
915 embedded_test_server()->GetURL("/workers/fetch_from_shared_worker.html");
916 const GURL fetch_url = embedded_test_server()->GetURL("/echo");
917
918 // Navigate to the page and prepare a shared worker.
919 EXPECT_TRUE(NavigateToURL(shell(), page_url));
920
Matt Falkenhagene6721962018-10-05 10:17:05921 // Fetch from the shared worker to ensure it has started.
Finditc0f7c6202018-10-05 07:14:23922 const std::string script =
923 "fetch_from_shared_worker('" + fetch_url.spec() + "');";
924 EXPECT_EQ("Echo", EvalJs(shell(), script));
Makoto Shimazu2075b0d2018-09-21 09:04:22925
Matt Falkenhagene6721962018-10-05 10:17:05926 // There should be one worker host. We will later wait for it to terminate.
927 SharedWorkerServiceImpl* service = partition->GetSharedWorkerService();
928 EXPECT_EQ(1u, service->worker_hosts_.size());
929 base::RunLoop loop;
930 service->SetWorkerTerminationCallbackForTesting(loop.QuitClosure());
Makoto Shimazu2075b0d2018-09-21 09:04:22931
Matt Falkenhagene6721962018-10-05 10:17:05932 // Crash the NetworkService process.
933 SimulateNetworkServiceCrash();
934
935 // Wait for the worker to detect the crash and self-terminate.
936 loop.Run();
937 EXPECT_TRUE(service->worker_hosts_.empty());
Makoto Shimazu2075b0d2018-09-21 09:04:22938}
939
Chong Zhang53047762018-05-02 21:24:08940// Make sure the entry in |NetworkService::GetTotalNetworkUsages()| was cleared
941// after process closed.
942IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
943 GetNetworkUsagesClosed) {
Clark DuVall3290462e2019-02-16 02:19:50944 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36945 return;
Chong Zhang53047762018-05-02 21:24:08946 EXPECT_TRUE(NavigateToURL(shell(), GetTestURL()));
947 Shell* shell2 = CreateBrowser();
948 EXPECT_TRUE(NavigateToURL(shell2, GetTestURL()));
949
950 int process_id1 =
951 shell()->web_contents()->GetMainFrame()->GetProcess()->GetID();
952 int process_id2 =
953 shell2->web_contents()->GetMainFrame()->GetProcess()->GetID();
954
955 // Load resource on the renderer to make sure the traffic was recorded.
956 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
957 EXPECT_TRUE(CheckCanLoadHttp(shell2, "/title3.html"));
958
959 // Both processes should have traffic recorded.
960 auto network_usages = GetTotalNetworkUsages();
961 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
962 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id2));
963
964 // Closing |shell2| should cause the entry to be cleared.
965 shell2->Close();
966 shell2 = nullptr;
967
968 // Wait until the Network Service has noticed the change. We don't have a
969 // better way to force a flush on the Network Service side.
970 WaitForCondition(base::BindRepeating(
971 [](int process_id) {
972 auto usages = GetTotalNetworkUsages();
973 return !CheckContainsProcessID(usages, process_id);
974 },
975 process_id2));
976
977 network_usages = GetTotalNetworkUsages();
978 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
979 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id2));
980}
981
Christopher Thompson2a4c69e92019-08-21 16:29:11982// Make sure that kSSLKeyLogFileHistogram is correctly recorded when the
983// network service instance is started and the SSLKEYLOGFILE env var is set or
984// the "--ssl-key-log-file" arg is set.
985IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, SSLKeyLogFileMetrics) {
986 if (IsInProcessNetworkService())
987 return;
988 // Actions on temporary files are blocking.
989 base::ScopedAllowBlockingForTesting scoped_allow_blocking;
990 base::FilePath log_file_path;
991 base::CreateTemporaryFile(&log_file_path);
992
993#if defined(OS_WIN)
994 // On Windows, FilePath::value() returns base::string16, so convert.
995 std::string log_file_path_str = base::UTF16ToUTF8(log_file_path.value());
996#else
997 std::string log_file_path_str = log_file_path.value();
998#endif
999
1000 // Test that env var causes the histogram to be recorded.
1001 {
1002 base::test::ScopedEnvironmentVariableOverride scoped_env("SSLKEYLOGFILE",
1003 log_file_path_str);
1004 base::HistogramTester histograms;
1005 // Restart network service to cause SSLKeyLogger to be re-initialized.
1006 SimulateNetworkServiceCrash();
1007 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1008 SSLKeyLogFileAction::kLogFileEnabled, 1);
1009 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1010 SSLKeyLogFileAction::kEnvVarFound, 1);
1011 }
1012
1013 // Test that the command-line switch causes the histogram to be recorded.
1014 {
1015 base::test::ScopedCommandLine scoped_command_line;
1016 scoped_command_line.GetProcessCommandLine()->AppendSwitchPath(
1017 "ssl-key-log-file", log_file_path);
1018 base::HistogramTester histograms;
1019 // Restart network service to cause SSLKeyLogger to be re-initialized.
1020 SimulateNetworkServiceCrash();
1021 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1022 SSLKeyLogFileAction::kLogFileEnabled, 1);
1023 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1024 SSLKeyLogFileAction::kSwitchFound, 1);
1025 }
1026}
1027
Chong Zhang53047762018-05-02 21:24:081028// Make sure |NetworkService::GetTotalNetworkUsages()| continues to work after
1029// crash. See 'network_usage_accumulator_unittest' for quantified tests.
1030IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
1031 GetNetworkUsagesCrashed) {
Clark DuVall3290462e2019-02-16 02:19:501032 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361033 return;
Chong Zhang53047762018-05-02 21:24:081034 EXPECT_TRUE(NavigateToURL(shell(), GetTestURL()));
1035 Shell* shell2 = CreateBrowser();
1036 EXPECT_TRUE(NavigateToURL(shell2, GetTestURL()));
1037
1038 int process_id1 =
1039 shell()->web_contents()->GetMainFrame()->GetProcess()->GetID();
1040 int process_id2 =
1041 shell2->web_contents()->GetMainFrame()->GetProcess()->GetID();
1042
1043 // Load resource on the renderer to make sure the traffic was recorded.
1044 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
1045 EXPECT_TRUE(CheckCanLoadHttp(shell2, "/title3.html"));
1046
1047 // Both processes should have traffic recorded.
1048 auto network_usages = GetTotalNetworkUsages();
1049 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
1050 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id2));
1051
1052 // Crashing Network Service should cause all entries to be cleared.
1053 SimulateNetworkServiceCrash();
1054 network_usages = GetTotalNetworkUsages();
1055 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id1));
1056 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id2));
1057
1058 // Should still be able to recored new traffic after crash.
1059 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
1060 network_usages = GetTotalNetworkUsages();
1061 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
1062 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id2));
1063}
1064
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141065// Make sure cookie access doesn't hang or fail after a network process crash.
1066IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, Cookies) {
Clark DuVall3290462e2019-02-16 02:19:501067 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361068 return;
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141069 auto* web_contents = shell()->web_contents();
Lukasz Anforowiczce4487b72018-10-23 18:05:531070 ASSERT_TRUE(
1071 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141072 EXPECT_TRUE(ExecuteScript(web_contents, "document.cookie = 'foo=bar';"));
1073
1074 std::string cookie;
1075 EXPECT_TRUE(ExecuteScriptAndExtractString(
1076 web_contents, "window.domAutomationController.send(document.cookie);",
1077 &cookie));
1078 EXPECT_EQ("foo=bar", cookie);
1079
1080 SimulateNetworkServiceCrash();
1081
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141082 // content_shell uses in-memory cookie database, so the value saved earlier
1083 // won't persist across crashes. What matters is that new access works.
1084 EXPECT_TRUE(ExecuteScript(web_contents, "document.cookie = 'foo=bar';"));
1085
1086 // This will hang without the fix.
1087 EXPECT_TRUE(ExecuteScriptAndExtractString(
1088 web_contents, "window.domAutomationController.send(document.cookie);",
1089 &cookie));
1090 EXPECT_EQ("foo=bar", cookie);
1091}
1092
Lukasz Anforowiczce4487b72018-10-23 18:05:531093#if BUILDFLAG(ENABLE_PLUGINS)
1094// Make sure that "trusted" plugins continue to be able to issue cross-origin
1095// requests after a network process crash.
1096IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, Plugin) {
Clark DuVall3290462e2019-02-16 02:19:501097 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361098 return;
Lukasz Anforowiczce4487b72018-10-23 18:05:531099 auto* web_contents = shell()->web_contents();
1100 ASSERT_TRUE(NavigateToURL(web_contents,
1101 embedded_test_server()->GetURL("/title1.html")));
1102
1103 // Load the test plugin (see ppapi::RegisterFlashTestPlugin and
1104 // ppapi/tests/power_saver_test_plugin.cc).
1105 const char kLoadingScript[] = R"(
1106 var obj = document.createElement('object');
1107 obj.id = 'plugin';
1108 obj.data = 'test.swf';
1109 obj.type = 'application/x-shockwave-flash';
1110 obj.width = 400;
1111 obj.height = 400;
1112
1113 document.body.appendChild(obj);
1114 )";
1115 ASSERT_TRUE(ExecJs(web_contents, kLoadingScript));
1116
1117 // Ask the plugin to perform a cross-origin, CORB-eligible (i.e.
1118 // application/json + nosniff) URL request. Plugins with universal access
1119 // should not be subject to CORS/CORB and so the request should go through.
1120 // See also https://crbug.com/874515 and https://crbug.com/846339.
1121 GURL cross_origin_url = embedded_test_server()->GetURL(
1122 "cross.origin.com", "/site_isolation/nosniff.json");
1123 const char kFetchScriptTemplate[] = R"(
1124 new Promise(function (resolve, reject) {
1125 var obj = document.getElementById('plugin');
1126 function callback(event) {
1127 // Ignore plugin messages unrelated to requestUrl.
1128 if (!event.data.startsWith('requestUrl: '))
1129 return;
1130
1131 obj.removeEventListener('message', callback);
1132 resolve('msg-from-plugin: ' + event.data);
1133 };
1134 obj.addEventListener('message', callback);
1135 obj.postMessage('requestUrl: ' + $1);
1136 });
1137 )";
1138 std::string fetch_script = JsReplace(kFetchScriptTemplate, cross_origin_url);
1139 ASSERT_EQ(
1140 "msg-from-plugin: requestUrl: RESPONSE BODY: "
1141 "runMe({ \"name\" : \"chromium\" });\n",
1142 EvalJs(web_contents, fetch_script));
1143
1144 // Crash the Network Service process and wait until host frame's
1145 // URLLoaderFactory has been refreshed.
1146 SimulateNetworkServiceCrash();
1147 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
1148
1149 // Try the fetch again - it should still work (i.e. the mechanism for relaxing
1150 // CORB for universal-access-plugins should be resilient to network process
1151 // crashes). See also https://crbug.com/891904.
1152 ASSERT_EQ(
1153 "msg-from-plugin: requestUrl: RESPONSE BODY: "
1154 "runMe({ \"name\" : \"chromium\" });\n",
1155 EvalJs(web_contents, fetch_script));
1156}
1157#endif
1158
Clark DuVallf742bcbd2018-11-07 17:16:201159// TODO(crbug.com/901026): Fix deadlock on process startup on Android.
1160#if defined(OS_ANDROID)
1161#define MAYBE_SyncCallDuringRestart DISABLED_SyncCallDuringRestart
1162#else
1163#define MAYBE_SyncCallDuringRestart SyncCallDuringRestart
1164#endif
1165IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
1166 MAYBE_SyncCallDuringRestart) {
Clark DuVall3290462e2019-02-16 02:19:501167 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361168 return;
Clark DuVallf742bcbd2018-11-07 17:16:201169 network::mojom::NetworkServiceTestPtr network_service_test;
1170 base::RunLoop run_loop;
Ken Rockotfd03e682019-06-20 21:13:541171 GetSystemConnector()->BindInterface(mojom::kNetworkServiceName,
1172 &network_service_test);
Clark DuVallf742bcbd2018-11-07 17:16:201173
1174 // Crash the network service, but do not wait for full startup.
1175 network_service_test.set_connection_error_handler(run_loop.QuitClosure());
1176 network_service_test->SimulateCrash();
1177 run_loop.Run();
1178
Ken Rockotfd03e682019-06-20 21:13:541179 GetSystemConnector()->BindInterface(mojom::kNetworkServiceName,
1180 &network_service_test);
Clark DuVallf742bcbd2018-11-07 17:16:201181
1182 // Sync call should be fine, even though network process is still starting up.
1183 mojo::ScopedAllowSyncCallForTesting allow_sync_call;
1184 network_service_test->AddRules({});
1185}
1186
Chong Zhangc583e672017-11-08 16:34:081187} // namespace content