blob: 94b43ac07f55bec862d2194948659ec57376d580 [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"
Hiroki Nakagawa3b90e642019-09-10 01:59:5814#include "base/test/scoped_feature_list.h"
Chong Zhang53047762018-05-02 21:24:0815#include "base/test/test_timeouts.h"
David Benjaminff93edd2019-06-19 22:51:5816#include "base/thread_annotations.h"
John Abd-El-Maleka7289152018-02-17 00:16:1917#include "base/threading/thread_restrictions.h"
Chong Zhangc583e672017-11-08 16:34:0818#include "build/build_config.h"
Chong Zhang7306b0b2018-01-24 05:59:2419#include "content/browser/frame_host/render_frame_host_impl.h"
John Abd-El-Malek1f61a5fd2018-09-21 01:13:1420#include "content/browser/frame_host/render_frame_message_filter.h"
John Abd-El-Malek984dc002019-05-29 01:26:5921#include "content/browser/network_service_instance_impl.h"
John Abd-El-Malek1f61a5fd2018-09-21 01:13:1422#include "content/browser/renderer_host/render_process_host_impl.h"
Makoto Shimazu2075b0d2018-09-21 09:04:2223#include "content/browser/service_worker/embedded_worker_instance.h"
24#include "content/browser/service_worker/embedded_worker_status.h"
25#include "content/browser/service_worker/service_worker_context_core_observer.h"
Chong Zhang5f468272017-12-07 23:59:1426#include "content/browser/storage_partition_impl.h"
Chong Zhangd4c923642018-01-03 21:22:2927#include "content/browser/url_loader_factory_getter.h"
Patrick Monette3f51a042019-08-30 17:57:0428#include "content/browser/worker_host/test_shared_worker_service_impl.h"
Chong Zhang5f468272017-12-07 23:59:1429#include "content/public/browser/browser_context.h"
Gabriel Charette790754c2018-03-16 21:32:5930#include "content/public/browser/browser_thread.h"
Chong Zhangc583e672017-11-08 16:34:0831#include "content/public/browser/network_service_instance.h"
Ken Rockotfd03e682019-06-20 21:13:5432#include "content/public/browser/system_connector.h"
Chong Zhang5f468272017-12-07 23:59:1433#include "content/public/browser/web_contents.h"
Chong Zhang7306b0b2018-01-24 05:59:2434#include "content/public/common/content_switches.h"
Clark DuVall3290462e2019-02-16 02:19:5035#include "content/public/common/network_service_util.h"
Clark DuVallf742bcbd2018-11-07 17:16:2036#include "content/public/common/service_names.mojom.h"
Chong Zhangc40a6ce52017-12-10 03:00:2837#include "content/public/test/browser_test_utils.h"
Chong Zhangc583e672017-11-08 16:34:0838#include "content/public/test/content_browser_test.h"
39#include "content/public/test/content_browser_test_utils.h"
Chong Zhangd4c923642018-01-03 21:22:2940#include "content/public/test/simple_url_loader_test_helper.h"
Chong Zhang53047762018-05-02 21:24:0841#include "content/public/test/test_utils.h"
Patrick Monette3f51a042019-08-30 17:57:0442#include "content/public/test/web_test_support.h"
Chong Zhang5f468272017-12-07 23:59:1443#include "content/shell/browser/shell.h"
John Abd-El-Maleka7289152018-02-17 00:16:1944#include "content/shell/browser/shell_browser_context.h"
Chong Zhang83d0e4f2018-05-04 18:55:0945#include "content/test/storage_partition_test_utils.h"
Julie Jeongeun Kim5984e992019-09-11 11:00:4646#include "mojo/public/cpp/bindings/pending_remote.h"
47#include "mojo/public/cpp/bindings/remote.h"
Clark DuVallf742bcbd2018-11-07 17:16:2048#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
Chong Zhang7306b0b2018-01-24 05:59:2449#include "net/dns/mock_host_resolver.h"
50#include "net/test/embedded_test_server/http_request.h"
Chong Zhangd4c923642018-01-03 21:22:2951#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
John Abd-El-Malekbdafede2018-02-06 15:10:3652#include "services/network/public/cpp/simple_url_loader.h"
Ken Rockot54311e62018-02-10 19:01:5253#include "services/network/public/mojom/network_service.mojom.h"
Clark DuVallf742bcbd2018-11-07 17:16:2054#include "services/network/public/mojom/network_service_test.mojom.h"
55#include "services/service_manager/public/cpp/connector.h"
Hiroki Nakagawa3b90e642019-09-10 01:59:5856#include "third_party/blink/public/common/features.h"
Chong Zhangc583e672017-11-08 16:34:0857
Lukasz Anforowiczce4487b72018-10-23 18:05:5358#if BUILDFLAG(ENABLE_PLUGINS)
59#include "content/public/test/ppapi_test_utils.h"
60#endif
61
Chong Zhangc583e672017-11-08 16:34:0862namespace content {
63
64namespace {
65
Chong Zhang4dd97ebf2018-03-07 04:48:4866using SharedURLLoaderFactoryGetterCallback =
Chong Zhangb7c8d1ce2018-03-13 19:14:1167 base::OnceCallback<scoped_refptr<network::SharedURLLoaderFactory>()>;
Chong Zhang4dd97ebf2018-03-07 04:48:4868
Julie Jeongeun Kim5984e992019-09-11 11:00:4669mojo::PendingRemote<network::mojom::NetworkContext> CreateNetworkContext() {
70 mojo::PendingRemote<network::mojom::NetworkContext> network_context;
John Abd-El-Malek53670dd2018-01-18 22:07:2171 network::mojom::NetworkContextParamsPtr context_params =
72 network::mojom::NetworkContextParams::New();
Julie Jeongeun Kim5984e992019-09-11 11:00:4673 GetNetworkService()->CreateNetworkContext(
74 network_context.InitWithNewPipeAndPassReceiver(),
75 std::move(context_params));
Chong Zhangc583e672017-11-08 16:34:0876 return network_context;
77}
78
John Abd-El-Maleka7289152018-02-17 00:16:1979int LoadBasicRequestOnUIThread(
80 network::mojom::URLLoaderFactory* url_loader_factory,
81 const GURL& url) {
82 DCHECK_CURRENTLY_ON(BrowserThread::UI);
83 auto request = std::make_unique<network::ResourceRequest>();
84 request->url = url;
85
86 SimpleURLLoaderTestHelper simple_loader_helper;
87 std::unique_ptr<network::SimpleURLLoader> simple_loader =
88 network::SimpleURLLoader::Create(std::move(request),
89 TRAFFIC_ANNOTATION_FOR_TESTS);
90 simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
91 url_loader_factory, simple_loader_helper.GetCallback());
92 simple_loader_helper.WaitForCallback();
93 return simple_loader->NetError();
94}
95
Chong Zhang53047762018-05-02 21:24:0896std::vector<network::mojom::NetworkUsagePtr> GetTotalNetworkUsages() {
97 std::vector<network::mojom::NetworkUsagePtr> network_usages;
98 base::RunLoop run_loop;
99 GetNetworkService()->GetTotalNetworkUsages(base::BindOnce(
100 [](std::vector<network::mojom::NetworkUsagePtr>* p_network_usages,
101 base::OnceClosure quit_closure,
102 std::vector<network::mojom::NetworkUsagePtr> returned_usages) {
103 *p_network_usages = std::move(returned_usages);
104 std::move(quit_closure).Run();
105 },
106 base::Unretained(&network_usages), run_loop.QuitClosure()));
107 run_loop.Run();
108 return network_usages;
109}
110
111bool CheckContainsProcessID(
112 const std::vector<network::mojom::NetworkUsagePtr>& usages,
113 int process_id) {
114 for (const auto& usage : usages) {
115 if ((int)usage->process_id == process_id)
116 return true;
117 }
118 return false;
119}
120
121// Wait until |condition| returns true.
122void WaitForCondition(base::RepeatingCallback<bool()> condition) {
123 while (!condition.Run()) {
124 base::RunLoop run_loop;
125 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
126 FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
127 run_loop.Run();
128 }
129}
130
Makoto Shimazu2075b0d2018-09-21 09:04:22131class ServiceWorkerStatusObserver : public ServiceWorkerContextCoreObserver {
132 public:
Patrick Monette9f3aae62019-10-08 00:16:03133 void WaitForStopped() {
134 if (stopped_)
135 return;
Makoto Shimazu2075b0d2018-09-21 09:04:22136
Makoto Shimazu2075b0d2018-09-21 09:04:22137 base::RunLoop loop;
138 callback_ = loop.QuitClosure();
139 loop.Run();
140 }
141
142 private:
Patrick Monette9f3aae62019-10-08 00:16:03143 void OnStopped(int64_t version_id) override {
144 stopped_ = true;
145
146 if (callback_)
Makoto Shimazu2075b0d2018-09-21 09:04:22147 std::move(callback_).Run();
Makoto Shimazu2075b0d2018-09-21 09:04:22148 }
149
Patrick Monette9f3aae62019-10-08 00:16:03150 bool stopped_ = false;
Makoto Shimazu2075b0d2018-09-21 09:04:22151 base::OnceClosure callback_;
152};
153
Chong Zhangc583e672017-11-08 16:34:08154} // namespace
155
Chong Zhangc583e672017-11-08 16:34:08156class NetworkServiceRestartBrowserTest : public ContentBrowserTest {
157 public:
John Abd-El-Malekc134dd82019-07-31 20:51:44158 NetworkServiceRestartBrowserTest() {}
Chong Zhang7306b0b2018-01-24 05:59:24159
Lukasz Anforowiczce4487b72018-10-23 18:05:53160 void SetUpCommandLine(base::CommandLine* command_line) override {
161#if BUILDFLAG(ENABLE_PLUGINS)
162 ASSERT_TRUE(ppapi::RegisterCorbTestPlugin(command_line));
163#endif
164 ContentBrowserTest::SetUpCommandLine(command_line);
165 }
166
Chong Zhang7306b0b2018-01-24 05:59:24167 void SetUpOnMainThread() override {
Chong Zhang5d9b34182018-01-30 16:20:57168 embedded_test_server()->RegisterRequestMonitor(
169 base::BindRepeating(&NetworkServiceRestartBrowserTest::MonitorRequest,
170 base::Unretained(this)));
Lukasz Anforowiczce4487b72018-10-23 18:05:53171 host_resolver()->AddRule("*", "127.0.0.1");
Chong Zhangc583e672017-11-08 16:34:08172 EXPECT_TRUE(embedded_test_server()->Start());
Chong Zhang7306b0b2018-01-24 05:59:24173 ContentBrowserTest::SetUpOnMainThread();
Chong Zhangc583e672017-11-08 16:34:08174 }
175
Chong Zhangc40a6ce52017-12-10 03:00:28176 GURL GetTestURL() const {
Chong Zhang5f468272017-12-07 23:59:14177 // Use '/echoheader' instead of '/echo' to avoid a disk_cache bug.
178 // See https://crbug.com/792255.
Chong Zhangc40a6ce52017-12-10 03:00:28179 return embedded_test_server()->GetURL("/echoheader");
Chong Zhangc583e672017-11-08 16:34:08180 }
181
Chong Zhangd4c923642018-01-03 21:22:29182 BrowserContext* browser_context() {
183 return shell()->web_contents()->GetBrowserContext();
184 }
185
Chong Zhang5d9b34182018-01-30 16:20:57186 RenderFrameHostImpl* main_frame() {
187 return static_cast<RenderFrameHostImpl*>(
188 shell()->web_contents()->GetMainFrame());
189 }
190
Chong Zhang53047762018-05-02 21:24:08191 bool CheckCanLoadHttp(Shell* shell, const std::string& relative_url) {
Chong Zhang5d9b34182018-01-30 16:20:57192 GURL test_url = embedded_test_server()->GetURL(relative_url);
193 std::string script(
194 "var xhr = new XMLHttpRequest();"
195 "xhr.open('GET', '");
196 script += test_url.spec() +
197 "', true);"
198 "xhr.onload = function (e) {"
199 " if (xhr.readyState === 4) {"
200 " window.domAutomationController.send(xhr.status === 200);"
201 " }"
202 "};"
203 "xhr.onerror = function () {"
204 " window.domAutomationController.send(false);"
205 "};"
206 "xhr.send(null)";
207 bool xhr_result = false;
208 // The JS call will fail if disallowed because the process will be killed.
209 bool execute_result =
Chong Zhang53047762018-05-02 21:24:08210 ExecuteScriptAndExtractBool(shell, script, &xhr_result);
Chong Zhang5d9b34182018-01-30 16:20:57211 return xhr_result && execute_result;
212 }
213
Chong Zhang4513fab2018-02-28 18:50:18214 // Will reuse the single opened windows through the test case.
215 bool CheckCanLoadHttpInWindowOpen(const std::string& relative_url) {
216 GURL test_url = embedded_test_server()->GetURL(relative_url);
217 std::string inject_script = base::StringPrintf(
218 "var xhr = new XMLHttpRequest();"
219 "xhr.open('GET', '%s', true);"
220 "xhr.onload = function (e) {"
221 " if (xhr.readyState === 4) {"
222 " window.opener.domAutomationController.send(xhr.status === 200);"
223 " }"
224 "};"
225 "xhr.onerror = function () {"
226 " window.opener.domAutomationController.send(false);"
227 "};"
228 "xhr.send(null)",
229 test_url.spec().c_str());
230 std::string window_open_script = base::StringPrintf(
231 "var new_window = new_window || window.open('');"
232 "var inject_script = document.createElement('script');"
233 "inject_script.innerHTML = \"%s\";"
234 "new_window.document.body.appendChild(inject_script);",
235 inject_script.c_str());
236
237 bool xhr_result = false;
238 // The JS call will fail if disallowed because the process will be killed.
239 bool execute_result =
240 ExecuteScriptAndExtractBool(shell(), window_open_script, &xhr_result);
241 return xhr_result && execute_result;
242 }
243
244 // Workers will live throughout the test case unless terminated.
245 bool CheckCanWorkerFetch(const std::string& worker_name,
246 const std::string& relative_url) {
247 GURL worker_url =
248 embedded_test_server()->GetURL("/workers/worker_common.js");
249 GURL fetch_url = embedded_test_server()->GetURL(relative_url);
250 std::string script = base::StringPrintf(
251 "var workers = workers || {};"
252 "var worker_name = '%s';"
253 "workers[worker_name] = workers[worker_name] || new Worker('%s');"
254 "workers[worker_name].onmessage = evt => {"
255 " if (evt.data != 'wait')"
256 " window.domAutomationController.send(evt.data === 200);"
257 "};"
258 "workers[worker_name].postMessage(\"eval "
259 " fetch(new Request('%s'))"
260 " .then(res => postMessage(res.status))"
261 " .catch(error => postMessage(error.toString()));"
262 " 'wait'"
263 "\");",
264 worker_name.c_str(), worker_url.spec().c_str(),
265 fetch_url.spec().c_str());
266 bool fetch_result = false;
267 // The JS call will fail if disallowed because the process will be killed.
268 bool execute_result =
269 ExecuteScriptAndExtractBool(shell(), script, &fetch_result);
270 return fetch_result && execute_result;
271 }
272
273 // Terminate and delete the worker.
274 bool TerminateWorker(const std::string& worker_name) {
275 std::string script = base::StringPrintf(
276 "var workers = workers || {};"
277 "var worker_name = '%s';"
278 "if (workers[worker_name]) {"
279 " workers[worker_name].terminate();"
280 " delete workers[worker_name];"
281 " window.domAutomationController.send(true);"
282 "} else {"
283 " window.domAutomationController.send(false);"
284 "}",
285 worker_name.c_str());
286 bool fetch_result = false;
287 // The JS call will fail if disallowed because the process will be killed.
288 bool execute_result =
289 ExecuteScriptAndExtractBool(shell(), script, &fetch_result);
290 return fetch_result && execute_result;
291 }
292
Chong Zhang5d9b34182018-01-30 16:20:57293 // Called by |embedded_test_server()|.
294 void MonitorRequest(const net::test_server::HttpRequest& request) {
David Benjaminff93edd2019-06-19 22:51:58295 base::AutoLock lock(last_request_lock_);
Chong Zhang5d9b34182018-01-30 16:20:57296 last_request_relative_url_ = request.relative_url;
297 }
298
299 std::string last_request_relative_url() const {
David Benjaminff93edd2019-06-19 22:51:58300 base::AutoLock lock(last_request_lock_);
Chong Zhang5d9b34182018-01-30 16:20:57301 return last_request_relative_url_;
302 }
303
Chong Zhangc583e672017-11-08 16:34:08304 private:
David Benjaminff93edd2019-06-19 22:51:58305 mutable base::Lock last_request_lock_;
306 std::string last_request_relative_url_ GUARDED_BY(last_request_lock_);
Chong Zhangc583e672017-11-08 16:34:08307
308 DISALLOW_COPY_AND_ASSIGN(NetworkServiceRestartBrowserTest);
309};
310
311IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
312 NetworkServiceProcessRecovery) {
Clark DuVall3290462e2019-02-16 02:19:50313 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36314 return;
Julie Jeongeun Kim5984e992019-09-11 11:00:46315 mojo::Remote<network::mojom::NetworkContext> network_context(
316 CreateNetworkContext());
Chong Zhangc40a6ce52017-12-10 03:00:28317 EXPECT_EQ(net::OK, LoadBasicRequest(network_context.get(), GetTestURL()));
Chong Zhangc583e672017-11-08 16:34:08318 EXPECT_TRUE(network_context.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46319 EXPECT_TRUE(network_context.is_connected());
Chong Zhangc583e672017-11-08 16:34:08320
Chong Zhang5f468272017-12-07 23:59:14321 // Crash the NetworkService process. Existing interfaces should receive error
322 // notifications at some point.
Chong Zhangc583e672017-11-08 16:34:08323 SimulateNetworkServiceCrash();
Chong Zhang5f468272017-12-07 23:59:14324 // |network_context| will receive an error notification, but it's not
Julie Jeongeun Kim5984e992019-09-11 11:00:46325 // guaranteed to have arrived at this point. Flush the remote to make sure
Chong Zhang5f468272017-12-07 23:59:14326 // the notification has been received.
327 network_context.FlushForTesting();
Chong Zhangc583e672017-11-08 16:34:08328 EXPECT_TRUE(network_context.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46329 EXPECT_FALSE(network_context.is_connected());
Chong Zhang5f468272017-12-07 23:59:14330 // Make sure we could get |net::ERR_FAILED| with an invalid |network_context|.
Chong Zhangc40a6ce52017-12-10 03:00:28331 EXPECT_EQ(net::ERR_FAILED,
332 LoadBasicRequest(network_context.get(), GetTestURL()));
Chong Zhangc583e672017-11-08 16:34:08333
334 // NetworkService should restart automatically and return valid interface.
Julie Jeongeun Kim5984e992019-09-11 11:00:46335 mojo::Remote<network::mojom::NetworkContext> network_context2(
336 CreateNetworkContext());
Chong Zhangc40a6ce52017-12-10 03:00:28337 EXPECT_EQ(net::OK, LoadBasicRequest(network_context2.get(), GetTestURL()));
Chong Zhangc583e672017-11-08 16:34:08338 EXPECT_TRUE(network_context2.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46339 EXPECT_TRUE(network_context2.is_connected());
Chong Zhangc583e672017-11-08 16:34:08340}
341
Lukasz Anforowiczce4487b72018-10-23 18:05:53342void IncrementInt(int* i) {
343 *i = *i + 1;
344}
345
346// This test verifies basic functionality of RegisterNetworkServiceCrashHandler
347// and UnregisterNetworkServiceCrashHandler.
348IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, CrashHandlers) {
Clark DuVall3290462e2019-02-16 02:19:50349 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36350 return;
Julie Jeongeun Kim5984e992019-09-11 11:00:46351 mojo::Remote<network::mojom::NetworkContext> network_context(
352 CreateNetworkContext());
Lukasz Anforowiczce4487b72018-10-23 18:05:53353 EXPECT_TRUE(network_context.is_bound());
354
355 // Register 2 crash handlers.
356 int counter1 = 0;
357 int counter2 = 0;
Lukasz Anforowiczc195e912018-10-30 16:20:54358 auto handler1 = RegisterNetworkServiceCrashHandler(
Lukasz Anforowiczce4487b72018-10-23 18:05:53359 base::BindRepeating(&IncrementInt, base::Unretained(&counter1)));
Lukasz Anforowiczc195e912018-10-30 16:20:54360 auto handler2 = RegisterNetworkServiceCrashHandler(
Lukasz Anforowiczce4487b72018-10-23 18:05:53361 base::BindRepeating(&IncrementInt, base::Unretained(&counter2)));
362
363 // Crash the NetworkService process.
364 SimulateNetworkServiceCrash();
365 // |network_context| will receive an error notification, but it's not
Julie Jeongeun Kim5984e992019-09-11 11:00:46366 // guaranteed to have arrived at this point. Flush the remote to make sure
Lukasz Anforowiczce4487b72018-10-23 18:05:53367 // the notification has been received.
368 network_context.FlushForTesting();
369 EXPECT_TRUE(network_context.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46370 EXPECT_FALSE(network_context.is_connected());
Lukasz Anforowiczce4487b72018-10-23 18:05:53371
372 // Verify the crash handlers executed.
373 EXPECT_EQ(1, counter1);
374 EXPECT_EQ(1, counter2);
375
376 // Revive the NetworkService process.
Julie Jeongeun Kim5984e992019-09-11 11:00:46377 network_context.reset();
378 network_context.Bind(CreateNetworkContext());
Lukasz Anforowiczce4487b72018-10-23 18:05:53379 EXPECT_TRUE(network_context.is_bound());
380
381 // Unregister one of the handlers.
Lukasz Anforowiczc195e912018-10-30 16:20:54382 handler2.reset();
Lukasz Anforowiczce4487b72018-10-23 18:05:53383
384 // Crash the NetworkService process.
385 SimulateNetworkServiceCrash();
386 // |network_context| will receive an error notification, but it's not
Julie Jeongeun Kim5984e992019-09-11 11:00:46387 // guaranteed to have arrived at this point. Flush the remote to make sure
Lukasz Anforowiczce4487b72018-10-23 18:05:53388 // the notification has been received.
389 network_context.FlushForTesting();
390 EXPECT_TRUE(network_context.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46391 EXPECT_FALSE(network_context.is_connected());
Lukasz Anforowiczce4487b72018-10-23 18:05:53392
393 // Verify only the first crash handler executed.
394 EXPECT_EQ(2, counter1);
395 EXPECT_EQ(1, counter2);
Lukasz Anforowiczce4487b72018-10-23 18:05:53396}
397
Chong Zhang5f468272017-12-07 23:59:14398// Make sure |StoragePartitionImpl::GetNetworkContext()| returns valid interface
399// after crash.
400IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
Chong Zhange0dfdb62017-12-09 18:25:14401 StoragePartitionImplGetNetworkContext) {
Clark DuVall3290462e2019-02-16 02:19:50402 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36403 return;
Chong Zhang5f468272017-12-07 23:59:14404 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
Chong Zhangd4c923642018-01-03 21:22:29405 BrowserContext::GetDefaultStoragePartition(browser_context()));
Chong Zhang5f468272017-12-07 23:59:14406
John Abd-El-Malek53670dd2018-01-18 22:07:21407 network::mojom::NetworkContext* old_network_context =
408 partition->GetNetworkContext();
Chong Zhangc40a6ce52017-12-10 03:00:28409 EXPECT_EQ(net::OK, LoadBasicRequest(old_network_context, GetTestURL()));
Chong Zhang5f468272017-12-07 23:59:14410
411 // Crash the NetworkService process. Existing interfaces should receive error
412 // notifications at some point.
413 SimulateNetworkServiceCrash();
414 // Flush the interface to make sure the error notification was received.
415 partition->FlushNetworkInterfaceForTesting();
416
417 // |partition->GetNetworkContext()| should return a valid new pointer after
418 // crash.
419 EXPECT_NE(old_network_context, partition->GetNetworkContext());
Chong Zhangc40a6ce52017-12-10 03:00:28420 EXPECT_EQ(net::OK,
421 LoadBasicRequest(partition->GetNetworkContext(), GetTestURL()));
Chong Zhang5f468272017-12-07 23:59:14422}
423
Chong Zhangd4c923642018-01-03 21:22:29424// Make sure |URLLoaderFactoryGetter| returns valid interface after crash.
425IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
426 URLLoaderFactoryGetterGetNetworkFactory) {
Clark DuVall3290462e2019-02-16 02:19:50427 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36428 return;
Chong Zhangd4c923642018-01-03 21:22:29429 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
430 BrowserContext::GetDefaultStoragePartition(browser_context()));
431 scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter =
432 partition->url_loader_factory_getter();
Chong Zhang5271432a2018-03-01 23:31:02433
Chong Zhang83d0e4f2018-05-04 18:55:09434 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
435 url_loader_factory_getter.get());
436 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02437
Chong Zhangd4c923642018-01-03 21:22:29438 // Crash the NetworkService process. Existing interfaces should receive error
439 // notifications at some point.
440 SimulateNetworkServiceCrash();
441 // Flush the interface to make sure the error notification was received.
442 partition->FlushNetworkInterfaceForTesting();
443 url_loader_factory_getter->FlushNetworkInterfaceOnIOThreadForTesting();
444
445 // |url_loader_factory_getter| should be able to get a valid new pointer after
446 // crash.
Chong Zhang83d0e4f2018-05-04 18:55:09447 factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
448 url_loader_factory_getter.get());
449 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02450}
451
452// Make sure the factory returned from
453// |URLLoaderFactoryGetter::GetNetworkFactory()| continues to work after
454// crashes.
455IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
456 BrowserIOSharedURLLoaderFactory) {
Clark DuVall3290462e2019-02-16 02:19:50457 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36458 return;
Chong Zhang5271432a2018-03-01 23:31:02459 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
460 BrowserContext::GetDefaultStoragePartition(browser_context()));
461
Chong Zhang83d0e4f2018-05-04 18:55:09462 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
463 partition->url_loader_factory_getter().get());
Chong Zhang5271432a2018-03-01 23:31:02464
Chong Zhang83d0e4f2018-05-04 18:55:09465 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02466
467 // Crash the NetworkService process. Existing interfaces should receive error
468 // notifications at some point.
469 SimulateNetworkServiceCrash();
470 // Flush the interface to make sure the error notification was received.
471 partition->FlushNetworkInterfaceForTesting();
472 partition->url_loader_factory_getter()
473 ->FlushNetworkInterfaceOnIOThreadForTesting();
474
475 // |shared_factory| should continue to work.
Chong Zhang83d0e4f2018-05-04 18:55:09476 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02477}
478
479// Make sure the factory returned from
480// |URLLoaderFactoryGetter::GetNetworkFactory()| doesn't crash if
481// it's called after the StoragePartition is deleted.
Chong Zhangf8572182018-03-16 23:10:18482IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
483 BrowserIOSharedFactoryAfterStoragePartitionGone) {
Clark DuVall3290462e2019-02-16 02:19:50484 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36485 return;
Chong Zhang5271432a2018-03-01 23:31:02486 base::ScopedAllowBlockingForTesting allow_blocking;
487 std::unique_ptr<ShellBrowserContext> browser_context =
Eric Romanb56d0ef2019-07-02 17:36:06488 std::make_unique<ShellBrowserContext>(true);
Chong Zhang5271432a2018-03-01 23:31:02489 auto* partition = static_cast<StoragePartitionImpl*>(
490 BrowserContext::GetDefaultStoragePartition(browser_context.get()));
Chong Zhang83d0e4f2018-05-04 18:55:09491 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
492 partition->url_loader_factory_getter().get());
Chong Zhang5271432a2018-03-01 23:31:02493
Chong Zhang83d0e4f2018-05-04 18:55:09494 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02495
496 browser_context.reset();
497
498 EXPECT_EQ(net::ERR_FAILED,
Chong Zhang83d0e4f2018-05-04 18:55:09499 factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhangd4c923642018-01-03 21:22:29500}
501
502// Make sure basic navigation works after crash.
503IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
504 NavigationURLLoaderBasic) {
Clark DuVall3290462e2019-02-16 02:19:50505 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36506 return;
Chong Zhangd4c923642018-01-03 21:22:29507 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
508 BrowserContext::GetDefaultStoragePartition(browser_context()));
509
510 EXPECT_TRUE(
511 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
512
513 // Crash the NetworkService process. Existing interfaces should receive error
514 // notifications at some point.
515 SimulateNetworkServiceCrash();
516 // Flush the interface to make sure the error notification was received.
517 partition->FlushNetworkInterfaceForTesting();
518 partition->url_loader_factory_getter()
519 ->FlushNetworkInterfaceOnIOThreadForTesting();
520
521 EXPECT_TRUE(
522 NavigateToURL(shell(), embedded_test_server()->GetURL("/title2.html")));
523}
524
Chong Zhang7306b0b2018-01-24 05:59:24525// Make sure basic XHR works after crash.
Chong Zhang5d9b34182018-01-30 16:20:57526IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BasicXHR) {
Clark DuVall3290462e2019-02-16 02:19:50527 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36528 return;
Chong Zhang7306b0b2018-01-24 05:59:24529 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
530 BrowserContext::GetDefaultStoragePartition(browser_context()));
531
Chong Zhang5d9b34182018-01-30 16:20:57532 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
Chong Zhang53047762018-05-02 21:24:08533 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title1.html"));
Chong Zhang7306b0b2018-01-24 05:59:24534 EXPECT_EQ(last_request_relative_url(), "/title1.html");
535
536 // Crash the NetworkService process. Existing interfaces should receive error
537 // notifications at some point.
538 SimulateNetworkServiceCrash();
539 // Flush the interface to make sure the error notification was received.
540 partition->FlushNetworkInterfaceForTesting();
541 // Flush the interface to make sure the frame host has received error
542 // notification and the new URLLoaderFactoryBundle has been received by the
543 // frame.
544 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
545
Chong Zhang53047762018-05-02 21:24:08546 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
Chong Zhang7306b0b2018-01-24 05:59:24547 EXPECT_EQ(last_request_relative_url(), "/title2.html");
548}
549
John Abd-El-Maleka7289152018-02-17 00:16:19550// Make sure the factory returned from
551// |StoragePartition::GetURLLoaderFactoryForBrowserProcess()| continues to work
552// after crashes.
553IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BrowserUIFactory) {
Clark DuVall3290462e2019-02-16 02:19:50554 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36555 return;
John Abd-El-Maleka7289152018-02-17 00:16:19556 auto* partition =
557 BrowserContext::GetDefaultStoragePartition(browser_context());
558 auto* factory = partition->GetURLLoaderFactoryForBrowserProcess().get();
559
560 EXPECT_EQ(net::OK, LoadBasicRequestOnUIThread(factory, GetTestURL()));
561
562 SimulateNetworkServiceCrash();
563 // Flush the interface to make sure the error notification was received.
564 partition->FlushNetworkInterfaceForTesting();
565
566 EXPECT_EQ(net::OK, LoadBasicRequestOnUIThread(factory, GetTestURL()));
567}
568
569// Make sure the factory returned from
570// |StoragePartition::GetURLLoaderFactoryForBrowserProcess()| doesn't crash if
571// it's called after the StoragePartition is deleted.
572IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
573 BrowserUIFactoryAfterStoragePartitionGone) {
Clark DuVall3290462e2019-02-16 02:19:50574 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36575 return;
John Abd-El-Maleka7289152018-02-17 00:16:19576 base::ScopedAllowBlockingForTesting allow_blocking;
577 std::unique_ptr<ShellBrowserContext> browser_context =
Eric Romanb56d0ef2019-07-02 17:36:06578 std::make_unique<ShellBrowserContext>(true);
John Abd-El-Maleka7289152018-02-17 00:16:19579 auto* partition =
580 BrowserContext::GetDefaultStoragePartition(browser_context.get());
Chong Zhangb7c8d1ce2018-03-13 19:14:11581 scoped_refptr<network::SharedURLLoaderFactory> factory(
John Abd-El-Maleka7289152018-02-17 00:16:19582 partition->GetURLLoaderFactoryForBrowserProcess());
583
584 EXPECT_EQ(net::OK, LoadBasicRequestOnUIThread(factory.get(), GetTestURL()));
585
586 browser_context.reset();
587
588 EXPECT_EQ(net::ERR_FAILED,
589 LoadBasicRequestOnUIThread(factory.get(), GetTestURL()));
590}
591
Chong Zhang83d0e4f2018-05-04 18:55:09592// Make sure the factory info returned from
593// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| can be
594// used after crashes.
Guido Urdaneta9cbbe382018-05-07 14:51:06595// Flaky on Windows. https://crbug.com/840127
596#if defined(OS_WIN)
597#define MAYBE_BrowserIOFactoryInfo DISABLED_BrowserIOFactoryInfo
598#else
599#define MAYBE_BrowserIOFactoryInfo BrowserIOFactoryInfo
600#endif
601IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
602 MAYBE_BrowserIOFactoryInfo) {
Clark DuVall3290462e2019-02-16 02:19:50603 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36604 return;
Chong Zhang4dd97ebf2018-03-07 04:48:48605 auto* partition =
606 BrowserContext::GetDefaultStoragePartition(browser_context());
Chong Zhang83d0e4f2018-05-04 18:55:09607 auto shared_url_loader_factory_info =
608 partition->GetURLLoaderFactoryForBrowserProcessIOThread();
Chong Zhang4dd97ebf2018-03-07 04:48:48609
610 SimulateNetworkServiceCrash();
611 // Flush the interface to make sure the error notification was received.
612 partition->FlushNetworkInterfaceForTesting();
613 static_cast<StoragePartitionImpl*>(partition)
614 ->url_loader_factory_getter()
615 ->FlushNetworkInterfaceOnIOThreadForTesting();
616
Chong Zhang83d0e4f2018-05-04 18:55:09617 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
618 std::move(shared_url_loader_factory_info));
619
620 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang4dd97ebf2018-03-07 04:48:48621}
622
Chong Zhang83d0e4f2018-05-04 18:55:09623// Make sure the factory constructed from
624// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| continues
625// to work after crashes.
626IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BrowserIOFactory) {
Clark DuVall3290462e2019-02-16 02:19:50627 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36628 return;
Chong Zhang4dd97ebf2018-03-07 04:48:48629 auto* partition =
Chong Zhang83d0e4f2018-05-04 18:55:09630 BrowserContext::GetDefaultStoragePartition(browser_context());
631 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
632 partition->GetURLLoaderFactoryForBrowserProcessIOThread());
Chong Zhang4dd97ebf2018-03-07 04:48:48633
Chong Zhang83d0e4f2018-05-04 18:55:09634 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang4dd97ebf2018-03-07 04:48:48635
Chong Zhang83d0e4f2018-05-04 18:55:09636 SimulateNetworkServiceCrash();
637 // Flush the interface to make sure the error notification was received.
638 partition->FlushNetworkInterfaceForTesting();
639 static_cast<StoragePartitionImpl*>(partition)
640 ->url_loader_factory_getter()
641 ->FlushNetworkInterfaceOnIOThreadForTesting();
Chong Zhang4dd97ebf2018-03-07 04:48:48642
Chong Zhang83d0e4f2018-05-04 18:55:09643 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang4dd97ebf2018-03-07 04:48:48644}
645
Chong Zhang4513fab2018-02-28 18:50:18646// Make sure the window from |window.open()| can load XHR after crash.
647IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, WindowOpenXHR) {
Clark DuVall3290462e2019-02-16 02:19:50648 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36649 return;
Chong Zhang4513fab2018-02-28 18:50:18650 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
651 BrowserContext::GetDefaultStoragePartition(browser_context()));
652
653 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
654 EXPECT_TRUE(CheckCanLoadHttpInWindowOpen("/title1.html"));
655 EXPECT_EQ(last_request_relative_url(), "/title1.html");
656
657 // Crash the NetworkService process. Existing interfaces should receive error
658 // notifications at some point.
659 SimulateNetworkServiceCrash();
660 // Flush the interface to make sure the error notification was received.
661 partition->FlushNetworkInterfaceForTesting();
662 // Flush the interface to make sure the frame host has received error
663 // notification and the new URLLoaderFactoryBundle has been received by the
664 // frame.
665 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
666
667 EXPECT_TRUE(CheckCanLoadHttpInWindowOpen("/title2.html"));
668 EXPECT_EQ(last_request_relative_url(), "/title2.html");
669}
670
Hiroki Nakagawa3b90e642019-09-10 01:59:58671// Run tests with PlzDedicatedWorker.
672// TODO(https://crbug.com/906991): Merge this test fixture into
673// NetworkServiceRestartBrowserTest once PlzDedicatedWorker is enabled by
674// default.
675class NetworkServiceRestartForWorkerBrowserTest
676 : public NetworkServiceRestartBrowserTest,
677 public ::testing::WithParamInterface<bool> {
678 public:
679 NetworkServiceRestartForWorkerBrowserTest() {
680 if (GetParam()) {
681 scoped_feature_list_.InitAndEnableFeature(
682 blink::features::kPlzDedicatedWorker);
683 } else {
684 scoped_feature_list_.InitAndDisableFeature(
685 blink::features::kPlzDedicatedWorker);
686 }
687 }
688
689 private:
690 base::test::ScopedFeatureList scoped_feature_list_;
691};
692
693INSTANTIATE_TEST_SUITE_P(,
694 NetworkServiceRestartForWorkerBrowserTest,
695 ::testing::Values(false, true));
696
Chong Zhang4513fab2018-02-28 18:50:18697// Make sure worker fetch works after crash.
Hiroki Nakagawa3b90e642019-09-10 01:59:58698IN_PROC_BROWSER_TEST_P(NetworkServiceRestartForWorkerBrowserTest, WorkerFetch) {
Clark DuVall3290462e2019-02-16 02:19:50699 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36700 return;
Chong Zhang4513fab2018-02-28 18:50:18701 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
702 BrowserContext::GetDefaultStoragePartition(browser_context()));
703
704 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
705 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title1.html"));
706 EXPECT_EQ(last_request_relative_url(), "/title1.html");
707
708 // Crash the NetworkService process. Existing interfaces should receive error
709 // notifications at some point.
710 SimulateNetworkServiceCrash();
711 // Flush the interface to make sure the error notification was received.
712 partition->FlushNetworkInterfaceForTesting();
713 // Flush the interface to make sure the frame host has received error
714 // notification and the new URLLoaderFactoryBundle has been received by the
715 // frame.
716 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
717
718 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title2.html"));
719 EXPECT_EQ(last_request_relative_url(), "/title2.html");
720}
721
722// Make sure multiple workers are tracked correctly and work after crash.
Hiroki Nakagawa3b90e642019-09-10 01:59:58723IN_PROC_BROWSER_TEST_P(NetworkServiceRestartForWorkerBrowserTest,
724 MultipleWorkerFetch) {
Clark DuVall3290462e2019-02-16 02:19:50725 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36726 return;
Chong Zhang4513fab2018-02-28 18:50:18727 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
728 BrowserContext::GetDefaultStoragePartition(browser_context()));
729
730 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
731 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title1.html"));
732 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title1.html"));
733 EXPECT_EQ(last_request_relative_url(), "/title1.html");
734
735 // Crash the NetworkService process. Existing interfaces should receive error
736 // notifications at some point.
737 SimulateNetworkServiceCrash();
738 // Flush the interface to make sure the error notification was received.
739 partition->FlushNetworkInterfaceForTesting();
740 // Flush the interface to make sure the frame host has received error
741 // notification and the new URLLoaderFactoryBundle has been received by the
742 // frame.
743 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
744
745 // Both workers should work after crash.
746 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title2.html"));
747 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title2.html"));
748 EXPECT_EQ(last_request_relative_url(), "/title2.html");
749
750 // Terminate "worker1". "worker2" shouldn't be affected.
751 EXPECT_TRUE(TerminateWorker("worker1"));
752 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title1.html"));
753 EXPECT_EQ(last_request_relative_url(), "/title1.html");
754
755 // Crash the NetworkService process again. "worker2" should still work.
756 SimulateNetworkServiceCrash();
757 partition->FlushNetworkInterfaceForTesting();
758 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
759
760 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title2.html"));
761 EXPECT_EQ(last_request_relative_url(), "/title2.html");
762}
763
Makoto Shimazu775101a52018-09-26 04:46:52764// Make sure fetch from a page controlled by a service worker which doesn't have
765// a fetch handler works after crash.
Makoto Shimazu2540a642018-11-15 06:24:44766IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
767 FetchFromServiceWorkerControlledPage_NoFetchHandler) {
Clark DuVall3290462e2019-02-16 02:19:50768 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36769 return;
Makoto Shimazu775101a52018-09-26 04:46:52770 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
771 BrowserContext::GetDefaultStoragePartition(browser_context()));
772 ServiceWorkerStatusObserver observer;
773 ServiceWorkerContextWrapper* service_worker_context =
774 partition->GetServiceWorkerContext();
775 service_worker_context->AddObserver(&observer);
776
777 // Register a service worker which controls /service_worker/.
778 EXPECT_TRUE(NavigateToURL(shell(),
779 embedded_test_server()->GetURL(
780 "/service_worker/create_service_worker.html")));
781 EXPECT_EQ("DONE", EvalJs(shell(), "register('empty.js')"));
782
783 // Navigate to a controlled page.
784 EXPECT_TRUE(NavigateToURL(
785 shell(),
786 embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
787
788 // Fetch from the controlled page.
789 const std::string script = "fetch_from_page('/echo');";
790 EXPECT_EQ("Echo", EvalJs(shell(), script));
791
792 // Crash the NetworkService process. Existing interfaces should receive error
793 // notifications at some point.
794 SimulateNetworkServiceCrash();
795 // Flush the interface to make sure the error notification was received.
796 partition->FlushNetworkInterfaceForTesting();
797
798 // Service worker should be stopped when network service crashes.
Patrick Monette9f3aae62019-10-08 00:16:03799 observer.WaitForStopped();
Makoto Shimazu775101a52018-09-26 04:46:52800
801 // Fetch from the controlled page again.
802 EXPECT_EQ("Echo", EvalJs(shell(), script));
803
804 service_worker_context->RemoveObserver(&observer);
805}
806
807// Make sure fetch from a page controlled by a service worker which has a fetch
808// handler but falls back to the network works after crash.
809IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
Makoto Shimazu2540a642018-11-15 06:24:44810 FetchFromServiceWorkerControlledPage_PassThrough) {
Clark DuVall3290462e2019-02-16 02:19:50811 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36812 return;
Makoto Shimazu775101a52018-09-26 04:46:52813 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
814 BrowserContext::GetDefaultStoragePartition(browser_context()));
815 ServiceWorkerStatusObserver observer;
816 ServiceWorkerContextWrapper* service_worker_context =
817 partition->GetServiceWorkerContext();
818 service_worker_context->AddObserver(&observer);
819
820 // Register a service worker which controls /service_worker/.
821 EXPECT_TRUE(NavigateToURL(shell(),
822 embedded_test_server()->GetURL(
823 "/service_worker/create_service_worker.html")));
824 EXPECT_EQ("DONE", EvalJs(shell(), "register('fetch_event_pass_through.js')"));
825
826 // Navigate to a controlled page.
827 EXPECT_TRUE(NavigateToURL(
828 shell(),
829 embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
830
831 // Fetch from the controlled page.
832 const std::string script = "fetch_from_page('/echo');";
833 EXPECT_EQ("Echo", EvalJs(shell(), script));
834
835 // Crash the NetworkService process. Existing interfaces should receive error
836 // notifications at some point.
837 SimulateNetworkServiceCrash();
838 // Flush the interface to make sure the error notification was received.
839 partition->FlushNetworkInterfaceForTesting();
840
841 // Service worker should be stopped when network service crashes.
Patrick Monette9f3aae62019-10-08 00:16:03842 observer.WaitForStopped();
Makoto Shimazu775101a52018-09-26 04:46:52843
844 // Fetch from the controlled page again.
845 EXPECT_EQ("Echo", EvalJs(shell(), script));
846
847 service_worker_context->RemoveObserver(&observer);
848}
849
850// Make sure fetch from a page controlled by a service worker which has a fetch
851// handler and responds with fetch() works after crash.
Makoto Shimazu2540a642018-11-15 06:24:44852IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
853 FetchFromServiceWorkerControlledPage_RespondWithFetch) {
Clark DuVall3290462e2019-02-16 02:19:50854 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36855 return;
Makoto Shimazu775101a52018-09-26 04:46:52856 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
857 BrowserContext::GetDefaultStoragePartition(browser_context()));
858 ServiceWorkerStatusObserver observer;
859 ServiceWorkerContextWrapper* service_worker_context =
860 partition->GetServiceWorkerContext();
861 service_worker_context->AddObserver(&observer);
862
863 // Register a service worker which controls /service_worker/.
864 EXPECT_TRUE(NavigateToURL(shell(),
865 embedded_test_server()->GetURL(
866 "/service_worker/create_service_worker.html")));
867 EXPECT_EQ("DONE",
868 EvalJs(shell(), "register('fetch_event_respond_with_fetch.js')"));
869
870 // Navigate to a controlled page.
871 EXPECT_TRUE(NavigateToURL(
872 shell(),
873 embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
874
875 // Fetch from the controlled page.
876 const std::string script = "fetch_from_page('/echo');";
877 EXPECT_EQ("Echo", EvalJs(shell(), script));
878
879 // Crash the NetworkService process. Existing interfaces should receive error
880 // notifications at some point.
881 SimulateNetworkServiceCrash();
882 // Flush the interface to make sure the error notification was received.
883 partition->FlushNetworkInterfaceForTesting();
884
885 // Service worker should be stopped when network service crashes.
Patrick Monette9f3aae62019-10-08 00:16:03886 observer.WaitForStopped();
Makoto Shimazu775101a52018-09-26 04:46:52887
888 // Fetch from the controlled page again.
889 EXPECT_EQ("Echo", EvalJs(shell(), script));
890
891 service_worker_context->RemoveObserver(&observer);
892}
893
Makoto Shimazu2075b0d2018-09-21 09:04:22894// Make sure fetch from service worker context works after crash.
Makoto Shimazu6a96cb62018-09-21 11:39:13895IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, ServiceWorkerFetch) {
Clark DuVall3290462e2019-02-16 02:19:50896 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36897 return;
Makoto Shimazu2075b0d2018-09-21 09:04:22898 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
899 BrowserContext::GetDefaultStoragePartition(browser_context()));
900 ServiceWorkerStatusObserver observer;
901 ServiceWorkerContextWrapper* service_worker_context =
902 partition->GetServiceWorkerContext();
903 service_worker_context->AddObserver(&observer);
904
905 const GURL page_url = embedded_test_server()->GetURL(
906 "/service_worker/fetch_from_service_worker.html");
907 const GURL fetch_url = embedded_test_server()->GetURL("/echo");
908
909 // Navigate to the page and register a service worker.
910 EXPECT_TRUE(NavigateToURL(shell(), page_url));
911 EXPECT_EQ("ready", EvalJs(shell(), "setup();"));
912
913 // Fetch from the service worker.
914 const std::string script =
915 "fetch_from_service_worker('" + fetch_url.spec() + "');";
916 EXPECT_EQ("Echo", EvalJs(shell(), script));
917
918 // Crash the NetworkService process. Existing interfaces should receive error
919 // notifications at some point.
920 SimulateNetworkServiceCrash();
921 // Flush the interface to make sure the error notification was received.
922 partition->FlushNetworkInterfaceForTesting();
923
924 // Service worker should be stopped when network service crashes.
Patrick Monette9f3aae62019-10-08 00:16:03925 observer.WaitForStopped();
Makoto Shimazu2075b0d2018-09-21 09:04:22926
927 // Fetch from the service worker again.
928 EXPECT_EQ("Echo", EvalJs(shell(), script));
929
930 service_worker_context->RemoveObserver(&observer);
931}
932
Clark DuVallf742bcbd2018-11-07 17:16:20933// TODO(crbug.com/154571): Shared workers are not available on Android.
934#if defined(OS_ANDROID)
935#define MAYBE_SharedWorker DISABLED_SharedWorker
936#else
937#define MAYBE_SharedWorker SharedWorker
938#endif
Matt Falkenhagene6721962018-10-05 10:17:05939// Make sure shared workers terminate after crash.
Clark DuVallf742bcbd2018-11-07 17:16:20940IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, MAYBE_SharedWorker) {
Clark DuVall3290462e2019-02-16 02:19:50941 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36942 return;
Makoto Shimazu2075b0d2018-09-21 09:04:22943 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
944 BrowserContext::GetDefaultStoragePartition(browser_context()));
945
Patrick Monette3f51a042019-08-30 17:57:04946 InjectTestSharedWorkerService(partition);
947
Makoto Shimazu2075b0d2018-09-21 09:04:22948 const GURL page_url =
949 embedded_test_server()->GetURL("/workers/fetch_from_shared_worker.html");
950 const GURL fetch_url = embedded_test_server()->GetURL("/echo");
951
952 // Navigate to the page and prepare a shared worker.
953 EXPECT_TRUE(NavigateToURL(shell(), page_url));
954
Matt Falkenhagene6721962018-10-05 10:17:05955 // Fetch from the shared worker to ensure it has started.
Finditc0f7c6202018-10-05 07:14:23956 const std::string script =
957 "fetch_from_shared_worker('" + fetch_url.spec() + "');";
958 EXPECT_EQ("Echo", EvalJs(shell(), script));
Makoto Shimazu2075b0d2018-09-21 09:04:22959
Matt Falkenhagene6721962018-10-05 10:17:05960 // There should be one worker host. We will later wait for it to terminate.
Patrick Monette3f51a042019-08-30 17:57:04961 TestSharedWorkerServiceImpl* service =
962 static_cast<TestSharedWorkerServiceImpl*>(
963 partition->GetSharedWorkerService());
Matt Falkenhagene6721962018-10-05 10:17:05964 EXPECT_EQ(1u, service->worker_hosts_.size());
965 base::RunLoop loop;
Patrick Monette3f51a042019-08-30 17:57:04966 service->SetWorkerTerminationCallback(loop.QuitClosure());
Makoto Shimazu2075b0d2018-09-21 09:04:22967
Matt Falkenhagene6721962018-10-05 10:17:05968 // Crash the NetworkService process.
969 SimulateNetworkServiceCrash();
970
971 // Wait for the worker to detect the crash and self-terminate.
972 loop.Run();
973 EXPECT_TRUE(service->worker_hosts_.empty());
Makoto Shimazu2075b0d2018-09-21 09:04:22974}
975
Chong Zhang53047762018-05-02 21:24:08976// Make sure the entry in |NetworkService::GetTotalNetworkUsages()| was cleared
977// after process closed.
978IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
979 GetNetworkUsagesClosed) {
Clark DuVall3290462e2019-02-16 02:19:50980 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36981 return;
Chong Zhang53047762018-05-02 21:24:08982 EXPECT_TRUE(NavigateToURL(shell(), GetTestURL()));
983 Shell* shell2 = CreateBrowser();
984 EXPECT_TRUE(NavigateToURL(shell2, GetTestURL()));
985
986 int process_id1 =
987 shell()->web_contents()->GetMainFrame()->GetProcess()->GetID();
988 int process_id2 =
989 shell2->web_contents()->GetMainFrame()->GetProcess()->GetID();
990
991 // Load resource on the renderer to make sure the traffic was recorded.
992 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
993 EXPECT_TRUE(CheckCanLoadHttp(shell2, "/title3.html"));
994
995 // Both processes should have traffic recorded.
996 auto network_usages = GetTotalNetworkUsages();
997 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
998 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id2));
999
1000 // Closing |shell2| should cause the entry to be cleared.
1001 shell2->Close();
1002 shell2 = nullptr;
1003
1004 // Wait until the Network Service has noticed the change. We don't have a
1005 // better way to force a flush on the Network Service side.
1006 WaitForCondition(base::BindRepeating(
1007 [](int process_id) {
1008 auto usages = GetTotalNetworkUsages();
1009 return !CheckContainsProcessID(usages, process_id);
1010 },
1011 process_id2));
1012
1013 network_usages = GetTotalNetworkUsages();
1014 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
1015 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id2));
1016}
1017
Christopher Thompson2a4c69e92019-08-21 16:29:111018// Make sure that kSSLKeyLogFileHistogram is correctly recorded when the
1019// network service instance is started and the SSLKEYLOGFILE env var is set or
1020// the "--ssl-key-log-file" arg is set.
1021IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, SSLKeyLogFileMetrics) {
1022 if (IsInProcessNetworkService())
1023 return;
1024 // Actions on temporary files are blocking.
1025 base::ScopedAllowBlockingForTesting scoped_allow_blocking;
1026 base::FilePath log_file_path;
1027 base::CreateTemporaryFile(&log_file_path);
1028
1029#if defined(OS_WIN)
1030 // On Windows, FilePath::value() returns base::string16, so convert.
1031 std::string log_file_path_str = base::UTF16ToUTF8(log_file_path.value());
1032#else
1033 std::string log_file_path_str = log_file_path.value();
1034#endif
1035
1036 // Test that env var causes the histogram to be recorded.
1037 {
1038 base::test::ScopedEnvironmentVariableOverride scoped_env("SSLKEYLOGFILE",
1039 log_file_path_str);
1040 base::HistogramTester histograms;
1041 // Restart network service to cause SSLKeyLogger to be re-initialized.
1042 SimulateNetworkServiceCrash();
1043 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1044 SSLKeyLogFileAction::kLogFileEnabled, 1);
1045 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1046 SSLKeyLogFileAction::kEnvVarFound, 1);
1047 }
1048
1049 // Test that the command-line switch causes the histogram to be recorded.
1050 {
1051 base::test::ScopedCommandLine scoped_command_line;
1052 scoped_command_line.GetProcessCommandLine()->AppendSwitchPath(
1053 "ssl-key-log-file", log_file_path);
1054 base::HistogramTester histograms;
1055 // Restart network service to cause SSLKeyLogger to be re-initialized.
1056 SimulateNetworkServiceCrash();
1057 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1058 SSLKeyLogFileAction::kLogFileEnabled, 1);
1059 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1060 SSLKeyLogFileAction::kSwitchFound, 1);
1061 }
1062}
1063
Chong Zhang53047762018-05-02 21:24:081064// Make sure |NetworkService::GetTotalNetworkUsages()| continues to work after
1065// crash. See 'network_usage_accumulator_unittest' for quantified tests.
1066IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
1067 GetNetworkUsagesCrashed) {
Clark DuVall3290462e2019-02-16 02:19:501068 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361069 return;
Chong Zhang53047762018-05-02 21:24:081070 EXPECT_TRUE(NavigateToURL(shell(), GetTestURL()));
1071 Shell* shell2 = CreateBrowser();
1072 EXPECT_TRUE(NavigateToURL(shell2, GetTestURL()));
1073
1074 int process_id1 =
1075 shell()->web_contents()->GetMainFrame()->GetProcess()->GetID();
1076 int process_id2 =
1077 shell2->web_contents()->GetMainFrame()->GetProcess()->GetID();
1078
1079 // Load resource on the renderer to make sure the traffic was recorded.
1080 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
1081 EXPECT_TRUE(CheckCanLoadHttp(shell2, "/title3.html"));
1082
1083 // Both processes should have traffic recorded.
1084 auto network_usages = GetTotalNetworkUsages();
1085 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
1086 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id2));
1087
1088 // Crashing Network Service should cause all entries to be cleared.
1089 SimulateNetworkServiceCrash();
1090 network_usages = GetTotalNetworkUsages();
1091 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id1));
1092 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id2));
1093
1094 // Should still be able to recored new traffic after crash.
1095 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
1096 network_usages = GetTotalNetworkUsages();
1097 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
1098 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id2));
1099}
1100
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141101// Make sure cookie access doesn't hang or fail after a network process crash.
1102IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, Cookies) {
Clark DuVall3290462e2019-02-16 02:19:501103 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361104 return;
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141105 auto* web_contents = shell()->web_contents();
Lukasz Anforowiczce4487b72018-10-23 18:05:531106 ASSERT_TRUE(
1107 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141108 EXPECT_TRUE(ExecuteScript(web_contents, "document.cookie = 'foo=bar';"));
1109
1110 std::string cookie;
1111 EXPECT_TRUE(ExecuteScriptAndExtractString(
1112 web_contents, "window.domAutomationController.send(document.cookie);",
1113 &cookie));
1114 EXPECT_EQ("foo=bar", cookie);
1115
1116 SimulateNetworkServiceCrash();
1117
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141118 // content_shell uses in-memory cookie database, so the value saved earlier
1119 // won't persist across crashes. What matters is that new access works.
1120 EXPECT_TRUE(ExecuteScript(web_contents, "document.cookie = 'foo=bar';"));
1121
1122 // This will hang without the fix.
1123 EXPECT_TRUE(ExecuteScriptAndExtractString(
1124 web_contents, "window.domAutomationController.send(document.cookie);",
1125 &cookie));
1126 EXPECT_EQ("foo=bar", cookie);
1127}
1128
Lukasz Anforowiczce4487b72018-10-23 18:05:531129#if BUILDFLAG(ENABLE_PLUGINS)
1130// Make sure that "trusted" plugins continue to be able to issue cross-origin
1131// requests after a network process crash.
1132IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, Plugin) {
Clark DuVall3290462e2019-02-16 02:19:501133 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361134 return;
Lukasz Anforowiczce4487b72018-10-23 18:05:531135 auto* web_contents = shell()->web_contents();
1136 ASSERT_TRUE(NavigateToURL(web_contents,
1137 embedded_test_server()->GetURL("/title1.html")));
1138
1139 // Load the test plugin (see ppapi::RegisterFlashTestPlugin and
1140 // ppapi/tests/power_saver_test_plugin.cc).
1141 const char kLoadingScript[] = R"(
1142 var obj = document.createElement('object');
1143 obj.id = 'plugin';
1144 obj.data = 'test.swf';
1145 obj.type = 'application/x-shockwave-flash';
1146 obj.width = 400;
1147 obj.height = 400;
1148
1149 document.body.appendChild(obj);
1150 )";
1151 ASSERT_TRUE(ExecJs(web_contents, kLoadingScript));
1152
1153 // Ask the plugin to perform a cross-origin, CORB-eligible (i.e.
1154 // application/json + nosniff) URL request. Plugins with universal access
1155 // should not be subject to CORS/CORB and so the request should go through.
1156 // See also https://crbug.com/874515 and https://crbug.com/846339.
1157 GURL cross_origin_url = embedded_test_server()->GetURL(
1158 "cross.origin.com", "/site_isolation/nosniff.json");
1159 const char kFetchScriptTemplate[] = R"(
1160 new Promise(function (resolve, reject) {
1161 var obj = document.getElementById('plugin');
1162 function callback(event) {
1163 // Ignore plugin messages unrelated to requestUrl.
1164 if (!event.data.startsWith('requestUrl: '))
1165 return;
1166
1167 obj.removeEventListener('message', callback);
1168 resolve('msg-from-plugin: ' + event.data);
1169 };
1170 obj.addEventListener('message', callback);
1171 obj.postMessage('requestUrl: ' + $1);
1172 });
1173 )";
1174 std::string fetch_script = JsReplace(kFetchScriptTemplate, cross_origin_url);
1175 ASSERT_EQ(
1176 "msg-from-plugin: requestUrl: RESPONSE BODY: "
1177 "runMe({ \"name\" : \"chromium\" });\n",
1178 EvalJs(web_contents, fetch_script));
1179
1180 // Crash the Network Service process and wait until host frame's
1181 // URLLoaderFactory has been refreshed.
1182 SimulateNetworkServiceCrash();
1183 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
1184
1185 // Try the fetch again - it should still work (i.e. the mechanism for relaxing
1186 // CORB for universal-access-plugins should be resilient to network process
1187 // crashes). See also https://crbug.com/891904.
1188 ASSERT_EQ(
1189 "msg-from-plugin: requestUrl: RESPONSE BODY: "
1190 "runMe({ \"name\" : \"chromium\" });\n",
1191 EvalJs(web_contents, fetch_script));
1192}
1193#endif
1194
Clark DuVallf742bcbd2018-11-07 17:16:201195// TODO(crbug.com/901026): Fix deadlock on process startup on Android.
1196#if defined(OS_ANDROID)
1197#define MAYBE_SyncCallDuringRestart DISABLED_SyncCallDuringRestart
1198#else
1199#define MAYBE_SyncCallDuringRestart SyncCallDuringRestart
1200#endif
1201IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
1202 MAYBE_SyncCallDuringRestart) {
Clark DuVall3290462e2019-02-16 02:19:501203 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361204 return;
Clark DuVallf742bcbd2018-11-07 17:16:201205 network::mojom::NetworkServiceTestPtr network_service_test;
1206 base::RunLoop run_loop;
Ken Rockotfd03e682019-06-20 21:13:541207 GetSystemConnector()->BindInterface(mojom::kNetworkServiceName,
1208 &network_service_test);
Clark DuVallf742bcbd2018-11-07 17:16:201209
1210 // Crash the network service, but do not wait for full startup.
1211 network_service_test.set_connection_error_handler(run_loop.QuitClosure());
1212 network_service_test->SimulateCrash();
1213 run_loop.Run();
1214
Ken Rockotfd03e682019-06-20 21:13:541215 GetSystemConnector()->BindInterface(mojom::kNetworkServiceName,
1216 &network_service_test);
Clark DuVallf742bcbd2018-11-07 17:16:201217
1218 // Sync call should be fine, even though network process is still starting up.
1219 mojo::ScopedAllowSyncCallForTesting allow_sync_call;
1220 network_service_test->AddRules({});
1221}
1222
Chong Zhangc583e672017-11-08 16:34:081223} // namespace content