blob: 15c6d94c37be19555979ec0e507058800ddeb930 [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"
Chong Zhang5f468272017-12-07 23:59:1432#include "content/public/browser/web_contents.h"
Chong Zhang7306b0b2018-01-24 05:59:2433#include "content/public/common/content_switches.h"
Clark DuVall3290462e2019-02-16 02:19:5034#include "content/public/common/network_service_util.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"
Patrick Monette3f51a042019-08-30 17:57:0440#include "content/public/test/web_test_support.h"
Chong Zhang5f468272017-12-07 23:59:1441#include "content/shell/browser/shell.h"
John Abd-El-Maleka7289152018-02-17 00:16:1942#include "content/shell/browser/shell_browser_context.h"
Chong Zhang83d0e4f2018-05-04 18:55:0943#include "content/test/storage_partition_test_utils.h"
Julie Jeongeun Kim5984e992019-09-11 11:00:4644#include "mojo/public/cpp/bindings/pending_remote.h"
45#include "mojo/public/cpp/bindings/remote.h"
Clark DuVallf742bcbd2018-11-07 17:16:2046#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
Chong Zhang7306b0b2018-01-24 05:59:2447#include "net/dns/mock_host_resolver.h"
48#include "net/test/embedded_test_server/http_request.h"
Chong Zhangd4c923642018-01-03 21:22:2949#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
John Abd-El-Malekbdafede2018-02-06 15:10:3650#include "services/network/public/cpp/simple_url_loader.h"
Ken Rockot54311e62018-02-10 19:01:5251#include "services/network/public/mojom/network_service.mojom.h"
Clark DuVallf742bcbd2018-11-07 17:16:2052#include "services/network/public/mojom/network_service_test.mojom.h"
Hiroki Nakagawa3b90e642019-09-10 01:59:5853#include "third_party/blink/public/common/features.h"
Chong Zhangc583e672017-11-08 16:34:0854
Lukasz Anforowiczce4487b72018-10-23 18:05:5355#if BUILDFLAG(ENABLE_PLUGINS)
56#include "content/public/test/ppapi_test_utils.h"
57#endif
58
Chong Zhangc583e672017-11-08 16:34:0859namespace content {
60
61namespace {
62
Chong Zhang4dd97ebf2018-03-07 04:48:4863using SharedURLLoaderFactoryGetterCallback =
Chong Zhangb7c8d1ce2018-03-13 19:14:1164 base::OnceCallback<scoped_refptr<network::SharedURLLoaderFactory>()>;
Chong Zhang4dd97ebf2018-03-07 04:48:4865
Julie Jeongeun Kim5984e992019-09-11 11:00:4666mojo::PendingRemote<network::mojom::NetworkContext> CreateNetworkContext() {
67 mojo::PendingRemote<network::mojom::NetworkContext> network_context;
John Abd-El-Malek53670dd2018-01-18 22:07:2168 network::mojom::NetworkContextParamsPtr context_params =
69 network::mojom::NetworkContextParams::New();
Julie Jeongeun Kim5984e992019-09-11 11:00:4670 GetNetworkService()->CreateNetworkContext(
71 network_context.InitWithNewPipeAndPassReceiver(),
72 std::move(context_params));
Chong Zhangc583e672017-11-08 16:34:0873 return network_context;
74}
75
John Abd-El-Maleka7289152018-02-17 00:16:1976int LoadBasicRequestOnUIThread(
77 network::mojom::URLLoaderFactory* url_loader_factory,
78 const GURL& url) {
79 DCHECK_CURRENTLY_ON(BrowserThread::UI);
80 auto request = std::make_unique<network::ResourceRequest>();
81 request->url = url;
82
83 SimpleURLLoaderTestHelper simple_loader_helper;
84 std::unique_ptr<network::SimpleURLLoader> simple_loader =
85 network::SimpleURLLoader::Create(std::move(request),
86 TRAFFIC_ANNOTATION_FOR_TESTS);
87 simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
88 url_loader_factory, simple_loader_helper.GetCallback());
89 simple_loader_helper.WaitForCallback();
90 return simple_loader->NetError();
91}
92
Chong Zhang53047762018-05-02 21:24:0893std::vector<network::mojom::NetworkUsagePtr> GetTotalNetworkUsages() {
94 std::vector<network::mojom::NetworkUsagePtr> network_usages;
95 base::RunLoop run_loop;
96 GetNetworkService()->GetTotalNetworkUsages(base::BindOnce(
97 [](std::vector<network::mojom::NetworkUsagePtr>* p_network_usages,
98 base::OnceClosure quit_closure,
99 std::vector<network::mojom::NetworkUsagePtr> returned_usages) {
100 *p_network_usages = std::move(returned_usages);
101 std::move(quit_closure).Run();
102 },
103 base::Unretained(&network_usages), run_loop.QuitClosure()));
104 run_loop.Run();
105 return network_usages;
106}
107
108bool CheckContainsProcessID(
109 const std::vector<network::mojom::NetworkUsagePtr>& usages,
110 int process_id) {
111 for (const auto& usage : usages) {
112 if ((int)usage->process_id == process_id)
113 return true;
114 }
115 return false;
116}
117
118// Wait until |condition| returns true.
119void WaitForCondition(base::RepeatingCallback<bool()> condition) {
120 while (!condition.Run()) {
121 base::RunLoop run_loop;
122 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
123 FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
124 run_loop.Run();
125 }
126}
127
Makoto Shimazu2075b0d2018-09-21 09:04:22128class ServiceWorkerStatusObserver : public ServiceWorkerContextCoreObserver {
129 public:
Patrick Monette9f3aae62019-10-08 00:16:03130 void WaitForStopped() {
131 if (stopped_)
132 return;
Makoto Shimazu2075b0d2018-09-21 09:04:22133
Makoto Shimazu2075b0d2018-09-21 09:04:22134 base::RunLoop loop;
135 callback_ = loop.QuitClosure();
136 loop.Run();
137 }
138
139 private:
Patrick Monette9f3aae62019-10-08 00:16:03140 void OnStopped(int64_t version_id) override {
141 stopped_ = true;
142
143 if (callback_)
Makoto Shimazu2075b0d2018-09-21 09:04:22144 std::move(callback_).Run();
Makoto Shimazu2075b0d2018-09-21 09:04:22145 }
146
Patrick Monette9f3aae62019-10-08 00:16:03147 bool stopped_ = false;
Makoto Shimazu2075b0d2018-09-21 09:04:22148 base::OnceClosure callback_;
149};
150
Chong Zhangc583e672017-11-08 16:34:08151} // namespace
152
Chong Zhangc583e672017-11-08 16:34:08153class NetworkServiceRestartBrowserTest : public ContentBrowserTest {
154 public:
John Abd-El-Malekc134dd82019-07-31 20:51:44155 NetworkServiceRestartBrowserTest() {}
Chong Zhang7306b0b2018-01-24 05:59:24156
Lukasz Anforowiczce4487b72018-10-23 18:05:53157 void SetUpCommandLine(base::CommandLine* command_line) override {
158#if BUILDFLAG(ENABLE_PLUGINS)
159 ASSERT_TRUE(ppapi::RegisterCorbTestPlugin(command_line));
160#endif
161 ContentBrowserTest::SetUpCommandLine(command_line);
162 }
163
Chong Zhang7306b0b2018-01-24 05:59:24164 void SetUpOnMainThread() override {
Chong Zhang5d9b34182018-01-30 16:20:57165 embedded_test_server()->RegisterRequestMonitor(
166 base::BindRepeating(&NetworkServiceRestartBrowserTest::MonitorRequest,
167 base::Unretained(this)));
Lukasz Anforowiczce4487b72018-10-23 18:05:53168 host_resolver()->AddRule("*", "127.0.0.1");
Chong Zhangc583e672017-11-08 16:34:08169 EXPECT_TRUE(embedded_test_server()->Start());
Chong Zhang7306b0b2018-01-24 05:59:24170 ContentBrowserTest::SetUpOnMainThread();
Chong Zhangc583e672017-11-08 16:34:08171 }
172
Chong Zhangc40a6ce52017-12-10 03:00:28173 GURL GetTestURL() const {
Chong Zhang5f468272017-12-07 23:59:14174 // Use '/echoheader' instead of '/echo' to avoid a disk_cache bug.
175 // See https://crbug.com/792255.
Chong Zhangc40a6ce52017-12-10 03:00:28176 return embedded_test_server()->GetURL("/echoheader");
Chong Zhangc583e672017-11-08 16:34:08177 }
178
Chong Zhangd4c923642018-01-03 21:22:29179 BrowserContext* browser_context() {
180 return shell()->web_contents()->GetBrowserContext();
181 }
182
Chong Zhang5d9b34182018-01-30 16:20:57183 RenderFrameHostImpl* main_frame() {
184 return static_cast<RenderFrameHostImpl*>(
185 shell()->web_contents()->GetMainFrame());
186 }
187
Chong Zhang53047762018-05-02 21:24:08188 bool CheckCanLoadHttp(Shell* shell, const std::string& relative_url) {
Chong Zhang5d9b34182018-01-30 16:20:57189 GURL test_url = embedded_test_server()->GetURL(relative_url);
190 std::string script(
191 "var xhr = new XMLHttpRequest();"
192 "xhr.open('GET', '");
193 script += test_url.spec() +
194 "', true);"
195 "xhr.onload = function (e) {"
196 " if (xhr.readyState === 4) {"
197 " window.domAutomationController.send(xhr.status === 200);"
198 " }"
199 "};"
200 "xhr.onerror = function () {"
201 " window.domAutomationController.send(false);"
202 "};"
203 "xhr.send(null)";
204 bool xhr_result = false;
205 // The JS call will fail if disallowed because the process will be killed.
206 bool execute_result =
Chong Zhang53047762018-05-02 21:24:08207 ExecuteScriptAndExtractBool(shell, script, &xhr_result);
Chong Zhang5d9b34182018-01-30 16:20:57208 return xhr_result && execute_result;
209 }
210
Chong Zhang4513fab2018-02-28 18:50:18211 // Will reuse the single opened windows through the test case.
212 bool CheckCanLoadHttpInWindowOpen(const std::string& relative_url) {
213 GURL test_url = embedded_test_server()->GetURL(relative_url);
214 std::string inject_script = base::StringPrintf(
215 "var xhr = new XMLHttpRequest();"
216 "xhr.open('GET', '%s', true);"
217 "xhr.onload = function (e) {"
218 " if (xhr.readyState === 4) {"
219 " window.opener.domAutomationController.send(xhr.status === 200);"
220 " }"
221 "};"
222 "xhr.onerror = function () {"
223 " window.opener.domAutomationController.send(false);"
224 "};"
225 "xhr.send(null)",
226 test_url.spec().c_str());
227 std::string window_open_script = base::StringPrintf(
228 "var new_window = new_window || window.open('');"
229 "var inject_script = document.createElement('script');"
230 "inject_script.innerHTML = \"%s\";"
231 "new_window.document.body.appendChild(inject_script);",
232 inject_script.c_str());
233
234 bool xhr_result = false;
235 // The JS call will fail if disallowed because the process will be killed.
236 bool execute_result =
237 ExecuteScriptAndExtractBool(shell(), window_open_script, &xhr_result);
238 return xhr_result && execute_result;
239 }
240
241 // Workers will live throughout the test case unless terminated.
242 bool CheckCanWorkerFetch(const std::string& worker_name,
243 const std::string& relative_url) {
244 GURL worker_url =
245 embedded_test_server()->GetURL("/workers/worker_common.js");
246 GURL fetch_url = embedded_test_server()->GetURL(relative_url);
247 std::string script = base::StringPrintf(
248 "var workers = workers || {};"
249 "var worker_name = '%s';"
250 "workers[worker_name] = workers[worker_name] || new Worker('%s');"
251 "workers[worker_name].onmessage = evt => {"
252 " if (evt.data != 'wait')"
253 " window.domAutomationController.send(evt.data === 200);"
254 "};"
255 "workers[worker_name].postMessage(\"eval "
256 " fetch(new Request('%s'))"
257 " .then(res => postMessage(res.status))"
258 " .catch(error => postMessage(error.toString()));"
259 " 'wait'"
260 "\");",
261 worker_name.c_str(), worker_url.spec().c_str(),
262 fetch_url.spec().c_str());
263 bool fetch_result = false;
264 // The JS call will fail if disallowed because the process will be killed.
265 bool execute_result =
266 ExecuteScriptAndExtractBool(shell(), script, &fetch_result);
267 return fetch_result && execute_result;
268 }
269
270 // Terminate and delete the worker.
271 bool TerminateWorker(const std::string& worker_name) {
272 std::string script = base::StringPrintf(
273 "var workers = workers || {};"
274 "var worker_name = '%s';"
275 "if (workers[worker_name]) {"
276 " workers[worker_name].terminate();"
277 " delete workers[worker_name];"
278 " window.domAutomationController.send(true);"
279 "} else {"
280 " window.domAutomationController.send(false);"
281 "}",
282 worker_name.c_str());
283 bool fetch_result = false;
284 // The JS call will fail if disallowed because the process will be killed.
285 bool execute_result =
286 ExecuteScriptAndExtractBool(shell(), script, &fetch_result);
287 return fetch_result && execute_result;
288 }
289
Chong Zhang5d9b34182018-01-30 16:20:57290 // Called by |embedded_test_server()|.
291 void MonitorRequest(const net::test_server::HttpRequest& request) {
David Benjaminff93edd2019-06-19 22:51:58292 base::AutoLock lock(last_request_lock_);
Chong Zhang5d9b34182018-01-30 16:20:57293 last_request_relative_url_ = request.relative_url;
294 }
295
296 std::string last_request_relative_url() const {
David Benjaminff93edd2019-06-19 22:51:58297 base::AutoLock lock(last_request_lock_);
Chong Zhang5d9b34182018-01-30 16:20:57298 return last_request_relative_url_;
299 }
300
Chong Zhangc583e672017-11-08 16:34:08301 private:
David Benjaminff93edd2019-06-19 22:51:58302 mutable base::Lock last_request_lock_;
303 std::string last_request_relative_url_ GUARDED_BY(last_request_lock_);
Chong Zhangc583e672017-11-08 16:34:08304
305 DISALLOW_COPY_AND_ASSIGN(NetworkServiceRestartBrowserTest);
306};
307
308IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
309 NetworkServiceProcessRecovery) {
Clark DuVall3290462e2019-02-16 02:19:50310 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36311 return;
Julie Jeongeun Kim5984e992019-09-11 11:00:46312 mojo::Remote<network::mojom::NetworkContext> network_context(
313 CreateNetworkContext());
Chong Zhangc40a6ce52017-12-10 03:00:28314 EXPECT_EQ(net::OK, LoadBasicRequest(network_context.get(), GetTestURL()));
Chong Zhangc583e672017-11-08 16:34:08315 EXPECT_TRUE(network_context.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46316 EXPECT_TRUE(network_context.is_connected());
Chong Zhangc583e672017-11-08 16:34:08317
Chong Zhang5f468272017-12-07 23:59:14318 // Crash the NetworkService process. Existing interfaces should receive error
319 // notifications at some point.
Chong Zhangc583e672017-11-08 16:34:08320 SimulateNetworkServiceCrash();
Chong Zhang5f468272017-12-07 23:59:14321 // |network_context| will receive an error notification, but it's not
Julie Jeongeun Kim5984e992019-09-11 11:00:46322 // guaranteed to have arrived at this point. Flush the remote to make sure
Chong Zhang5f468272017-12-07 23:59:14323 // the notification has been received.
324 network_context.FlushForTesting();
Chong Zhangc583e672017-11-08 16:34:08325 EXPECT_TRUE(network_context.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46326 EXPECT_FALSE(network_context.is_connected());
Chong Zhang5f468272017-12-07 23:59:14327 // Make sure we could get |net::ERR_FAILED| with an invalid |network_context|.
Chong Zhangc40a6ce52017-12-10 03:00:28328 EXPECT_EQ(net::ERR_FAILED,
329 LoadBasicRequest(network_context.get(), GetTestURL()));
Chong Zhangc583e672017-11-08 16:34:08330
331 // NetworkService should restart automatically and return valid interface.
Julie Jeongeun Kim5984e992019-09-11 11:00:46332 mojo::Remote<network::mojom::NetworkContext> network_context2(
333 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());
Julie Jeongeun Kim5984e992019-09-11 11:00:46336 EXPECT_TRUE(network_context2.is_connected());
Chong Zhangc583e672017-11-08 16:34:08337}
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;
Julie Jeongeun Kim5984e992019-09-11 11:00:46348 mojo::Remote<network::mojom::NetworkContext> network_context(
349 CreateNetworkContext());
Lukasz Anforowiczce4487b72018-10-23 18:05:53350 EXPECT_TRUE(network_context.is_bound());
351
352 // Register 2 crash handlers.
353 int counter1 = 0;
354 int counter2 = 0;
Lukasz Anforowiczc195e912018-10-30 16:20:54355 auto handler1 = RegisterNetworkServiceCrashHandler(
Lukasz Anforowiczce4487b72018-10-23 18:05:53356 base::BindRepeating(&IncrementInt, base::Unretained(&counter1)));
Lukasz Anforowiczc195e912018-10-30 16:20:54357 auto handler2 = RegisterNetworkServiceCrashHandler(
Lukasz Anforowiczce4487b72018-10-23 18:05:53358 base::BindRepeating(&IncrementInt, base::Unretained(&counter2)));
359
360 // Crash the NetworkService process.
361 SimulateNetworkServiceCrash();
362 // |network_context| will receive an error notification, but it's not
Julie Jeongeun Kim5984e992019-09-11 11:00:46363 // guaranteed to have arrived at this point. Flush the remote to make sure
Lukasz Anforowiczce4487b72018-10-23 18:05:53364 // the notification has been received.
365 network_context.FlushForTesting();
366 EXPECT_TRUE(network_context.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46367 EXPECT_FALSE(network_context.is_connected());
Lukasz Anforowiczce4487b72018-10-23 18:05:53368
369 // Verify the crash handlers executed.
370 EXPECT_EQ(1, counter1);
371 EXPECT_EQ(1, counter2);
372
373 // Revive the NetworkService process.
Julie Jeongeun Kim5984e992019-09-11 11:00:46374 network_context.reset();
375 network_context.Bind(CreateNetworkContext());
Lukasz Anforowiczce4487b72018-10-23 18:05:53376 EXPECT_TRUE(network_context.is_bound());
377
378 // Unregister one of the handlers.
Lukasz Anforowiczc195e912018-10-30 16:20:54379 handler2.reset();
Lukasz Anforowiczce4487b72018-10-23 18:05:53380
381 // Crash the NetworkService process.
382 SimulateNetworkServiceCrash();
383 // |network_context| will receive an error notification, but it's not
Julie Jeongeun Kim5984e992019-09-11 11:00:46384 // guaranteed to have arrived at this point. Flush the remote to make sure
Lukasz Anforowiczce4487b72018-10-23 18:05:53385 // the notification has been received.
386 network_context.FlushForTesting();
387 EXPECT_TRUE(network_context.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46388 EXPECT_FALSE(network_context.is_connected());
Lukasz Anforowiczce4487b72018-10-23 18:05:53389
390 // Verify only the first crash handler executed.
391 EXPECT_EQ(2, counter1);
392 EXPECT_EQ(1, counter2);
Lukasz Anforowiczce4487b72018-10-23 18:05:53393}
394
Chong Zhang5f468272017-12-07 23:59:14395// Make sure |StoragePartitionImpl::GetNetworkContext()| returns valid interface
396// after crash.
397IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
Chong Zhange0dfdb62017-12-09 18:25:14398 StoragePartitionImplGetNetworkContext) {
Clark DuVall3290462e2019-02-16 02:19:50399 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36400 return;
Chong Zhang5f468272017-12-07 23:59:14401 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
Chong Zhangd4c923642018-01-03 21:22:29402 BrowserContext::GetDefaultStoragePartition(browser_context()));
Chong Zhang5f468272017-12-07 23:59:14403
John Abd-El-Malek53670dd2018-01-18 22:07:21404 network::mojom::NetworkContext* old_network_context =
405 partition->GetNetworkContext();
Chong Zhangc40a6ce52017-12-10 03:00:28406 EXPECT_EQ(net::OK, LoadBasicRequest(old_network_context, GetTestURL()));
Chong Zhang5f468272017-12-07 23:59:14407
408 // Crash the NetworkService process. Existing interfaces should receive error
409 // notifications at some point.
410 SimulateNetworkServiceCrash();
411 // Flush the interface to make sure the error notification was received.
412 partition->FlushNetworkInterfaceForTesting();
413
414 // |partition->GetNetworkContext()| should return a valid new pointer after
415 // crash.
416 EXPECT_NE(old_network_context, partition->GetNetworkContext());
Chong Zhangc40a6ce52017-12-10 03:00:28417 EXPECT_EQ(net::OK,
418 LoadBasicRequest(partition->GetNetworkContext(), GetTestURL()));
Chong Zhang5f468272017-12-07 23:59:14419}
420
Chong Zhangd4c923642018-01-03 21:22:29421// Make sure |URLLoaderFactoryGetter| returns valid interface after crash.
422IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
423 URLLoaderFactoryGetterGetNetworkFactory) {
Clark DuVall3290462e2019-02-16 02:19:50424 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36425 return;
Chong Zhangd4c923642018-01-03 21:22:29426 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
427 BrowserContext::GetDefaultStoragePartition(browser_context()));
428 scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter =
429 partition->url_loader_factory_getter();
Chong Zhang5271432a2018-03-01 23:31:02430
Chong Zhang83d0e4f2018-05-04 18:55:09431 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
432 url_loader_factory_getter.get());
433 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02434
Chong Zhangd4c923642018-01-03 21:22:29435 // Crash the NetworkService process. Existing interfaces should receive error
436 // notifications at some point.
437 SimulateNetworkServiceCrash();
438 // Flush the interface to make sure the error notification was received.
439 partition->FlushNetworkInterfaceForTesting();
440 url_loader_factory_getter->FlushNetworkInterfaceOnIOThreadForTesting();
441
442 // |url_loader_factory_getter| should be able to get a valid new pointer after
443 // crash.
Chong Zhang83d0e4f2018-05-04 18:55:09444 factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
445 url_loader_factory_getter.get());
446 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02447}
448
449// Make sure the factory returned from
450// |URLLoaderFactoryGetter::GetNetworkFactory()| continues to work after
451// crashes.
452IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
453 BrowserIOSharedURLLoaderFactory) {
Clark DuVall3290462e2019-02-16 02:19:50454 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36455 return;
Chong Zhang5271432a2018-03-01 23:31:02456 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
457 BrowserContext::GetDefaultStoragePartition(browser_context()));
458
Chong Zhang83d0e4f2018-05-04 18:55:09459 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
460 partition->url_loader_factory_getter().get());
Chong Zhang5271432a2018-03-01 23:31:02461
Chong Zhang83d0e4f2018-05-04 18:55:09462 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02463
464 // Crash the NetworkService process. Existing interfaces should receive error
465 // notifications at some point.
466 SimulateNetworkServiceCrash();
467 // Flush the interface to make sure the error notification was received.
468 partition->FlushNetworkInterfaceForTesting();
469 partition->url_loader_factory_getter()
470 ->FlushNetworkInterfaceOnIOThreadForTesting();
471
472 // |shared_factory| should continue to work.
Chong Zhang83d0e4f2018-05-04 18:55:09473 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02474}
475
476// Make sure the factory returned from
477// |URLLoaderFactoryGetter::GetNetworkFactory()| doesn't crash if
478// it's called after the StoragePartition is deleted.
Chong Zhangf8572182018-03-16 23:10:18479IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
480 BrowserIOSharedFactoryAfterStoragePartitionGone) {
Clark DuVall3290462e2019-02-16 02:19:50481 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36482 return;
Chong Zhang5271432a2018-03-01 23:31:02483 base::ScopedAllowBlockingForTesting allow_blocking;
484 std::unique_ptr<ShellBrowserContext> browser_context =
Eric Romanb56d0ef2019-07-02 17:36:06485 std::make_unique<ShellBrowserContext>(true);
Chong Zhang5271432a2018-03-01 23:31:02486 auto* partition = static_cast<StoragePartitionImpl*>(
487 BrowserContext::GetDefaultStoragePartition(browser_context.get()));
Chong Zhang83d0e4f2018-05-04 18:55:09488 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
489 partition->url_loader_factory_getter().get());
Chong Zhang5271432a2018-03-01 23:31:02490
Chong Zhang83d0e4f2018-05-04 18:55:09491 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02492
493 browser_context.reset();
494
495 EXPECT_EQ(net::ERR_FAILED,
Chong Zhang83d0e4f2018-05-04 18:55:09496 factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhangd4c923642018-01-03 21:22:29497}
498
499// Make sure basic navigation works after crash.
500IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
501 NavigationURLLoaderBasic) {
Clark DuVall3290462e2019-02-16 02:19:50502 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36503 return;
Chong Zhangd4c923642018-01-03 21:22:29504 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
505 BrowserContext::GetDefaultStoragePartition(browser_context()));
506
507 EXPECT_TRUE(
508 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
509
510 // Crash the NetworkService process. Existing interfaces should receive error
511 // notifications at some point.
512 SimulateNetworkServiceCrash();
513 // Flush the interface to make sure the error notification was received.
514 partition->FlushNetworkInterfaceForTesting();
515 partition->url_loader_factory_getter()
516 ->FlushNetworkInterfaceOnIOThreadForTesting();
517
518 EXPECT_TRUE(
519 NavigateToURL(shell(), embedded_test_server()->GetURL("/title2.html")));
520}
521
Chong Zhang7306b0b2018-01-24 05:59:24522// Make sure basic XHR works after crash.
Chong Zhang5d9b34182018-01-30 16:20:57523IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BasicXHR) {
Clark DuVall3290462e2019-02-16 02:19:50524 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36525 return;
Chong Zhang7306b0b2018-01-24 05:59:24526 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
527 BrowserContext::GetDefaultStoragePartition(browser_context()));
528
Chong Zhang5d9b34182018-01-30 16:20:57529 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
Chong Zhang53047762018-05-02 21:24:08530 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title1.html"));
Chong Zhang7306b0b2018-01-24 05:59:24531 EXPECT_EQ(last_request_relative_url(), "/title1.html");
532
533 // Crash the NetworkService process. Existing interfaces should receive error
534 // notifications at some point.
535 SimulateNetworkServiceCrash();
536 // Flush the interface to make sure the error notification was received.
537 partition->FlushNetworkInterfaceForTesting();
538 // Flush the interface to make sure the frame host has received error
539 // notification and the new URLLoaderFactoryBundle has been received by the
540 // frame.
541 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
542
Chong Zhang53047762018-05-02 21:24:08543 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
Chong Zhang7306b0b2018-01-24 05:59:24544 EXPECT_EQ(last_request_relative_url(), "/title2.html");
545}
546
John Abd-El-Maleka7289152018-02-17 00:16:19547// Make sure the factory returned from
548// |StoragePartition::GetURLLoaderFactoryForBrowserProcess()| continues to work
549// after crashes.
550IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BrowserUIFactory) {
Clark DuVall3290462e2019-02-16 02:19:50551 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36552 return;
John Abd-El-Maleka7289152018-02-17 00:16:19553 auto* partition =
554 BrowserContext::GetDefaultStoragePartition(browser_context());
555 auto* factory = partition->GetURLLoaderFactoryForBrowserProcess().get();
556
557 EXPECT_EQ(net::OK, LoadBasicRequestOnUIThread(factory, GetTestURL()));
558
559 SimulateNetworkServiceCrash();
560 // Flush the interface to make sure the error notification was received.
561 partition->FlushNetworkInterfaceForTesting();
562
563 EXPECT_EQ(net::OK, LoadBasicRequestOnUIThread(factory, GetTestURL()));
564}
565
566// Make sure the factory returned from
567// |StoragePartition::GetURLLoaderFactoryForBrowserProcess()| doesn't crash if
568// it's called after the StoragePartition is deleted.
569IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
570 BrowserUIFactoryAfterStoragePartitionGone) {
Clark DuVall3290462e2019-02-16 02:19:50571 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36572 return;
John Abd-El-Maleka7289152018-02-17 00:16:19573 base::ScopedAllowBlockingForTesting allow_blocking;
574 std::unique_ptr<ShellBrowserContext> browser_context =
Eric Romanb56d0ef2019-07-02 17:36:06575 std::make_unique<ShellBrowserContext>(true);
John Abd-El-Maleka7289152018-02-17 00:16:19576 auto* partition =
577 BrowserContext::GetDefaultStoragePartition(browser_context.get());
Chong Zhangb7c8d1ce2018-03-13 19:14:11578 scoped_refptr<network::SharedURLLoaderFactory> factory(
John Abd-El-Maleka7289152018-02-17 00:16:19579 partition->GetURLLoaderFactoryForBrowserProcess());
580
581 EXPECT_EQ(net::OK, LoadBasicRequestOnUIThread(factory.get(), GetTestURL()));
582
583 browser_context.reset();
584
585 EXPECT_EQ(net::ERR_FAILED,
586 LoadBasicRequestOnUIThread(factory.get(), GetTestURL()));
587}
588
Chong Zhang83d0e4f2018-05-04 18:55:09589// Make sure the factory info returned from
590// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| can be
591// used after crashes.
Guido Urdaneta9cbbe382018-05-07 14:51:06592// Flaky on Windows. https://crbug.com/840127
593#if defined(OS_WIN)
594#define MAYBE_BrowserIOFactoryInfo DISABLED_BrowserIOFactoryInfo
595#else
596#define MAYBE_BrowserIOFactoryInfo BrowserIOFactoryInfo
597#endif
598IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
599 MAYBE_BrowserIOFactoryInfo) {
Clark DuVall3290462e2019-02-16 02:19:50600 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36601 return;
Chong Zhang4dd97ebf2018-03-07 04:48:48602 auto* partition =
603 BrowserContext::GetDefaultStoragePartition(browser_context());
Chong Zhang83d0e4f2018-05-04 18:55:09604 auto shared_url_loader_factory_info =
605 partition->GetURLLoaderFactoryForBrowserProcessIOThread();
Chong Zhang4dd97ebf2018-03-07 04:48:48606
607 SimulateNetworkServiceCrash();
608 // Flush the interface to make sure the error notification was received.
609 partition->FlushNetworkInterfaceForTesting();
610 static_cast<StoragePartitionImpl*>(partition)
611 ->url_loader_factory_getter()
612 ->FlushNetworkInterfaceOnIOThreadForTesting();
613
Chong Zhang83d0e4f2018-05-04 18:55:09614 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
615 std::move(shared_url_loader_factory_info));
616
617 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang4dd97ebf2018-03-07 04:48:48618}
619
Chong Zhang83d0e4f2018-05-04 18:55:09620// Make sure the factory constructed from
621// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| continues
622// to work after crashes.
623IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BrowserIOFactory) {
Clark DuVall3290462e2019-02-16 02:19:50624 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36625 return;
Chong Zhang4dd97ebf2018-03-07 04:48:48626 auto* partition =
Chong Zhang83d0e4f2018-05-04 18:55:09627 BrowserContext::GetDefaultStoragePartition(browser_context());
628 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
629 partition->GetURLLoaderFactoryForBrowserProcessIOThread());
Chong Zhang4dd97ebf2018-03-07 04:48:48630
Chong Zhang83d0e4f2018-05-04 18:55:09631 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang4dd97ebf2018-03-07 04:48:48632
Chong Zhang83d0e4f2018-05-04 18:55:09633 SimulateNetworkServiceCrash();
634 // Flush the interface to make sure the error notification was received.
635 partition->FlushNetworkInterfaceForTesting();
636 static_cast<StoragePartitionImpl*>(partition)
637 ->url_loader_factory_getter()
638 ->FlushNetworkInterfaceOnIOThreadForTesting();
Chong Zhang4dd97ebf2018-03-07 04:48:48639
Chong Zhang83d0e4f2018-05-04 18:55:09640 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang4dd97ebf2018-03-07 04:48:48641}
642
Chong Zhang4513fab2018-02-28 18:50:18643// Make sure the window from |window.open()| can load XHR after crash.
644IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, WindowOpenXHR) {
Clark DuVall3290462e2019-02-16 02:19:50645 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36646 return;
Chong Zhang4513fab2018-02-28 18:50:18647 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
648 BrowserContext::GetDefaultStoragePartition(browser_context()));
649
650 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
651 EXPECT_TRUE(CheckCanLoadHttpInWindowOpen("/title1.html"));
652 EXPECT_EQ(last_request_relative_url(), "/title1.html");
653
654 // Crash the NetworkService process. Existing interfaces should receive error
655 // notifications at some point.
656 SimulateNetworkServiceCrash();
657 // Flush the interface to make sure the error notification was received.
658 partition->FlushNetworkInterfaceForTesting();
659 // Flush the interface to make sure the frame host has received error
660 // notification and the new URLLoaderFactoryBundle has been received by the
661 // frame.
662 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
663
664 EXPECT_TRUE(CheckCanLoadHttpInWindowOpen("/title2.html"));
665 EXPECT_EQ(last_request_relative_url(), "/title2.html");
666}
667
Hiroki Nakagawa3b90e642019-09-10 01:59:58668// Run tests with PlzDedicatedWorker.
669// TODO(https://crbug.com/906991): Merge this test fixture into
670// NetworkServiceRestartBrowserTest once PlzDedicatedWorker is enabled by
671// default.
672class NetworkServiceRestartForWorkerBrowserTest
673 : public NetworkServiceRestartBrowserTest,
674 public ::testing::WithParamInterface<bool> {
675 public:
676 NetworkServiceRestartForWorkerBrowserTest() {
677 if (GetParam()) {
678 scoped_feature_list_.InitAndEnableFeature(
679 blink::features::kPlzDedicatedWorker);
680 } else {
681 scoped_feature_list_.InitAndDisableFeature(
682 blink::features::kPlzDedicatedWorker);
683 }
684 }
685
686 private:
687 base::test::ScopedFeatureList scoped_feature_list_;
688};
689
690INSTANTIATE_TEST_SUITE_P(,
691 NetworkServiceRestartForWorkerBrowserTest,
692 ::testing::Values(false, true));
693
Chong Zhang4513fab2018-02-28 18:50:18694// Make sure worker fetch works after crash.
Hiroki Nakagawa3b90e642019-09-10 01:59:58695IN_PROC_BROWSER_TEST_P(NetworkServiceRestartForWorkerBrowserTest, WorkerFetch) {
Clark DuVall3290462e2019-02-16 02:19:50696 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36697 return;
Chong Zhang4513fab2018-02-28 18:50:18698 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
699 BrowserContext::GetDefaultStoragePartition(browser_context()));
700
701 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
702 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title1.html"));
703 EXPECT_EQ(last_request_relative_url(), "/title1.html");
704
705 // Crash the NetworkService process. Existing interfaces should receive error
706 // notifications at some point.
707 SimulateNetworkServiceCrash();
708 // Flush the interface to make sure the error notification was received.
709 partition->FlushNetworkInterfaceForTesting();
710 // Flush the interface to make sure the frame host has received error
711 // notification and the new URLLoaderFactoryBundle has been received by the
712 // frame.
713 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
714
715 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title2.html"));
716 EXPECT_EQ(last_request_relative_url(), "/title2.html");
717}
718
719// Make sure multiple workers are tracked correctly and work after crash.
Hiroki Nakagawa3b90e642019-09-10 01:59:58720IN_PROC_BROWSER_TEST_P(NetworkServiceRestartForWorkerBrowserTest,
721 MultipleWorkerFetch) {
Clark DuVall3290462e2019-02-16 02:19:50722 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36723 return;
Chong Zhang4513fab2018-02-28 18:50:18724 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
725 BrowserContext::GetDefaultStoragePartition(browser_context()));
726
727 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
728 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title1.html"));
729 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title1.html"));
730 EXPECT_EQ(last_request_relative_url(), "/title1.html");
731
732 // Crash the NetworkService process. Existing interfaces should receive error
733 // notifications at some point.
734 SimulateNetworkServiceCrash();
735 // Flush the interface to make sure the error notification was received.
736 partition->FlushNetworkInterfaceForTesting();
737 // Flush the interface to make sure the frame host has received error
738 // notification and the new URLLoaderFactoryBundle has been received by the
739 // frame.
740 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
741
742 // Both workers should work after crash.
743 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title2.html"));
744 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title2.html"));
745 EXPECT_EQ(last_request_relative_url(), "/title2.html");
746
747 // Terminate "worker1". "worker2" shouldn't be affected.
748 EXPECT_TRUE(TerminateWorker("worker1"));
749 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title1.html"));
750 EXPECT_EQ(last_request_relative_url(), "/title1.html");
751
752 // Crash the NetworkService process again. "worker2" should still work.
753 SimulateNetworkServiceCrash();
754 partition->FlushNetworkInterfaceForTesting();
755 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
756
757 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title2.html"));
758 EXPECT_EQ(last_request_relative_url(), "/title2.html");
759}
760
Makoto Shimazu775101a52018-09-26 04:46:52761// Make sure fetch from a page controlled by a service worker which doesn't have
762// a fetch handler works after crash.
Makoto Shimazu2540a642018-11-15 06:24:44763IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
764 FetchFromServiceWorkerControlledPage_NoFetchHandler) {
Clark DuVall3290462e2019-02-16 02:19:50765 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36766 return;
Makoto Shimazu775101a52018-09-26 04:46:52767 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
768 BrowserContext::GetDefaultStoragePartition(browser_context()));
769 ServiceWorkerStatusObserver observer;
770 ServiceWorkerContextWrapper* service_worker_context =
771 partition->GetServiceWorkerContext();
772 service_worker_context->AddObserver(&observer);
773
774 // Register a service worker which controls /service_worker/.
775 EXPECT_TRUE(NavigateToURL(shell(),
776 embedded_test_server()->GetURL(
777 "/service_worker/create_service_worker.html")));
778 EXPECT_EQ("DONE", EvalJs(shell(), "register('empty.js')"));
779
780 // Navigate to a controlled page.
781 EXPECT_TRUE(NavigateToURL(
782 shell(),
783 embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
784
785 // Fetch from the controlled page.
786 const std::string script = "fetch_from_page('/echo');";
787 EXPECT_EQ("Echo", EvalJs(shell(), script));
788
789 // Crash the NetworkService process. Existing interfaces should receive error
790 // notifications at some point.
791 SimulateNetworkServiceCrash();
792 // Flush the interface to make sure the error notification was received.
793 partition->FlushNetworkInterfaceForTesting();
794
795 // Service worker should be stopped when network service crashes.
Patrick Monette9f3aae62019-10-08 00:16:03796 observer.WaitForStopped();
Makoto Shimazu775101a52018-09-26 04:46:52797
798 // Fetch from the controlled page again.
799 EXPECT_EQ("Echo", EvalJs(shell(), script));
800
801 service_worker_context->RemoveObserver(&observer);
802}
803
804// Make sure fetch from a page controlled by a service worker which has a fetch
805// handler but falls back to the network works after crash.
806IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
Makoto Shimazu2540a642018-11-15 06:24:44807 FetchFromServiceWorkerControlledPage_PassThrough) {
Clark DuVall3290462e2019-02-16 02:19:50808 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36809 return;
Makoto Shimazu775101a52018-09-26 04:46:52810 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
811 BrowserContext::GetDefaultStoragePartition(browser_context()));
812 ServiceWorkerStatusObserver observer;
813 ServiceWorkerContextWrapper* service_worker_context =
814 partition->GetServiceWorkerContext();
815 service_worker_context->AddObserver(&observer);
816
817 // Register a service worker which controls /service_worker/.
818 EXPECT_TRUE(NavigateToURL(shell(),
819 embedded_test_server()->GetURL(
820 "/service_worker/create_service_worker.html")));
821 EXPECT_EQ("DONE", EvalJs(shell(), "register('fetch_event_pass_through.js')"));
822
823 // Navigate to a controlled page.
824 EXPECT_TRUE(NavigateToURL(
825 shell(),
826 embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
827
828 // Fetch from the controlled page.
829 const std::string script = "fetch_from_page('/echo');";
830 EXPECT_EQ("Echo", EvalJs(shell(), script));
831
832 // Crash the NetworkService process. Existing interfaces should receive error
833 // notifications at some point.
834 SimulateNetworkServiceCrash();
835 // Flush the interface to make sure the error notification was received.
836 partition->FlushNetworkInterfaceForTesting();
837
838 // Service worker should be stopped when network service crashes.
Patrick Monette9f3aae62019-10-08 00:16:03839 observer.WaitForStopped();
Makoto Shimazu775101a52018-09-26 04:46:52840
841 // Fetch from the controlled page again.
842 EXPECT_EQ("Echo", EvalJs(shell(), script));
843
844 service_worker_context->RemoveObserver(&observer);
845}
846
847// Make sure fetch from a page controlled by a service worker which has a fetch
848// handler and responds with fetch() works after crash.
Makoto Shimazu2540a642018-11-15 06:24:44849IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
850 FetchFromServiceWorkerControlledPage_RespondWithFetch) {
Clark DuVall3290462e2019-02-16 02:19:50851 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36852 return;
Makoto Shimazu775101a52018-09-26 04:46:52853 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
854 BrowserContext::GetDefaultStoragePartition(browser_context()));
855 ServiceWorkerStatusObserver observer;
856 ServiceWorkerContextWrapper* service_worker_context =
857 partition->GetServiceWorkerContext();
858 service_worker_context->AddObserver(&observer);
859
860 // Register a service worker which controls /service_worker/.
861 EXPECT_TRUE(NavigateToURL(shell(),
862 embedded_test_server()->GetURL(
863 "/service_worker/create_service_worker.html")));
864 EXPECT_EQ("DONE",
865 EvalJs(shell(), "register('fetch_event_respond_with_fetch.js')"));
866
867 // Navigate to a controlled page.
868 EXPECT_TRUE(NavigateToURL(
869 shell(),
870 embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
871
872 // Fetch from the controlled page.
873 const std::string script = "fetch_from_page('/echo');";
874 EXPECT_EQ("Echo", EvalJs(shell(), script));
875
876 // Crash the NetworkService process. Existing interfaces should receive error
877 // notifications at some point.
878 SimulateNetworkServiceCrash();
879 // Flush the interface to make sure the error notification was received.
880 partition->FlushNetworkInterfaceForTesting();
881
882 // Service worker should be stopped when network service crashes.
Patrick Monette9f3aae62019-10-08 00:16:03883 observer.WaitForStopped();
Makoto Shimazu775101a52018-09-26 04:46:52884
885 // Fetch from the controlled page again.
886 EXPECT_EQ("Echo", EvalJs(shell(), script));
887
888 service_worker_context->RemoveObserver(&observer);
889}
890
Makoto Shimazu2075b0d2018-09-21 09:04:22891// Make sure fetch from service worker context works after crash.
Makoto Shimazu6a96cb62018-09-21 11:39:13892IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, ServiceWorkerFetch) {
Clark DuVall3290462e2019-02-16 02:19:50893 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36894 return;
Makoto Shimazu2075b0d2018-09-21 09:04:22895 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
896 BrowserContext::GetDefaultStoragePartition(browser_context()));
897 ServiceWorkerStatusObserver observer;
898 ServiceWorkerContextWrapper* service_worker_context =
899 partition->GetServiceWorkerContext();
900 service_worker_context->AddObserver(&observer);
901
902 const GURL page_url = embedded_test_server()->GetURL(
903 "/service_worker/fetch_from_service_worker.html");
904 const GURL fetch_url = embedded_test_server()->GetURL("/echo");
905
906 // Navigate to the page and register a service worker.
907 EXPECT_TRUE(NavigateToURL(shell(), page_url));
908 EXPECT_EQ("ready", EvalJs(shell(), "setup();"));
909
910 // Fetch from the service worker.
911 const std::string script =
912 "fetch_from_service_worker('" + fetch_url.spec() + "');";
913 EXPECT_EQ("Echo", EvalJs(shell(), script));
914
915 // Crash the NetworkService process. Existing interfaces should receive error
916 // notifications at some point.
917 SimulateNetworkServiceCrash();
918 // Flush the interface to make sure the error notification was received.
919 partition->FlushNetworkInterfaceForTesting();
920
921 // Service worker should be stopped when network service crashes.
Patrick Monette9f3aae62019-10-08 00:16:03922 observer.WaitForStopped();
Makoto Shimazu2075b0d2018-09-21 09:04:22923
924 // Fetch from the service worker again.
925 EXPECT_EQ("Echo", EvalJs(shell(), script));
926
927 service_worker_context->RemoveObserver(&observer);
928}
929
Clark DuVallf742bcbd2018-11-07 17:16:20930// TODO(crbug.com/154571): Shared workers are not available on Android.
931#if defined(OS_ANDROID)
932#define MAYBE_SharedWorker DISABLED_SharedWorker
933#else
934#define MAYBE_SharedWorker SharedWorker
935#endif
Matt Falkenhagene6721962018-10-05 10:17:05936// Make sure shared workers terminate after crash.
Clark DuVallf742bcbd2018-11-07 17:16:20937IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, MAYBE_SharedWorker) {
Clark DuVall3290462e2019-02-16 02:19:50938 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36939 return;
Makoto Shimazu2075b0d2018-09-21 09:04:22940 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
941 BrowserContext::GetDefaultStoragePartition(browser_context()));
942
Patrick Monette3f51a042019-08-30 17:57:04943 InjectTestSharedWorkerService(partition);
944
Makoto Shimazu2075b0d2018-09-21 09:04:22945 const GURL page_url =
946 embedded_test_server()->GetURL("/workers/fetch_from_shared_worker.html");
947 const GURL fetch_url = embedded_test_server()->GetURL("/echo");
948
949 // Navigate to the page and prepare a shared worker.
950 EXPECT_TRUE(NavigateToURL(shell(), page_url));
951
Matt Falkenhagene6721962018-10-05 10:17:05952 // Fetch from the shared worker to ensure it has started.
Finditc0f7c6202018-10-05 07:14:23953 const std::string script =
954 "fetch_from_shared_worker('" + fetch_url.spec() + "');";
955 EXPECT_EQ("Echo", EvalJs(shell(), script));
Makoto Shimazu2075b0d2018-09-21 09:04:22956
Matt Falkenhagene6721962018-10-05 10:17:05957 // There should be one worker host. We will later wait for it to terminate.
Patrick Monette3f51a042019-08-30 17:57:04958 TestSharedWorkerServiceImpl* service =
959 static_cast<TestSharedWorkerServiceImpl*>(
960 partition->GetSharedWorkerService());
Matt Falkenhagene6721962018-10-05 10:17:05961 EXPECT_EQ(1u, service->worker_hosts_.size());
962 base::RunLoop loop;
Patrick Monette3f51a042019-08-30 17:57:04963 service->SetWorkerTerminationCallback(loop.QuitClosure());
Makoto Shimazu2075b0d2018-09-21 09:04:22964
Matt Falkenhagene6721962018-10-05 10:17:05965 // Crash the NetworkService process.
966 SimulateNetworkServiceCrash();
967
968 // Wait for the worker to detect the crash and self-terminate.
969 loop.Run();
970 EXPECT_TRUE(service->worker_hosts_.empty());
Makoto Shimazu2075b0d2018-09-21 09:04:22971}
972
Chong Zhang53047762018-05-02 21:24:08973// Make sure the entry in |NetworkService::GetTotalNetworkUsages()| was cleared
974// after process closed.
975IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
976 GetNetworkUsagesClosed) {
Clark DuVall3290462e2019-02-16 02:19:50977 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36978 return;
Chong Zhang53047762018-05-02 21:24:08979 EXPECT_TRUE(NavigateToURL(shell(), GetTestURL()));
980 Shell* shell2 = CreateBrowser();
981 EXPECT_TRUE(NavigateToURL(shell2, GetTestURL()));
982
983 int process_id1 =
984 shell()->web_contents()->GetMainFrame()->GetProcess()->GetID();
985 int process_id2 =
986 shell2->web_contents()->GetMainFrame()->GetProcess()->GetID();
987
988 // Load resource on the renderer to make sure the traffic was recorded.
989 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
990 EXPECT_TRUE(CheckCanLoadHttp(shell2, "/title3.html"));
991
992 // Both processes should have traffic recorded.
993 auto network_usages = GetTotalNetworkUsages();
994 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
995 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id2));
996
997 // Closing |shell2| should cause the entry to be cleared.
998 shell2->Close();
999 shell2 = nullptr;
1000
1001 // Wait until the Network Service has noticed the change. We don't have a
1002 // better way to force a flush on the Network Service side.
1003 WaitForCondition(base::BindRepeating(
1004 [](int process_id) {
1005 auto usages = GetTotalNetworkUsages();
1006 return !CheckContainsProcessID(usages, process_id);
1007 },
1008 process_id2));
1009
1010 network_usages = GetTotalNetworkUsages();
1011 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
1012 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id2));
1013}
1014
Christopher Thompson2a4c69e92019-08-21 16:29:111015// Make sure that kSSLKeyLogFileHistogram is correctly recorded when the
1016// network service instance is started and the SSLKEYLOGFILE env var is set or
1017// the "--ssl-key-log-file" arg is set.
1018IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, SSLKeyLogFileMetrics) {
1019 if (IsInProcessNetworkService())
1020 return;
1021 // Actions on temporary files are blocking.
1022 base::ScopedAllowBlockingForTesting scoped_allow_blocking;
1023 base::FilePath log_file_path;
1024 base::CreateTemporaryFile(&log_file_path);
1025
1026#if defined(OS_WIN)
1027 // On Windows, FilePath::value() returns base::string16, so convert.
1028 std::string log_file_path_str = base::UTF16ToUTF8(log_file_path.value());
1029#else
1030 std::string log_file_path_str = log_file_path.value();
1031#endif
1032
1033 // Test that env var causes the histogram to be recorded.
1034 {
1035 base::test::ScopedEnvironmentVariableOverride scoped_env("SSLKEYLOGFILE",
1036 log_file_path_str);
1037 base::HistogramTester histograms;
1038 // Restart network service to cause SSLKeyLogger to be re-initialized.
1039 SimulateNetworkServiceCrash();
1040 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1041 SSLKeyLogFileAction::kLogFileEnabled, 1);
1042 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1043 SSLKeyLogFileAction::kEnvVarFound, 1);
1044 }
1045
1046 // Test that the command-line switch causes the histogram to be recorded.
1047 {
1048 base::test::ScopedCommandLine scoped_command_line;
1049 scoped_command_line.GetProcessCommandLine()->AppendSwitchPath(
1050 "ssl-key-log-file", log_file_path);
1051 base::HistogramTester histograms;
1052 // Restart network service to cause SSLKeyLogger to be re-initialized.
1053 SimulateNetworkServiceCrash();
1054 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1055 SSLKeyLogFileAction::kLogFileEnabled, 1);
1056 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1057 SSLKeyLogFileAction::kSwitchFound, 1);
1058 }
1059}
1060
Chong Zhang53047762018-05-02 21:24:081061// Make sure |NetworkService::GetTotalNetworkUsages()| continues to work after
1062// crash. See 'network_usage_accumulator_unittest' for quantified tests.
1063IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
1064 GetNetworkUsagesCrashed) {
Clark DuVall3290462e2019-02-16 02:19:501065 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361066 return;
Chong Zhang53047762018-05-02 21:24:081067 EXPECT_TRUE(NavigateToURL(shell(), GetTestURL()));
1068 Shell* shell2 = CreateBrowser();
1069 EXPECT_TRUE(NavigateToURL(shell2, GetTestURL()));
1070
1071 int process_id1 =
1072 shell()->web_contents()->GetMainFrame()->GetProcess()->GetID();
1073 int process_id2 =
1074 shell2->web_contents()->GetMainFrame()->GetProcess()->GetID();
1075
1076 // Load resource on the renderer to make sure the traffic was recorded.
1077 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
1078 EXPECT_TRUE(CheckCanLoadHttp(shell2, "/title3.html"));
1079
1080 // Both processes should have traffic recorded.
1081 auto network_usages = GetTotalNetworkUsages();
1082 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
1083 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id2));
1084
1085 // Crashing Network Service should cause all entries to be cleared.
1086 SimulateNetworkServiceCrash();
1087 network_usages = GetTotalNetworkUsages();
1088 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id1));
1089 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id2));
1090
1091 // Should still be able to recored new traffic after crash.
1092 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
1093 network_usages = GetTotalNetworkUsages();
1094 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
1095 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id2));
1096}
1097
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141098// Make sure cookie access doesn't hang or fail after a network process crash.
1099IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, Cookies) {
Clark DuVall3290462e2019-02-16 02:19:501100 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361101 return;
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141102 auto* web_contents = shell()->web_contents();
Lukasz Anforowiczce4487b72018-10-23 18:05:531103 ASSERT_TRUE(
1104 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141105 EXPECT_TRUE(ExecuteScript(web_contents, "document.cookie = 'foo=bar';"));
1106
1107 std::string cookie;
1108 EXPECT_TRUE(ExecuteScriptAndExtractString(
1109 web_contents, "window.domAutomationController.send(document.cookie);",
1110 &cookie));
1111 EXPECT_EQ("foo=bar", cookie);
1112
1113 SimulateNetworkServiceCrash();
1114
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141115 // content_shell uses in-memory cookie database, so the value saved earlier
1116 // won't persist across crashes. What matters is that new access works.
1117 EXPECT_TRUE(ExecuteScript(web_contents, "document.cookie = 'foo=bar';"));
1118
1119 // This will hang without the fix.
1120 EXPECT_TRUE(ExecuteScriptAndExtractString(
1121 web_contents, "window.domAutomationController.send(document.cookie);",
1122 &cookie));
1123 EXPECT_EQ("foo=bar", cookie);
1124}
1125
Lukasz Anforowiczce4487b72018-10-23 18:05:531126#if BUILDFLAG(ENABLE_PLUGINS)
1127// Make sure that "trusted" plugins continue to be able to issue cross-origin
1128// requests after a network process crash.
1129IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, Plugin) {
Clark DuVall3290462e2019-02-16 02:19:501130 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361131 return;
Lukasz Anforowiczce4487b72018-10-23 18:05:531132 auto* web_contents = shell()->web_contents();
1133 ASSERT_TRUE(NavigateToURL(web_contents,
1134 embedded_test_server()->GetURL("/title1.html")));
1135
1136 // Load the test plugin (see ppapi::RegisterFlashTestPlugin and
1137 // ppapi/tests/power_saver_test_plugin.cc).
1138 const char kLoadingScript[] = R"(
1139 var obj = document.createElement('object');
1140 obj.id = 'plugin';
1141 obj.data = 'test.swf';
1142 obj.type = 'application/x-shockwave-flash';
1143 obj.width = 400;
1144 obj.height = 400;
1145
1146 document.body.appendChild(obj);
1147 )";
1148 ASSERT_TRUE(ExecJs(web_contents, kLoadingScript));
1149
1150 // Ask the plugin to perform a cross-origin, CORB-eligible (i.e.
1151 // application/json + nosniff) URL request. Plugins with universal access
1152 // should not be subject to CORS/CORB and so the request should go through.
1153 // See also https://crbug.com/874515 and https://crbug.com/846339.
1154 GURL cross_origin_url = embedded_test_server()->GetURL(
1155 "cross.origin.com", "/site_isolation/nosniff.json");
1156 const char kFetchScriptTemplate[] = R"(
1157 new Promise(function (resolve, reject) {
1158 var obj = document.getElementById('plugin');
1159 function callback(event) {
1160 // Ignore plugin messages unrelated to requestUrl.
1161 if (!event.data.startsWith('requestUrl: '))
1162 return;
1163
1164 obj.removeEventListener('message', callback);
1165 resolve('msg-from-plugin: ' + event.data);
1166 };
1167 obj.addEventListener('message', callback);
1168 obj.postMessage('requestUrl: ' + $1);
1169 });
1170 )";
1171 std::string fetch_script = JsReplace(kFetchScriptTemplate, cross_origin_url);
1172 ASSERT_EQ(
1173 "msg-from-plugin: requestUrl: RESPONSE BODY: "
1174 "runMe({ \"name\" : \"chromium\" });\n",
1175 EvalJs(web_contents, fetch_script));
1176
1177 // Crash the Network Service process and wait until host frame's
1178 // URLLoaderFactory has been refreshed.
1179 SimulateNetworkServiceCrash();
1180 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
1181
1182 // Try the fetch again - it should still work (i.e. the mechanism for relaxing
1183 // CORB for universal-access-plugins should be resilient to network process
1184 // crashes). See also https://crbug.com/891904.
1185 ASSERT_EQ(
1186 "msg-from-plugin: requestUrl: RESPONSE BODY: "
1187 "runMe({ \"name\" : \"chromium\" });\n",
1188 EvalJs(web_contents, fetch_script));
1189}
1190#endif
1191
Clark DuVallf742bcbd2018-11-07 17:16:201192// TODO(crbug.com/901026): Fix deadlock on process startup on Android.
1193#if defined(OS_ANDROID)
1194#define MAYBE_SyncCallDuringRestart DISABLED_SyncCallDuringRestart
1195#else
1196#define MAYBE_SyncCallDuringRestart SyncCallDuringRestart
1197#endif
1198IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
1199 MAYBE_SyncCallDuringRestart) {
Clark DuVall3290462e2019-02-16 02:19:501200 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361201 return;
Clark DuVallf742bcbd2018-11-07 17:16:201202 base::RunLoop run_loop;
Ken Rockot91216c0f2019-10-11 20:38:111203 mojo::Remote<network::mojom::NetworkServiceTest> network_service_test;
1204 content::GetNetworkService()->BindTestInterface(
1205 network_service_test.BindNewPipeAndPassReceiver());
Clark DuVallf742bcbd2018-11-07 17:16:201206
1207 // Crash the network service, but do not wait for full startup.
Ken Rockot91216c0f2019-10-11 20:38:111208 network_service_test.set_disconnect_handler(run_loop.QuitClosure());
Clark DuVallf742bcbd2018-11-07 17:16:201209 network_service_test->SimulateCrash();
1210 run_loop.Run();
1211
Ken Rockot91216c0f2019-10-11 20:38:111212 network_service_test.reset();
1213 content::GetNetworkService()->BindTestInterface(
1214 network_service_test.BindNewPipeAndPassReceiver());
Clark DuVallf742bcbd2018-11-07 17:16:201215
1216 // Sync call should be fine, even though network process is still starting up.
1217 mojo::ScopedAllowSyncCallForTesting allow_sync_call;
1218 network_service_test->AddRules({});
1219}
1220
Chong Zhangc583e672017-11-08 16:34:081221} // namespace content