blob: 7eb1e9138402827ec1a577aa5643bb118336ef94 [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:
133 void WaitForState(EmbeddedWorkerStatus expected_status) {
Makoto Shimazu2540a642018-11-15 06:24:44134 for (const auto& status : statuses_in_past_) {
135 if (status == expected_status)
136 return;
137 }
Makoto Shimazu2075b0d2018-09-21 09:04:22138
139 expected_status_ = expected_status;
140 base::RunLoop loop;
141 callback_ = loop.QuitClosure();
142 loop.Run();
143 }
144
145 private:
146 void OnRunningStateChanged(int64_t version_id,
147 EmbeddedWorkerStatus running_status) override {
Makoto Shimazu2540a642018-11-15 06:24:44148 statuses_in_past_.push_back(running_status);
Makoto Shimazu2075b0d2018-09-21 09:04:22149 if (expected_status_.has_value() &&
150 running_status == expected_status_.value()) {
151 std::move(callback_).Run();
152 }
153 }
154
155 base::Optional<EmbeddedWorkerStatus> expected_status_;
Makoto Shimazu2540a642018-11-15 06:24:44156 std::vector<EmbeddedWorkerStatus> statuses_in_past_;
Makoto Shimazu2075b0d2018-09-21 09:04:22157 base::OnceClosure callback_;
158};
159
Chong Zhangc583e672017-11-08 16:34:08160} // namespace
161
Chong Zhangc583e672017-11-08 16:34:08162class NetworkServiceRestartBrowserTest : public ContentBrowserTest {
163 public:
John Abd-El-Malekc134dd82019-07-31 20:51:44164 NetworkServiceRestartBrowserTest() {}
Chong Zhang7306b0b2018-01-24 05:59:24165
Lukasz Anforowiczce4487b72018-10-23 18:05:53166 void SetUpCommandLine(base::CommandLine* command_line) override {
167#if BUILDFLAG(ENABLE_PLUGINS)
168 ASSERT_TRUE(ppapi::RegisterCorbTestPlugin(command_line));
169#endif
170 ContentBrowserTest::SetUpCommandLine(command_line);
171 }
172
Chong Zhang7306b0b2018-01-24 05:59:24173 void SetUpOnMainThread() override {
Chong Zhang5d9b34182018-01-30 16:20:57174 embedded_test_server()->RegisterRequestMonitor(
175 base::BindRepeating(&NetworkServiceRestartBrowserTest::MonitorRequest,
176 base::Unretained(this)));
Lukasz Anforowiczce4487b72018-10-23 18:05:53177 host_resolver()->AddRule("*", "127.0.0.1");
Chong Zhangc583e672017-11-08 16:34:08178 EXPECT_TRUE(embedded_test_server()->Start());
Chong Zhang7306b0b2018-01-24 05:59:24179 ContentBrowserTest::SetUpOnMainThread();
Chong Zhangc583e672017-11-08 16:34:08180 }
181
Chong Zhangc40a6ce52017-12-10 03:00:28182 GURL GetTestURL() const {
Chong Zhang5f468272017-12-07 23:59:14183 // Use '/echoheader' instead of '/echo' to avoid a disk_cache bug.
184 // See https://crbug.com/792255.
Chong Zhangc40a6ce52017-12-10 03:00:28185 return embedded_test_server()->GetURL("/echoheader");
Chong Zhangc583e672017-11-08 16:34:08186 }
187
Chong Zhangd4c923642018-01-03 21:22:29188 BrowserContext* browser_context() {
189 return shell()->web_contents()->GetBrowserContext();
190 }
191
Chong Zhang5d9b34182018-01-30 16:20:57192 RenderFrameHostImpl* main_frame() {
193 return static_cast<RenderFrameHostImpl*>(
194 shell()->web_contents()->GetMainFrame());
195 }
196
Chong Zhang53047762018-05-02 21:24:08197 bool CheckCanLoadHttp(Shell* shell, const std::string& relative_url) {
Chong Zhang5d9b34182018-01-30 16:20:57198 GURL test_url = embedded_test_server()->GetURL(relative_url);
199 std::string script(
200 "var xhr = new XMLHttpRequest();"
201 "xhr.open('GET', '");
202 script += test_url.spec() +
203 "', true);"
204 "xhr.onload = function (e) {"
205 " if (xhr.readyState === 4) {"
206 " window.domAutomationController.send(xhr.status === 200);"
207 " }"
208 "};"
209 "xhr.onerror = function () {"
210 " window.domAutomationController.send(false);"
211 "};"
212 "xhr.send(null)";
213 bool xhr_result = false;
214 // The JS call will fail if disallowed because the process will be killed.
215 bool execute_result =
Chong Zhang53047762018-05-02 21:24:08216 ExecuteScriptAndExtractBool(shell, script, &xhr_result);
Chong Zhang5d9b34182018-01-30 16:20:57217 return xhr_result && execute_result;
218 }
219
Chong Zhang4513fab2018-02-28 18:50:18220 // Will reuse the single opened windows through the test case.
221 bool CheckCanLoadHttpInWindowOpen(const std::string& relative_url) {
222 GURL test_url = embedded_test_server()->GetURL(relative_url);
223 std::string inject_script = base::StringPrintf(
224 "var xhr = new XMLHttpRequest();"
225 "xhr.open('GET', '%s', true);"
226 "xhr.onload = function (e) {"
227 " if (xhr.readyState === 4) {"
228 " window.opener.domAutomationController.send(xhr.status === 200);"
229 " }"
230 "};"
231 "xhr.onerror = function () {"
232 " window.opener.domAutomationController.send(false);"
233 "};"
234 "xhr.send(null)",
235 test_url.spec().c_str());
236 std::string window_open_script = base::StringPrintf(
237 "var new_window = new_window || window.open('');"
238 "var inject_script = document.createElement('script');"
239 "inject_script.innerHTML = \"%s\";"
240 "new_window.document.body.appendChild(inject_script);",
241 inject_script.c_str());
242
243 bool xhr_result = false;
244 // The JS call will fail if disallowed because the process will be killed.
245 bool execute_result =
246 ExecuteScriptAndExtractBool(shell(), window_open_script, &xhr_result);
247 return xhr_result && execute_result;
248 }
249
250 // Workers will live throughout the test case unless terminated.
251 bool CheckCanWorkerFetch(const std::string& worker_name,
252 const std::string& relative_url) {
253 GURL worker_url =
254 embedded_test_server()->GetURL("/workers/worker_common.js");
255 GURL fetch_url = embedded_test_server()->GetURL(relative_url);
256 std::string script = base::StringPrintf(
257 "var workers = workers || {};"
258 "var worker_name = '%s';"
259 "workers[worker_name] = workers[worker_name] || new Worker('%s');"
260 "workers[worker_name].onmessage = evt => {"
261 " if (evt.data != 'wait')"
262 " window.domAutomationController.send(evt.data === 200);"
263 "};"
264 "workers[worker_name].postMessage(\"eval "
265 " fetch(new Request('%s'))"
266 " .then(res => postMessage(res.status))"
267 " .catch(error => postMessage(error.toString()));"
268 " 'wait'"
269 "\");",
270 worker_name.c_str(), worker_url.spec().c_str(),
271 fetch_url.spec().c_str());
272 bool fetch_result = false;
273 // The JS call will fail if disallowed because the process will be killed.
274 bool execute_result =
275 ExecuteScriptAndExtractBool(shell(), script, &fetch_result);
276 return fetch_result && execute_result;
277 }
278
279 // Terminate and delete the worker.
280 bool TerminateWorker(const std::string& worker_name) {
281 std::string script = base::StringPrintf(
282 "var workers = workers || {};"
283 "var worker_name = '%s';"
284 "if (workers[worker_name]) {"
285 " workers[worker_name].terminate();"
286 " delete workers[worker_name];"
287 " window.domAutomationController.send(true);"
288 "} else {"
289 " window.domAutomationController.send(false);"
290 "}",
291 worker_name.c_str());
292 bool fetch_result = false;
293 // The JS call will fail if disallowed because the process will be killed.
294 bool execute_result =
295 ExecuteScriptAndExtractBool(shell(), script, &fetch_result);
296 return fetch_result && execute_result;
297 }
298
Chong Zhang5d9b34182018-01-30 16:20:57299 // Called by |embedded_test_server()|.
300 void MonitorRequest(const net::test_server::HttpRequest& request) {
David Benjaminff93edd2019-06-19 22:51:58301 base::AutoLock lock(last_request_lock_);
Chong Zhang5d9b34182018-01-30 16:20:57302 last_request_relative_url_ = request.relative_url;
303 }
304
305 std::string last_request_relative_url() const {
David Benjaminff93edd2019-06-19 22:51:58306 base::AutoLock lock(last_request_lock_);
Chong Zhang5d9b34182018-01-30 16:20:57307 return last_request_relative_url_;
308 }
309
Chong Zhangc583e672017-11-08 16:34:08310 private:
David Benjaminff93edd2019-06-19 22:51:58311 mutable base::Lock last_request_lock_;
312 std::string last_request_relative_url_ GUARDED_BY(last_request_lock_);
Chong Zhangc583e672017-11-08 16:34:08313
314 DISALLOW_COPY_AND_ASSIGN(NetworkServiceRestartBrowserTest);
315};
316
317IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
318 NetworkServiceProcessRecovery) {
Clark DuVall3290462e2019-02-16 02:19:50319 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36320 return;
Julie Jeongeun Kim5984e992019-09-11 11:00:46321 mojo::Remote<network::mojom::NetworkContext> network_context(
322 CreateNetworkContext());
Chong Zhangc40a6ce52017-12-10 03:00:28323 EXPECT_EQ(net::OK, LoadBasicRequest(network_context.get(), GetTestURL()));
Chong Zhangc583e672017-11-08 16:34:08324 EXPECT_TRUE(network_context.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46325 EXPECT_TRUE(network_context.is_connected());
Chong Zhangc583e672017-11-08 16:34:08326
Chong Zhang5f468272017-12-07 23:59:14327 // Crash the NetworkService process. Existing interfaces should receive error
328 // notifications at some point.
Chong Zhangc583e672017-11-08 16:34:08329 SimulateNetworkServiceCrash();
Chong Zhang5f468272017-12-07 23:59:14330 // |network_context| will receive an error notification, but it's not
Julie Jeongeun Kim5984e992019-09-11 11:00:46331 // guaranteed to have arrived at this point. Flush the remote to make sure
Chong Zhang5f468272017-12-07 23:59:14332 // the notification has been received.
333 network_context.FlushForTesting();
Chong Zhangc583e672017-11-08 16:34:08334 EXPECT_TRUE(network_context.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46335 EXPECT_FALSE(network_context.is_connected());
Chong Zhang5f468272017-12-07 23:59:14336 // Make sure we could get |net::ERR_FAILED| with an invalid |network_context|.
Chong Zhangc40a6ce52017-12-10 03:00:28337 EXPECT_EQ(net::ERR_FAILED,
338 LoadBasicRequest(network_context.get(), GetTestURL()));
Chong Zhangc583e672017-11-08 16:34:08339
340 // NetworkService should restart automatically and return valid interface.
Julie Jeongeun Kim5984e992019-09-11 11:00:46341 mojo::Remote<network::mojom::NetworkContext> network_context2(
342 CreateNetworkContext());
Chong Zhangc40a6ce52017-12-10 03:00:28343 EXPECT_EQ(net::OK, LoadBasicRequest(network_context2.get(), GetTestURL()));
Chong Zhangc583e672017-11-08 16:34:08344 EXPECT_TRUE(network_context2.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46345 EXPECT_TRUE(network_context2.is_connected());
Chong Zhangc583e672017-11-08 16:34:08346}
347
Lukasz Anforowiczce4487b72018-10-23 18:05:53348void IncrementInt(int* i) {
349 *i = *i + 1;
350}
351
352// This test verifies basic functionality of RegisterNetworkServiceCrashHandler
353// and UnregisterNetworkServiceCrashHandler.
354IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, CrashHandlers) {
Clark DuVall3290462e2019-02-16 02:19:50355 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36356 return;
Julie Jeongeun Kim5984e992019-09-11 11:00:46357 mojo::Remote<network::mojom::NetworkContext> network_context(
358 CreateNetworkContext());
Lukasz Anforowiczce4487b72018-10-23 18:05:53359 EXPECT_TRUE(network_context.is_bound());
360
361 // Register 2 crash handlers.
362 int counter1 = 0;
363 int counter2 = 0;
Lukasz Anforowiczc195e912018-10-30 16:20:54364 auto handler1 = RegisterNetworkServiceCrashHandler(
Lukasz Anforowiczce4487b72018-10-23 18:05:53365 base::BindRepeating(&IncrementInt, base::Unretained(&counter1)));
Lukasz Anforowiczc195e912018-10-30 16:20:54366 auto handler2 = RegisterNetworkServiceCrashHandler(
Lukasz Anforowiczce4487b72018-10-23 18:05:53367 base::BindRepeating(&IncrementInt, base::Unretained(&counter2)));
368
369 // Crash the NetworkService process.
370 SimulateNetworkServiceCrash();
371 // |network_context| will receive an error notification, but it's not
Julie Jeongeun Kim5984e992019-09-11 11:00:46372 // guaranteed to have arrived at this point. Flush the remote to make sure
Lukasz Anforowiczce4487b72018-10-23 18:05:53373 // the notification has been received.
374 network_context.FlushForTesting();
375 EXPECT_TRUE(network_context.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46376 EXPECT_FALSE(network_context.is_connected());
Lukasz Anforowiczce4487b72018-10-23 18:05:53377
378 // Verify the crash handlers executed.
379 EXPECT_EQ(1, counter1);
380 EXPECT_EQ(1, counter2);
381
382 // Revive the NetworkService process.
Julie Jeongeun Kim5984e992019-09-11 11:00:46383 network_context.reset();
384 network_context.Bind(CreateNetworkContext());
Lukasz Anforowiczce4487b72018-10-23 18:05:53385 EXPECT_TRUE(network_context.is_bound());
386
387 // Unregister one of the handlers.
Lukasz Anforowiczc195e912018-10-30 16:20:54388 handler2.reset();
Lukasz Anforowiczce4487b72018-10-23 18:05:53389
390 // Crash the NetworkService process.
391 SimulateNetworkServiceCrash();
392 // |network_context| will receive an error notification, but it's not
Julie Jeongeun Kim5984e992019-09-11 11:00:46393 // guaranteed to have arrived at this point. Flush the remote to make sure
Lukasz Anforowiczce4487b72018-10-23 18:05:53394 // the notification has been received.
395 network_context.FlushForTesting();
396 EXPECT_TRUE(network_context.is_bound());
Julie Jeongeun Kim5984e992019-09-11 11:00:46397 EXPECT_FALSE(network_context.is_connected());
Lukasz Anforowiczce4487b72018-10-23 18:05:53398
399 // Verify only the first crash handler executed.
400 EXPECT_EQ(2, counter1);
401 EXPECT_EQ(1, counter2);
Lukasz Anforowiczce4487b72018-10-23 18:05:53402}
403
Chong Zhang5f468272017-12-07 23:59:14404// Make sure |StoragePartitionImpl::GetNetworkContext()| returns valid interface
405// after crash.
406IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
Chong Zhange0dfdb62017-12-09 18:25:14407 StoragePartitionImplGetNetworkContext) {
Clark DuVall3290462e2019-02-16 02:19:50408 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36409 return;
Chong Zhang5f468272017-12-07 23:59:14410 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
Chong Zhangd4c923642018-01-03 21:22:29411 BrowserContext::GetDefaultStoragePartition(browser_context()));
Chong Zhang5f468272017-12-07 23:59:14412
John Abd-El-Malek53670dd2018-01-18 22:07:21413 network::mojom::NetworkContext* old_network_context =
414 partition->GetNetworkContext();
Chong Zhangc40a6ce52017-12-10 03:00:28415 EXPECT_EQ(net::OK, LoadBasicRequest(old_network_context, GetTestURL()));
Chong Zhang5f468272017-12-07 23:59:14416
417 // Crash the NetworkService process. Existing interfaces should receive error
418 // notifications at some point.
419 SimulateNetworkServiceCrash();
420 // Flush the interface to make sure the error notification was received.
421 partition->FlushNetworkInterfaceForTesting();
422
423 // |partition->GetNetworkContext()| should return a valid new pointer after
424 // crash.
425 EXPECT_NE(old_network_context, partition->GetNetworkContext());
Chong Zhangc40a6ce52017-12-10 03:00:28426 EXPECT_EQ(net::OK,
427 LoadBasicRequest(partition->GetNetworkContext(), GetTestURL()));
Chong Zhang5f468272017-12-07 23:59:14428}
429
Chong Zhangd4c923642018-01-03 21:22:29430// Make sure |URLLoaderFactoryGetter| returns valid interface after crash.
431IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
432 URLLoaderFactoryGetterGetNetworkFactory) {
Clark DuVall3290462e2019-02-16 02:19:50433 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36434 return;
Chong Zhangd4c923642018-01-03 21:22:29435 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
436 BrowserContext::GetDefaultStoragePartition(browser_context()));
437 scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter =
438 partition->url_loader_factory_getter();
Chong Zhang5271432a2018-03-01 23:31:02439
Chong Zhang83d0e4f2018-05-04 18:55:09440 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
441 url_loader_factory_getter.get());
442 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02443
Chong Zhangd4c923642018-01-03 21:22:29444 // Crash the NetworkService process. Existing interfaces should receive error
445 // notifications at some point.
446 SimulateNetworkServiceCrash();
447 // Flush the interface to make sure the error notification was received.
448 partition->FlushNetworkInterfaceForTesting();
449 url_loader_factory_getter->FlushNetworkInterfaceOnIOThreadForTesting();
450
451 // |url_loader_factory_getter| should be able to get a valid new pointer after
452 // crash.
Chong Zhang83d0e4f2018-05-04 18:55:09453 factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
454 url_loader_factory_getter.get());
455 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02456}
457
458// Make sure the factory returned from
459// |URLLoaderFactoryGetter::GetNetworkFactory()| continues to work after
460// crashes.
461IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
462 BrowserIOSharedURLLoaderFactory) {
Clark DuVall3290462e2019-02-16 02:19:50463 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36464 return;
Chong Zhang5271432a2018-03-01 23:31:02465 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
466 BrowserContext::GetDefaultStoragePartition(browser_context()));
467
Chong Zhang83d0e4f2018-05-04 18:55:09468 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
469 partition->url_loader_factory_getter().get());
Chong Zhang5271432a2018-03-01 23:31:02470
Chong Zhang83d0e4f2018-05-04 18:55:09471 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02472
473 // Crash the NetworkService process. Existing interfaces should receive error
474 // notifications at some point.
475 SimulateNetworkServiceCrash();
476 // Flush the interface to make sure the error notification was received.
477 partition->FlushNetworkInterfaceForTesting();
478 partition->url_loader_factory_getter()
479 ->FlushNetworkInterfaceOnIOThreadForTesting();
480
481 // |shared_factory| should continue to work.
Chong Zhang83d0e4f2018-05-04 18:55:09482 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02483}
484
485// Make sure the factory returned from
486// |URLLoaderFactoryGetter::GetNetworkFactory()| doesn't crash if
487// it's called after the StoragePartition is deleted.
Chong Zhangf8572182018-03-16 23:10:18488IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
489 BrowserIOSharedFactoryAfterStoragePartitionGone) {
Clark DuVall3290462e2019-02-16 02:19:50490 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36491 return;
Chong Zhang5271432a2018-03-01 23:31:02492 base::ScopedAllowBlockingForTesting allow_blocking;
493 std::unique_ptr<ShellBrowserContext> browser_context =
Eric Romanb56d0ef2019-07-02 17:36:06494 std::make_unique<ShellBrowserContext>(true);
Chong Zhang5271432a2018-03-01 23:31:02495 auto* partition = static_cast<StoragePartitionImpl*>(
496 BrowserContext::GetDefaultStoragePartition(browser_context.get()));
Chong Zhang83d0e4f2018-05-04 18:55:09497 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
498 partition->url_loader_factory_getter().get());
Chong Zhang5271432a2018-03-01 23:31:02499
Chong Zhang83d0e4f2018-05-04 18:55:09500 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang5271432a2018-03-01 23:31:02501
502 browser_context.reset();
503
504 EXPECT_EQ(net::ERR_FAILED,
Chong Zhang83d0e4f2018-05-04 18:55:09505 factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhangd4c923642018-01-03 21:22:29506}
507
508// Make sure basic navigation works after crash.
509IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
510 NavigationURLLoaderBasic) {
Clark DuVall3290462e2019-02-16 02:19:50511 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36512 return;
Chong Zhangd4c923642018-01-03 21:22:29513 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
514 BrowserContext::GetDefaultStoragePartition(browser_context()));
515
516 EXPECT_TRUE(
517 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
518
519 // Crash the NetworkService process. Existing interfaces should receive error
520 // notifications at some point.
521 SimulateNetworkServiceCrash();
522 // Flush the interface to make sure the error notification was received.
523 partition->FlushNetworkInterfaceForTesting();
524 partition->url_loader_factory_getter()
525 ->FlushNetworkInterfaceOnIOThreadForTesting();
526
527 EXPECT_TRUE(
528 NavigateToURL(shell(), embedded_test_server()->GetURL("/title2.html")));
529}
530
Chong Zhang7306b0b2018-01-24 05:59:24531// Make sure basic XHR works after crash.
Chong Zhang5d9b34182018-01-30 16:20:57532IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BasicXHR) {
Clark DuVall3290462e2019-02-16 02:19:50533 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36534 return;
Chong Zhang7306b0b2018-01-24 05:59:24535 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
536 BrowserContext::GetDefaultStoragePartition(browser_context()));
537
Chong Zhang5d9b34182018-01-30 16:20:57538 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
Chong Zhang53047762018-05-02 21:24:08539 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title1.html"));
Chong Zhang7306b0b2018-01-24 05:59:24540 EXPECT_EQ(last_request_relative_url(), "/title1.html");
541
542 // Crash the NetworkService process. Existing interfaces should receive error
543 // notifications at some point.
544 SimulateNetworkServiceCrash();
545 // Flush the interface to make sure the error notification was received.
546 partition->FlushNetworkInterfaceForTesting();
547 // Flush the interface to make sure the frame host has received error
548 // notification and the new URLLoaderFactoryBundle has been received by the
549 // frame.
550 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
551
Chong Zhang53047762018-05-02 21:24:08552 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
Chong Zhang7306b0b2018-01-24 05:59:24553 EXPECT_EQ(last_request_relative_url(), "/title2.html");
554}
555
John Abd-El-Maleka7289152018-02-17 00:16:19556// Make sure the factory returned from
557// |StoragePartition::GetURLLoaderFactoryForBrowserProcess()| continues to work
558// after crashes.
559IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BrowserUIFactory) {
Clark DuVall3290462e2019-02-16 02:19:50560 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36561 return;
John Abd-El-Maleka7289152018-02-17 00:16:19562 auto* partition =
563 BrowserContext::GetDefaultStoragePartition(browser_context());
564 auto* factory = partition->GetURLLoaderFactoryForBrowserProcess().get();
565
566 EXPECT_EQ(net::OK, LoadBasicRequestOnUIThread(factory, GetTestURL()));
567
568 SimulateNetworkServiceCrash();
569 // Flush the interface to make sure the error notification was received.
570 partition->FlushNetworkInterfaceForTesting();
571
572 EXPECT_EQ(net::OK, LoadBasicRequestOnUIThread(factory, GetTestURL()));
573}
574
575// Make sure the factory returned from
576// |StoragePartition::GetURLLoaderFactoryForBrowserProcess()| doesn't crash if
577// it's called after the StoragePartition is deleted.
578IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
579 BrowserUIFactoryAfterStoragePartitionGone) {
Clark DuVall3290462e2019-02-16 02:19:50580 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36581 return;
John Abd-El-Maleka7289152018-02-17 00:16:19582 base::ScopedAllowBlockingForTesting allow_blocking;
583 std::unique_ptr<ShellBrowserContext> browser_context =
Eric Romanb56d0ef2019-07-02 17:36:06584 std::make_unique<ShellBrowserContext>(true);
John Abd-El-Maleka7289152018-02-17 00:16:19585 auto* partition =
586 BrowserContext::GetDefaultStoragePartition(browser_context.get());
Chong Zhangb7c8d1ce2018-03-13 19:14:11587 scoped_refptr<network::SharedURLLoaderFactory> factory(
John Abd-El-Maleka7289152018-02-17 00:16:19588 partition->GetURLLoaderFactoryForBrowserProcess());
589
590 EXPECT_EQ(net::OK, LoadBasicRequestOnUIThread(factory.get(), GetTestURL()));
591
592 browser_context.reset();
593
594 EXPECT_EQ(net::ERR_FAILED,
595 LoadBasicRequestOnUIThread(factory.get(), GetTestURL()));
596}
597
Chong Zhang83d0e4f2018-05-04 18:55:09598// Make sure the factory info returned from
599// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| can be
600// used after crashes.
Guido Urdaneta9cbbe382018-05-07 14:51:06601// Flaky on Windows. https://crbug.com/840127
602#if defined(OS_WIN)
603#define MAYBE_BrowserIOFactoryInfo DISABLED_BrowserIOFactoryInfo
604#else
605#define MAYBE_BrowserIOFactoryInfo BrowserIOFactoryInfo
606#endif
607IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
608 MAYBE_BrowserIOFactoryInfo) {
Clark DuVall3290462e2019-02-16 02:19:50609 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36610 return;
Chong Zhang4dd97ebf2018-03-07 04:48:48611 auto* partition =
612 BrowserContext::GetDefaultStoragePartition(browser_context());
Chong Zhang83d0e4f2018-05-04 18:55:09613 auto shared_url_loader_factory_info =
614 partition->GetURLLoaderFactoryForBrowserProcessIOThread();
Chong Zhang4dd97ebf2018-03-07 04:48:48615
616 SimulateNetworkServiceCrash();
617 // Flush the interface to make sure the error notification was received.
618 partition->FlushNetworkInterfaceForTesting();
619 static_cast<StoragePartitionImpl*>(partition)
620 ->url_loader_factory_getter()
621 ->FlushNetworkInterfaceOnIOThreadForTesting();
622
Chong Zhang83d0e4f2018-05-04 18:55:09623 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
624 std::move(shared_url_loader_factory_info));
625
626 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang4dd97ebf2018-03-07 04:48:48627}
628
Chong Zhang83d0e4f2018-05-04 18:55:09629// Make sure the factory constructed from
630// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| continues
631// to work after crashes.
632IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BrowserIOFactory) {
Clark DuVall3290462e2019-02-16 02:19:50633 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36634 return;
Chong Zhang4dd97ebf2018-03-07 04:48:48635 auto* partition =
Chong Zhang83d0e4f2018-05-04 18:55:09636 BrowserContext::GetDefaultStoragePartition(browser_context());
637 auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
638 partition->GetURLLoaderFactoryForBrowserProcessIOThread());
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
Chong Zhang83d0e4f2018-05-04 18:55:09642 SimulateNetworkServiceCrash();
643 // Flush the interface to make sure the error notification was received.
644 partition->FlushNetworkInterfaceForTesting();
645 static_cast<StoragePartitionImpl*>(partition)
646 ->url_loader_factory_getter()
647 ->FlushNetworkInterfaceOnIOThreadForTesting();
Chong Zhang4dd97ebf2018-03-07 04:48:48648
Chong Zhang83d0e4f2018-05-04 18:55:09649 EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
Chong Zhang4dd97ebf2018-03-07 04:48:48650}
651
Chong Zhang4513fab2018-02-28 18:50:18652// Make sure the window from |window.open()| can load XHR after crash.
653IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, WindowOpenXHR) {
Clark DuVall3290462e2019-02-16 02:19:50654 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36655 return;
Chong Zhang4513fab2018-02-28 18:50:18656 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
657 BrowserContext::GetDefaultStoragePartition(browser_context()));
658
659 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
660 EXPECT_TRUE(CheckCanLoadHttpInWindowOpen("/title1.html"));
661 EXPECT_EQ(last_request_relative_url(), "/title1.html");
662
663 // Crash the NetworkService process. Existing interfaces should receive error
664 // notifications at some point.
665 SimulateNetworkServiceCrash();
666 // Flush the interface to make sure the error notification was received.
667 partition->FlushNetworkInterfaceForTesting();
668 // Flush the interface to make sure the frame host has received error
669 // notification and the new URLLoaderFactoryBundle has been received by the
670 // frame.
671 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
672
673 EXPECT_TRUE(CheckCanLoadHttpInWindowOpen("/title2.html"));
674 EXPECT_EQ(last_request_relative_url(), "/title2.html");
675}
676
Hiroki Nakagawa3b90e642019-09-10 01:59:58677// Run tests with PlzDedicatedWorker.
678// TODO(https://crbug.com/906991): Merge this test fixture into
679// NetworkServiceRestartBrowserTest once PlzDedicatedWorker is enabled by
680// default.
681class NetworkServiceRestartForWorkerBrowserTest
682 : public NetworkServiceRestartBrowserTest,
683 public ::testing::WithParamInterface<bool> {
684 public:
685 NetworkServiceRestartForWorkerBrowserTest() {
686 if (GetParam()) {
687 scoped_feature_list_.InitAndEnableFeature(
688 blink::features::kPlzDedicatedWorker);
689 } else {
690 scoped_feature_list_.InitAndDisableFeature(
691 blink::features::kPlzDedicatedWorker);
692 }
693 }
694
695 private:
696 base::test::ScopedFeatureList scoped_feature_list_;
697};
698
699INSTANTIATE_TEST_SUITE_P(,
700 NetworkServiceRestartForWorkerBrowserTest,
701 ::testing::Values(false, true));
702
Chong Zhang4513fab2018-02-28 18:50:18703// Make sure worker fetch works after crash.
Hiroki Nakagawa3b90e642019-09-10 01:59:58704IN_PROC_BROWSER_TEST_P(NetworkServiceRestartForWorkerBrowserTest, WorkerFetch) {
Clark DuVall3290462e2019-02-16 02:19:50705 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36706 return;
Chong Zhang4513fab2018-02-28 18:50:18707 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
708 BrowserContext::GetDefaultStoragePartition(browser_context()));
709
710 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
711 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title1.html"));
712 EXPECT_EQ(last_request_relative_url(), "/title1.html");
713
714 // Crash the NetworkService process. Existing interfaces should receive error
715 // notifications at some point.
716 SimulateNetworkServiceCrash();
717 // Flush the interface to make sure the error notification was received.
718 partition->FlushNetworkInterfaceForTesting();
719 // Flush the interface to make sure the frame host has received error
720 // notification and the new URLLoaderFactoryBundle has been received by the
721 // frame.
722 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
723
724 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title2.html"));
725 EXPECT_EQ(last_request_relative_url(), "/title2.html");
726}
727
728// Make sure multiple workers are tracked correctly and work after crash.
Hiroki Nakagawa3b90e642019-09-10 01:59:58729IN_PROC_BROWSER_TEST_P(NetworkServiceRestartForWorkerBrowserTest,
730 MultipleWorkerFetch) {
Clark DuVall3290462e2019-02-16 02:19:50731 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36732 return;
Chong Zhang4513fab2018-02-28 18:50:18733 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
734 BrowserContext::GetDefaultStoragePartition(browser_context()));
735
736 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
737 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title1.html"));
738 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title1.html"));
739 EXPECT_EQ(last_request_relative_url(), "/title1.html");
740
741 // Crash the NetworkService process. Existing interfaces should receive error
742 // notifications at some point.
743 SimulateNetworkServiceCrash();
744 // Flush the interface to make sure the error notification was received.
745 partition->FlushNetworkInterfaceForTesting();
746 // Flush the interface to make sure the frame host has received error
747 // notification and the new URLLoaderFactoryBundle has been received by the
748 // frame.
749 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
750
751 // Both workers should work after crash.
752 EXPECT_TRUE(CheckCanWorkerFetch("worker1", "/title2.html"));
753 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title2.html"));
754 EXPECT_EQ(last_request_relative_url(), "/title2.html");
755
756 // Terminate "worker1". "worker2" shouldn't be affected.
757 EXPECT_TRUE(TerminateWorker("worker1"));
758 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title1.html"));
759 EXPECT_EQ(last_request_relative_url(), "/title1.html");
760
761 // Crash the NetworkService process again. "worker2" should still work.
762 SimulateNetworkServiceCrash();
763 partition->FlushNetworkInterfaceForTesting();
764 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
765
766 EXPECT_TRUE(CheckCanWorkerFetch("worker2", "/title2.html"));
767 EXPECT_EQ(last_request_relative_url(), "/title2.html");
768}
769
Makoto Shimazu775101a52018-09-26 04:46:52770// Make sure fetch from a page controlled by a service worker which doesn't have
771// a fetch handler works after crash.
Makoto Shimazu2540a642018-11-15 06:24:44772IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
773 FetchFromServiceWorkerControlledPage_NoFetchHandler) {
Clark DuVall3290462e2019-02-16 02:19:50774 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36775 return;
Makoto Shimazu775101a52018-09-26 04:46:52776 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
777 BrowserContext::GetDefaultStoragePartition(browser_context()));
778 ServiceWorkerStatusObserver observer;
779 ServiceWorkerContextWrapper* service_worker_context =
780 partition->GetServiceWorkerContext();
781 service_worker_context->AddObserver(&observer);
782
783 // Register a service worker which controls /service_worker/.
784 EXPECT_TRUE(NavigateToURL(shell(),
785 embedded_test_server()->GetURL(
786 "/service_worker/create_service_worker.html")));
787 EXPECT_EQ("DONE", EvalJs(shell(), "register('empty.js')"));
788
789 // Navigate to a controlled page.
790 EXPECT_TRUE(NavigateToURL(
791 shell(),
792 embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
793
794 // Fetch from the controlled page.
795 const std::string script = "fetch_from_page('/echo');";
796 EXPECT_EQ("Echo", EvalJs(shell(), script));
797
798 // Crash the NetworkService process. Existing interfaces should receive error
799 // notifications at some point.
800 SimulateNetworkServiceCrash();
801 // Flush the interface to make sure the error notification was received.
802 partition->FlushNetworkInterfaceForTesting();
803
804 // Service worker should be stopped when network service crashes.
805 observer.WaitForState(EmbeddedWorkerStatus::STOPPED);
806
807 // Fetch from the controlled page again.
808 EXPECT_EQ("Echo", EvalJs(shell(), script));
809
810 service_worker_context->RemoveObserver(&observer);
811}
812
813// Make sure fetch from a page controlled by a service worker which has a fetch
814// handler but falls back to the network works after crash.
815IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
Makoto Shimazu2540a642018-11-15 06:24:44816 FetchFromServiceWorkerControlledPage_PassThrough) {
Clark DuVall3290462e2019-02-16 02:19:50817 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36818 return;
Makoto Shimazu775101a52018-09-26 04:46:52819 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
820 BrowserContext::GetDefaultStoragePartition(browser_context()));
821 ServiceWorkerStatusObserver observer;
822 ServiceWorkerContextWrapper* service_worker_context =
823 partition->GetServiceWorkerContext();
824 service_worker_context->AddObserver(&observer);
825
826 // Register a service worker which controls /service_worker/.
827 EXPECT_TRUE(NavigateToURL(shell(),
828 embedded_test_server()->GetURL(
829 "/service_worker/create_service_worker.html")));
830 EXPECT_EQ("DONE", EvalJs(shell(), "register('fetch_event_pass_through.js')"));
831
832 // Navigate to a controlled page.
833 EXPECT_TRUE(NavigateToURL(
834 shell(),
835 embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
836
837 // Fetch from the controlled page.
838 const std::string script = "fetch_from_page('/echo');";
839 EXPECT_EQ("Echo", EvalJs(shell(), script));
840
841 // Crash the NetworkService process. Existing interfaces should receive error
842 // notifications at some point.
843 SimulateNetworkServiceCrash();
844 // Flush the interface to make sure the error notification was received.
845 partition->FlushNetworkInterfaceForTesting();
846
847 // Service worker should be stopped when network service crashes.
848 observer.WaitForState(EmbeddedWorkerStatus::STOPPED);
849
850 // Fetch from the controlled page again.
851 EXPECT_EQ("Echo", EvalJs(shell(), script));
852
853 service_worker_context->RemoveObserver(&observer);
854}
855
856// Make sure fetch from a page controlled by a service worker which has a fetch
857// handler and responds with fetch() works after crash.
Makoto Shimazu2540a642018-11-15 06:24:44858IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
859 FetchFromServiceWorkerControlledPage_RespondWithFetch) {
Clark DuVall3290462e2019-02-16 02:19:50860 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36861 return;
Makoto Shimazu775101a52018-09-26 04:46:52862 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
863 BrowserContext::GetDefaultStoragePartition(browser_context()));
864 ServiceWorkerStatusObserver observer;
865 ServiceWorkerContextWrapper* service_worker_context =
866 partition->GetServiceWorkerContext();
867 service_worker_context->AddObserver(&observer);
868
869 // Register a service worker which controls /service_worker/.
870 EXPECT_TRUE(NavigateToURL(shell(),
871 embedded_test_server()->GetURL(
872 "/service_worker/create_service_worker.html")));
873 EXPECT_EQ("DONE",
874 EvalJs(shell(), "register('fetch_event_respond_with_fetch.js')"));
875
876 // Navigate to a controlled page.
877 EXPECT_TRUE(NavigateToURL(
878 shell(),
879 embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
880
881 // Fetch from the controlled page.
882 const std::string script = "fetch_from_page('/echo');";
883 EXPECT_EQ("Echo", EvalJs(shell(), script));
884
885 // Crash the NetworkService process. Existing interfaces should receive error
886 // notifications at some point.
887 SimulateNetworkServiceCrash();
888 // Flush the interface to make sure the error notification was received.
889 partition->FlushNetworkInterfaceForTesting();
890
891 // Service worker should be stopped when network service crashes.
892 observer.WaitForState(EmbeddedWorkerStatus::STOPPED);
893
894 // Fetch from the controlled page again.
895 EXPECT_EQ("Echo", EvalJs(shell(), script));
896
897 service_worker_context->RemoveObserver(&observer);
898}
899
Makoto Shimazu2075b0d2018-09-21 09:04:22900// Make sure fetch from service worker context works after crash.
Makoto Shimazu6a96cb62018-09-21 11:39:13901IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, ServiceWorkerFetch) {
Clark DuVall3290462e2019-02-16 02:19:50902 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36903 return;
Makoto Shimazu2075b0d2018-09-21 09:04:22904 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
905 BrowserContext::GetDefaultStoragePartition(browser_context()));
906 ServiceWorkerStatusObserver observer;
907 ServiceWorkerContextWrapper* service_worker_context =
908 partition->GetServiceWorkerContext();
909 service_worker_context->AddObserver(&observer);
910
911 const GURL page_url = embedded_test_server()->GetURL(
912 "/service_worker/fetch_from_service_worker.html");
913 const GURL fetch_url = embedded_test_server()->GetURL("/echo");
914
915 // Navigate to the page and register a service worker.
916 EXPECT_TRUE(NavigateToURL(shell(), page_url));
917 EXPECT_EQ("ready", EvalJs(shell(), "setup();"));
918
919 // Fetch from the service worker.
920 const std::string script =
921 "fetch_from_service_worker('" + fetch_url.spec() + "');";
922 EXPECT_EQ("Echo", EvalJs(shell(), script));
923
924 // Crash the NetworkService process. Existing interfaces should receive error
925 // notifications at some point.
926 SimulateNetworkServiceCrash();
927 // Flush the interface to make sure the error notification was received.
928 partition->FlushNetworkInterfaceForTesting();
929
930 // Service worker should be stopped when network service crashes.
931 observer.WaitForState(EmbeddedWorkerStatus::STOPPED);
932
933 // Fetch from the service worker again.
934 EXPECT_EQ("Echo", EvalJs(shell(), script));
935
936 service_worker_context->RemoveObserver(&observer);
937}
938
Clark DuVallf742bcbd2018-11-07 17:16:20939// TODO(crbug.com/154571): Shared workers are not available on Android.
940#if defined(OS_ANDROID)
941#define MAYBE_SharedWorker DISABLED_SharedWorker
942#else
943#define MAYBE_SharedWorker SharedWorker
944#endif
Matt Falkenhagene6721962018-10-05 10:17:05945// Make sure shared workers terminate after crash.
Clark DuVallf742bcbd2018-11-07 17:16:20946IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, MAYBE_SharedWorker) {
Clark DuVall3290462e2019-02-16 02:19:50947 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36948 return;
Makoto Shimazu2075b0d2018-09-21 09:04:22949 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
950 BrowserContext::GetDefaultStoragePartition(browser_context()));
951
Patrick Monette3f51a042019-08-30 17:57:04952 InjectTestSharedWorkerService(partition);
953
Makoto Shimazu2075b0d2018-09-21 09:04:22954 const GURL page_url =
955 embedded_test_server()->GetURL("/workers/fetch_from_shared_worker.html");
956 const GURL fetch_url = embedded_test_server()->GetURL("/echo");
957
958 // Navigate to the page and prepare a shared worker.
959 EXPECT_TRUE(NavigateToURL(shell(), page_url));
960
Matt Falkenhagene6721962018-10-05 10:17:05961 // Fetch from the shared worker to ensure it has started.
Finditc0f7c6202018-10-05 07:14:23962 const std::string script =
963 "fetch_from_shared_worker('" + fetch_url.spec() + "');";
964 EXPECT_EQ("Echo", EvalJs(shell(), script));
Makoto Shimazu2075b0d2018-09-21 09:04:22965
Matt Falkenhagene6721962018-10-05 10:17:05966 // There should be one worker host. We will later wait for it to terminate.
Patrick Monette3f51a042019-08-30 17:57:04967 TestSharedWorkerServiceImpl* service =
968 static_cast<TestSharedWorkerServiceImpl*>(
969 partition->GetSharedWorkerService());
Matt Falkenhagene6721962018-10-05 10:17:05970 EXPECT_EQ(1u, service->worker_hosts_.size());
971 base::RunLoop loop;
Patrick Monette3f51a042019-08-30 17:57:04972 service->SetWorkerTerminationCallback(loop.QuitClosure());
Makoto Shimazu2075b0d2018-09-21 09:04:22973
Matt Falkenhagene6721962018-10-05 10:17:05974 // Crash the NetworkService process.
975 SimulateNetworkServiceCrash();
976
977 // Wait for the worker to detect the crash and self-terminate.
978 loop.Run();
979 EXPECT_TRUE(service->worker_hosts_.empty());
Makoto Shimazu2075b0d2018-09-21 09:04:22980}
981
Chong Zhang53047762018-05-02 21:24:08982// Make sure the entry in |NetworkService::GetTotalNetworkUsages()| was cleared
983// after process closed.
984IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
985 GetNetworkUsagesClosed) {
Clark DuVall3290462e2019-02-16 02:19:50986 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:36987 return;
Chong Zhang53047762018-05-02 21:24:08988 EXPECT_TRUE(NavigateToURL(shell(), GetTestURL()));
989 Shell* shell2 = CreateBrowser();
990 EXPECT_TRUE(NavigateToURL(shell2, GetTestURL()));
991
992 int process_id1 =
993 shell()->web_contents()->GetMainFrame()->GetProcess()->GetID();
994 int process_id2 =
995 shell2->web_contents()->GetMainFrame()->GetProcess()->GetID();
996
997 // Load resource on the renderer to make sure the traffic was recorded.
998 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
999 EXPECT_TRUE(CheckCanLoadHttp(shell2, "/title3.html"));
1000
1001 // Both processes should have traffic recorded.
1002 auto network_usages = GetTotalNetworkUsages();
1003 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
1004 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id2));
1005
1006 // Closing |shell2| should cause the entry to be cleared.
1007 shell2->Close();
1008 shell2 = nullptr;
1009
1010 // Wait until the Network Service has noticed the change. We don't have a
1011 // better way to force a flush on the Network Service side.
1012 WaitForCondition(base::BindRepeating(
1013 [](int process_id) {
1014 auto usages = GetTotalNetworkUsages();
1015 return !CheckContainsProcessID(usages, process_id);
1016 },
1017 process_id2));
1018
1019 network_usages = GetTotalNetworkUsages();
1020 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
1021 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id2));
1022}
1023
Christopher Thompson2a4c69e92019-08-21 16:29:111024// Make sure that kSSLKeyLogFileHistogram is correctly recorded when the
1025// network service instance is started and the SSLKEYLOGFILE env var is set or
1026// the "--ssl-key-log-file" arg is set.
1027IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, SSLKeyLogFileMetrics) {
1028 if (IsInProcessNetworkService())
1029 return;
1030 // Actions on temporary files are blocking.
1031 base::ScopedAllowBlockingForTesting scoped_allow_blocking;
1032 base::FilePath log_file_path;
1033 base::CreateTemporaryFile(&log_file_path);
1034
1035#if defined(OS_WIN)
1036 // On Windows, FilePath::value() returns base::string16, so convert.
1037 std::string log_file_path_str = base::UTF16ToUTF8(log_file_path.value());
1038#else
1039 std::string log_file_path_str = log_file_path.value();
1040#endif
1041
1042 // Test that env var causes the histogram to be recorded.
1043 {
1044 base::test::ScopedEnvironmentVariableOverride scoped_env("SSLKEYLOGFILE",
1045 log_file_path_str);
1046 base::HistogramTester histograms;
1047 // Restart network service to cause SSLKeyLogger to be re-initialized.
1048 SimulateNetworkServiceCrash();
1049 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1050 SSLKeyLogFileAction::kLogFileEnabled, 1);
1051 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1052 SSLKeyLogFileAction::kEnvVarFound, 1);
1053 }
1054
1055 // Test that the command-line switch causes the histogram to be recorded.
1056 {
1057 base::test::ScopedCommandLine scoped_command_line;
1058 scoped_command_line.GetProcessCommandLine()->AppendSwitchPath(
1059 "ssl-key-log-file", log_file_path);
1060 base::HistogramTester histograms;
1061 // Restart network service to cause SSLKeyLogger to be re-initialized.
1062 SimulateNetworkServiceCrash();
1063 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1064 SSLKeyLogFileAction::kLogFileEnabled, 1);
1065 histograms.ExpectBucketCount(kSSLKeyLogFileHistogram,
1066 SSLKeyLogFileAction::kSwitchFound, 1);
1067 }
1068}
1069
Chong Zhang53047762018-05-02 21:24:081070// Make sure |NetworkService::GetTotalNetworkUsages()| continues to work after
1071// crash. See 'network_usage_accumulator_unittest' for quantified tests.
1072IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
1073 GetNetworkUsagesCrashed) {
Clark DuVall3290462e2019-02-16 02:19:501074 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361075 return;
Chong Zhang53047762018-05-02 21:24:081076 EXPECT_TRUE(NavigateToURL(shell(), GetTestURL()));
1077 Shell* shell2 = CreateBrowser();
1078 EXPECT_TRUE(NavigateToURL(shell2, GetTestURL()));
1079
1080 int process_id1 =
1081 shell()->web_contents()->GetMainFrame()->GetProcess()->GetID();
1082 int process_id2 =
1083 shell2->web_contents()->GetMainFrame()->GetProcess()->GetID();
1084
1085 // Load resource on the renderer to make sure the traffic was recorded.
1086 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
1087 EXPECT_TRUE(CheckCanLoadHttp(shell2, "/title3.html"));
1088
1089 // Both processes should have traffic recorded.
1090 auto network_usages = GetTotalNetworkUsages();
1091 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
1092 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id2));
1093
1094 // Crashing Network Service should cause all entries to be cleared.
1095 SimulateNetworkServiceCrash();
1096 network_usages = GetTotalNetworkUsages();
1097 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id1));
1098 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id2));
1099
1100 // Should still be able to recored new traffic after crash.
1101 EXPECT_TRUE(CheckCanLoadHttp(shell(), "/title2.html"));
1102 network_usages = GetTotalNetworkUsages();
1103 EXPECT_TRUE(CheckContainsProcessID(network_usages, process_id1));
1104 EXPECT_FALSE(CheckContainsProcessID(network_usages, process_id2));
1105}
1106
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141107// Make sure cookie access doesn't hang or fail after a network process crash.
1108IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, Cookies) {
Clark DuVall3290462e2019-02-16 02:19:501109 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361110 return;
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141111 auto* web_contents = shell()->web_contents();
Lukasz Anforowiczce4487b72018-10-23 18:05:531112 ASSERT_TRUE(
1113 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141114 EXPECT_TRUE(ExecuteScript(web_contents, "document.cookie = 'foo=bar';"));
1115
1116 std::string cookie;
1117 EXPECT_TRUE(ExecuteScriptAndExtractString(
1118 web_contents, "window.domAutomationController.send(document.cookie);",
1119 &cookie));
1120 EXPECT_EQ("foo=bar", cookie);
1121
1122 SimulateNetworkServiceCrash();
1123
John Abd-El-Malek1f61a5fd2018-09-21 01:13:141124 // content_shell uses in-memory cookie database, so the value saved earlier
1125 // won't persist across crashes. What matters is that new access works.
1126 EXPECT_TRUE(ExecuteScript(web_contents, "document.cookie = 'foo=bar';"));
1127
1128 // This will hang without the fix.
1129 EXPECT_TRUE(ExecuteScriptAndExtractString(
1130 web_contents, "window.domAutomationController.send(document.cookie);",
1131 &cookie));
1132 EXPECT_EQ("foo=bar", cookie);
1133}
1134
Lukasz Anforowiczce4487b72018-10-23 18:05:531135#if BUILDFLAG(ENABLE_PLUGINS)
1136// Make sure that "trusted" plugins continue to be able to issue cross-origin
1137// requests after a network process crash.
1138IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, Plugin) {
Clark DuVall3290462e2019-02-16 02:19:501139 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361140 return;
Lukasz Anforowiczce4487b72018-10-23 18:05:531141 auto* web_contents = shell()->web_contents();
1142 ASSERT_TRUE(NavigateToURL(web_contents,
1143 embedded_test_server()->GetURL("/title1.html")));
1144
1145 // Load the test plugin (see ppapi::RegisterFlashTestPlugin and
1146 // ppapi/tests/power_saver_test_plugin.cc).
1147 const char kLoadingScript[] = R"(
1148 var obj = document.createElement('object');
1149 obj.id = 'plugin';
1150 obj.data = 'test.swf';
1151 obj.type = 'application/x-shockwave-flash';
1152 obj.width = 400;
1153 obj.height = 400;
1154
1155 document.body.appendChild(obj);
1156 )";
1157 ASSERT_TRUE(ExecJs(web_contents, kLoadingScript));
1158
1159 // Ask the plugin to perform a cross-origin, CORB-eligible (i.e.
1160 // application/json + nosniff) URL request. Plugins with universal access
1161 // should not be subject to CORS/CORB and so the request should go through.
1162 // See also https://crbug.com/874515 and https://crbug.com/846339.
1163 GURL cross_origin_url = embedded_test_server()->GetURL(
1164 "cross.origin.com", "/site_isolation/nosniff.json");
1165 const char kFetchScriptTemplate[] = R"(
1166 new Promise(function (resolve, reject) {
1167 var obj = document.getElementById('plugin');
1168 function callback(event) {
1169 // Ignore plugin messages unrelated to requestUrl.
1170 if (!event.data.startsWith('requestUrl: '))
1171 return;
1172
1173 obj.removeEventListener('message', callback);
1174 resolve('msg-from-plugin: ' + event.data);
1175 };
1176 obj.addEventListener('message', callback);
1177 obj.postMessage('requestUrl: ' + $1);
1178 });
1179 )";
1180 std::string fetch_script = JsReplace(kFetchScriptTemplate, cross_origin_url);
1181 ASSERT_EQ(
1182 "msg-from-plugin: requestUrl: RESPONSE BODY: "
1183 "runMe({ \"name\" : \"chromium\" });\n",
1184 EvalJs(web_contents, fetch_script));
1185
1186 // Crash the Network Service process and wait until host frame's
1187 // URLLoaderFactory has been refreshed.
1188 SimulateNetworkServiceCrash();
1189 main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
1190
1191 // Try the fetch again - it should still work (i.e. the mechanism for relaxing
1192 // CORB for universal-access-plugins should be resilient to network process
1193 // crashes). See also https://crbug.com/891904.
1194 ASSERT_EQ(
1195 "msg-from-plugin: requestUrl: RESPONSE BODY: "
1196 "runMe({ \"name\" : \"chromium\" });\n",
1197 EvalJs(web_contents, fetch_script));
1198}
1199#endif
1200
Clark DuVallf742bcbd2018-11-07 17:16:201201// TODO(crbug.com/901026): Fix deadlock on process startup on Android.
1202#if defined(OS_ANDROID)
1203#define MAYBE_SyncCallDuringRestart DISABLED_SyncCallDuringRestart
1204#else
1205#define MAYBE_SyncCallDuringRestart SyncCallDuringRestart
1206#endif
1207IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
1208 MAYBE_SyncCallDuringRestart) {
Clark DuVall3290462e2019-02-16 02:19:501209 if (IsInProcessNetworkService())
Clark DuVallc2227ae2018-11-28 22:26:361210 return;
Clark DuVallf742bcbd2018-11-07 17:16:201211 network::mojom::NetworkServiceTestPtr network_service_test;
1212 base::RunLoop run_loop;
Ken Rockotfd03e682019-06-20 21:13:541213 GetSystemConnector()->BindInterface(mojom::kNetworkServiceName,
1214 &network_service_test);
Clark DuVallf742bcbd2018-11-07 17:16:201215
1216 // Crash the network service, but do not wait for full startup.
1217 network_service_test.set_connection_error_handler(run_loop.QuitClosure());
1218 network_service_test->SimulateCrash();
1219 run_loop.Run();
1220
Ken Rockotfd03e682019-06-20 21:13:541221 GetSystemConnector()->BindInterface(mojom::kNetworkServiceName,
1222 &network_service_test);
Clark DuVallf742bcbd2018-11-07 17:16:201223
1224 // Sync call should be fine, even though network process is still starting up.
1225 mojo::ScopedAllowSyncCallForTesting allow_sync_call;
1226 network_service_test->AddRules({});
1227}
1228
Chong Zhangc583e672017-11-08 16:34:081229} // namespace content