Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Side by Side Diff: content/browser/site_per_process_browsertest.cc

Issue 185053007: Split cross-process transfer tests out of SitePerProcessBrowserTest. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Header cleanup Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/browser/cross_site_transfer_browsertest.cc ('k') | content/content_tests.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/command_line.h" 5 #include "base/command_line.h"
6 #include "base/strings/stringprintf.h" 6 #include "base/strings/stringprintf.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "content/browser/frame_host/frame_tree.h" 7 #include "content/browser/frame_host/frame_tree.h"
9 #include "content/browser/loader/resource_dispatcher_host_impl.h"
10 #include "content/browser/renderer_host/render_view_host_impl.h" 8 #include "content/browser/renderer_host/render_view_host_impl.h"
11 #include "content/browser/web_contents/web_contents_impl.h" 9 #include "content/browser/web_contents/web_contents_impl.h"
12 #include "content/public/browser/navigation_entry.h"
13 #include "content/public/browser/notification_observer.h" 10 #include "content/public/browser/notification_observer.h"
14 #include "content/public/browser/notification_service.h" 11 #include "content/public/browser/notification_service.h"
15 #include "content/public/browser/notification_types.h" 12 #include "content/public/browser/notification_types.h"
16 #include "content/public/browser/resource_dispatcher_host_delegate.h"
17 #include "content/public/browser/resource_throttle.h"
18 #include "content/public/browser/web_contents_observer.h" 13 #include "content/public/browser/web_contents_observer.h"
19 #include "content/public/common/content_switches.h" 14 #include "content/public/common/content_switches.h"
20 #include "content/public/common/url_constants.h"
21 #include "content/public/test/browser_test_utils.h" 15 #include "content/public/test/browser_test_utils.h"
22 #include "content/public/test/test_navigation_observer.h"
23 #include "content/public/test/test_utils.h" 16 #include "content/public/test/test_utils.h"
24 #include "content/shell/browser/shell.h" 17 #include "content/shell/browser/shell.h"
25 #include "content/shell/browser/shell_content_browser_client.h"
26 #include "content/shell/browser/shell_resource_dispatcher_host_delegate.h"
27 #include "content/test/content_browser_test.h" 18 #include "content/test/content_browser_test.h"
28 #include "content/test/content_browser_test_utils.h" 19 #include "content/test/content_browser_test_utils.h"
29 #include "net/base/escape.h"
30 #include "net/dns/mock_host_resolver.h" 20 #include "net/dns/mock_host_resolver.h"
31 #include "net/url_request/url_request.h" 21 #include "url/gurl.h"
32 #include "net/url_request/url_request_status.h"
33 22
34 namespace content { 23 namespace content {
35 24
36 class SitePerProcessWebContentsObserver: public WebContentsObserver { 25 class SitePerProcessWebContentsObserver: public WebContentsObserver {
37 public: 26 public:
38 explicit SitePerProcessWebContentsObserver(WebContents* web_contents) 27 explicit SitePerProcessWebContentsObserver(WebContents* web_contents)
39 : WebContentsObserver(web_contents), 28 : WebContentsObserver(web_contents),
40 navigation_succeeded_(false) {} 29 navigation_succeeded_(false) {}
41 virtual ~SitePerProcessWebContentsObserver() {} 30 virtual ~SitePerProcessWebContentsObserver() {}
42 31
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 details_ = details; 147 details_ = details;
159 seen_twice_ = seen_; 148 seen_twice_ = seen_;
160 seen_ = true; 149 seen_ = true;
161 if (!running_) 150 if (!running_)
162 return; 151 return;
163 152
164 message_loop_runner_->Quit(); 153 message_loop_runner_->Quit();
165 running_ = false; 154 running_ = false;
166 } 155 }
167 156
168 // Tracks a single request for a specified URL, and allows waiting until the
169 // request is destroyed, and then inspecting whether it completed successfully.
170 class TrackingResourceDispatcherHostDelegate
171 : public ShellResourceDispatcherHostDelegate {
172 public:
173 TrackingResourceDispatcherHostDelegate() : throttle_created_(false) {
174 }
175
176 virtual void RequestBeginning(
177 net::URLRequest* request,
178 ResourceContext* resource_context,
179 appcache::AppCacheService* appcache_service,
180 ResourceType::Type resource_type,
181 int child_id,
182 int route_id,
183 ScopedVector<ResourceThrottle>* throttles) OVERRIDE {
184 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
185 ShellResourceDispatcherHostDelegate::RequestBeginning(
186 request, resource_context, appcache_service, resource_type, child_id,
187 route_id, throttles);
188 // Expect only a single request for the tracked url.
189 ASSERT_FALSE(throttle_created_);
190 // If this is a request for the tracked URL, add a throttle to track it.
191 if (request->url() == tracked_url_)
192 throttles->push_back(new TrackingThrottle(request, this));
193 }
194
195 // Starts tracking a URL. The request for previously tracked URL, if any,
196 // must have been made and deleted before calling this function.
197 void SetTrackedURL(const GURL& tracked_url) {
198 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
199 // Should not currently be tracking any URL.
200 ASSERT_FALSE(run_loop_);
201
202 // Create a RunLoop that will be stopped once the request for the tracked
203 // URL has been destroyed, to allow tracking the URL while also waiting for
204 // other events.
205 run_loop_.reset(new base::RunLoop());
206
207 BrowserThread::PostTask(
208 BrowserThread::IO, FROM_HERE,
209 base::Bind(
210 &TrackingResourceDispatcherHostDelegate::SetTrackedURLOnIOThread,
211 base::Unretained(this),
212 tracked_url));
213 }
214
215 // Waits until the tracked URL has been requests, and the request for it has
216 // been destroyed.
217 bool WaitForTrackedURLAndGetCompleted() {
218 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
219 run_loop_->Run();
220 run_loop_.reset();
221 return tracked_request_completed_;
222 }
223
224 private:
225 // ResourceThrottle attached to request for the tracked URL. On destruction,
226 // passes the final URLRequestStatus back to the delegate.
227 class TrackingThrottle : public ResourceThrottle {
228 public:
229 TrackingThrottle(net::URLRequest* request,
230 TrackingResourceDispatcherHostDelegate* tracker)
231 : request_(request), tracker_(tracker) {
232 }
233
234 virtual ~TrackingThrottle() {
235 // If the request is deleted without being cancelled, its status will
236 // indicate it succeeded, so have to check if the request is still pending
237 // as well.
238 tracker_->OnTrackedRequestDestroyed(
239 !request_->is_pending() && request_->status().is_success());
240 }
241
242 // ResourceThrottle implementation:
243 virtual const char* GetNameForLogging() const OVERRIDE {
244 return "TrackingThrottle";
245 }
246
247 private:
248 net::URLRequest* request_;
249 TrackingResourceDispatcherHostDelegate* tracker_;
250
251 DISALLOW_COPY_AND_ASSIGN(TrackingThrottle);
252 };
253
254 void SetTrackedURLOnIOThread(const GURL& tracked_url) {
255 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
256 throttle_created_ = false;
257 tracked_url_ = tracked_url;
258 }
259
260 void OnTrackedRequestDestroyed(bool completed) {
261 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
262 tracked_request_completed_ = completed;
263 tracked_url_ = GURL();
264
265 BrowserThread::PostTask(
266 BrowserThread::UI, FROM_HERE, run_loop_->QuitClosure());
267 }
268
269 // These live on the IO thread.
270 GURL tracked_url_;
271 bool throttle_created_;
272
273 // This is created and destroyed on the UI thread, but stopped on the IO
274 // thread.
275 scoped_ptr<base::RunLoop> run_loop_;
276
277 // Set on the IO thread while |run_loop_| is non-NULL, read on the UI thread
278 // after deleting run_loop_.
279 bool tracked_request_completed_;
280
281 DISALLOW_COPY_AND_ASSIGN(TrackingResourceDispatcherHostDelegate);
282 };
283
284 // WebContentsDelegate that fails to open a URL when there's a request that
285 // needs to be transferred between renderers.
286 class NoTransferRequestDelegate : public WebContentsDelegate {
287 public:
288 NoTransferRequestDelegate() {}
289
290 virtual WebContents* OpenURLFromTab(WebContents* source,
291 const OpenURLParams& params) OVERRIDE {
292 bool is_transfer =
293 (params.transferred_global_request_id != GlobalRequestID());
294 if (is_transfer)
295 return NULL;
296 NavigationController::LoadURLParams load_url_params(params.url);
297 load_url_params.referrer = params.referrer;
298 load_url_params.frame_tree_node_id = params.frame_tree_node_id;
299 load_url_params.transition_type = params.transition;
300 load_url_params.extra_headers = params.extra_headers;
301 load_url_params.should_replace_current_entry =
302 params.should_replace_current_entry;
303 load_url_params.is_renderer_initiated = true;
304 source->GetController().LoadURLWithParams(load_url_params);
305 return source;
306 }
307
308 private:
309 DISALLOW_COPY_AND_ASSIGN(NoTransferRequestDelegate);
310 };
311
312 class SitePerProcessBrowserTest : public ContentBrowserTest { 157 class SitePerProcessBrowserTest : public ContentBrowserTest {
313 public: 158 public:
314 SitePerProcessBrowserTest() : old_delegate_(NULL) { 159 SitePerProcessBrowserTest() {}
315 }
316
317 // ContentBrowserTest implementation:
318 virtual void SetUpOnMainThread() OVERRIDE {
319 BrowserThread::PostTask(
320 BrowserThread::IO, FROM_HERE,
321 base::Bind(
322 &SitePerProcessBrowserTest::InjectResourceDisptcherHostDelegate,
323 base::Unretained(this)));
324 }
325
326 virtual void TearDownOnMainThread() OVERRIDE {
327 BrowserThread::PostTask(
328 BrowserThread::IO, FROM_HERE,
329 base::Bind(
330 &SitePerProcessBrowserTest::RestoreResourceDisptcherHostDelegate,
331 base::Unretained(this)));
332 }
333 160
334 protected: 161 protected:
335 // Start at a data URL so each extra navigation creates a navigation entry. 162 // Start at a data URL so each extra navigation creates a navigation entry.
336 // (The first navigation will silently be classified as AUTO_SUBFRAME.) 163 // (The first navigation will silently be classified as AUTO_SUBFRAME.)
337 // TODO(creis): This won't be necessary when we can wait for LOAD_STOP. 164 // TODO(creis): This won't be necessary when we can wait for LOAD_STOP.
338 void StartFrameAtDataURL() { 165 void StartFrameAtDataURL() {
339 std::string data_url_script = 166 std::string data_url_script =
340 "var iframes = document.getElementById('test');iframes.src=" 167 "var iframes = document.getElementById('test');iframes.src="
341 "'data:text/html,dataurl';"; 168 "'data:text/html,dataurl';";
342 ASSERT_TRUE(ExecuteScript(shell()->web_contents(), data_url_script)); 169 ASSERT_TRUE(ExecuteScript(shell()->web_contents(), data_url_script));
(...skipping 14 matching lines...) Expand all
357 iframe_id.c_str(), url.spec().c_str()); 184 iframe_id.c_str(), url.spec().c_str());
358 WindowedNotificationObserver load_observer( 185 WindowedNotificationObserver load_observer(
359 NOTIFICATION_NAV_ENTRY_COMMITTED, 186 NOTIFICATION_NAV_ENTRY_COMMITTED,
360 Source<NavigationController>( 187 Source<NavigationController>(
361 &window->web_contents()->GetController())); 188 &window->web_contents()->GetController()));
362 bool result = ExecuteScript(window->web_contents(), script); 189 bool result = ExecuteScript(window->web_contents(), script);
363 load_observer.Wait(); 190 load_observer.Wait();
364 return result; 191 return result;
365 } 192 }
366 193
367 void NavigateToURLContentInitiated(Shell* window,
368 const GURL& url,
369 bool should_replace_current_entry,
370 bool should_wait_for_navigation) {
371 std::string script;
372 if (should_replace_current_entry)
373 script = base::StringPrintf("location.replace('%s')", url.spec().c_str());
374 else
375 script = base::StringPrintf("location.href = '%s'", url.spec().c_str());
376 TestNavigationObserver load_observer(shell()->web_contents(), 1);
377 bool result = ExecuteScript(window->web_contents(), script);
378 EXPECT_TRUE(result);
379 if (should_wait_for_navigation)
380 load_observer.Wait();
381 }
382
383 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 194 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
384 command_line->AppendSwitch(switches::kSitePerProcess); 195 command_line->AppendSwitch(switches::kSitePerProcess);
385 196
386 // TODO(creis): Remove this when GTK is no longer a supported platform. 197 // TODO(creis): Remove this when GTK is no longer a supported platform.
387 command_line->AppendSwitch(switches::kForceCompositingMode); 198 command_line->AppendSwitch(switches::kForceCompositingMode);
388 } 199 }
389
390 void InjectResourceDisptcherHostDelegate() {
391 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
392 old_delegate_ = ResourceDispatcherHostImpl::Get()->delegate();
393 ResourceDispatcherHostImpl::Get()->SetDelegate(&tracking_delegate_);
394 }
395
396 void RestoreResourceDisptcherHostDelegate() {
397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
398 ResourceDispatcherHostImpl::Get()->SetDelegate(old_delegate_);
399 old_delegate_ = NULL;
400 }
401
402 TrackingResourceDispatcherHostDelegate& tracking_delegate() {
403 return tracking_delegate_;
404 }
405
406 private:
407 TrackingResourceDispatcherHostDelegate tracking_delegate_;
408 ResourceDispatcherHostDelegate* old_delegate_;
409 }; 200 };
410 201
411 // Ensure that we can complete a cross-process subframe navigation. 202 // Ensure that we can complete a cross-process subframe navigation.
412 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) { 203 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) {
413 host_resolver()->AddRule("*", "127.0.0.1"); 204 host_resolver()->AddRule("*", "127.0.0.1");
414 ASSERT_TRUE(test_server()->Start()); 205 ASSERT_TRUE(test_server()->Start());
415 GURL main_url(test_server()->GetURL("files/site_per_process_main.html")); 206 GURL main_url(test_server()->GetURL("files/site_per_process_main.html"));
416 NavigateToURL(shell(), main_url); 207 NavigateToURL(shell(), main_url);
417 208
418 StartFrameAtDataURL(); 209 StartFrameAtDataURL();
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 GURL server_redirect_http_url(test_server()->GetURL( 508 GURL server_redirect_http_url(test_server()->GetURL(
718 "server-redirect?" + client_redirect_http_url.spec())); 509 "server-redirect?" + client_redirect_http_url.spec()));
719 EXPECT_TRUE(NavigateIframeToURL(shell(), server_redirect_http_url, "test")); 510 EXPECT_TRUE(NavigateIframeToURL(shell(), server_redirect_http_url, "test"));
720 511
721 // DidFailProvisionalLoad when navigating to client_redirect_http_url. 512 // DidFailProvisionalLoad when navigating to client_redirect_http_url.
722 EXPECT_EQ(observer.navigation_url(), client_redirect_http_url); 513 EXPECT_EQ(observer.navigation_url(), client_redirect_http_url);
723 EXPECT_FALSE(observer.navigation_succeeded()); 514 EXPECT_FALSE(observer.navigation_succeeded());
724 } 515 }
725 } 516 }
726 517
727 // Tests that the |should_replace_current_entry| flag persists correctly across
728 // request transfers that began with a cross-process navigation.
729 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
730 ReplaceEntryCrossProcessThenTransfer) {
731 const NavigationController& controller =
732 shell()->web_contents()->GetController();
733 host_resolver()->AddRule("*", "127.0.0.1");
734 ASSERT_TRUE(test_server()->Start());
735
736 // These must all stay in scope with replace_host.
737 GURL::Replacements replace_host;
738 std::string a_com("A.com");
739 std::string b_com("B.com");
740
741 // Navigate to a starting URL, so there is a history entry to replace.
742 GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
743 NavigateToURL(shell(), url1);
744
745 // Force all future navigations to transfer. Note that this includes same-site
746 // navigiations which may cause double process swaps (via OpenURL and then via
747 // transfer). This test intentionally exercises that case.
748 ShellContentBrowserClient::SetSwapProcessesForRedirect(true);
749
750 // Navigate to a page on A.com with entry replacement. This navigation is
751 // cross-site, so the renderer will send it to the browser via OpenURL to give
752 // to a new process. It will then be transferred into yet another process due
753 // to the call above.
754 GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
755 replace_host.SetHostStr(a_com);
756 url2 = url2.ReplaceComponents(replace_host);
757 // Used to make sure the request for url2 succeeds, and there was only one of
758 // them.
759 tracking_delegate().SetTrackedURL(url2);
760 NavigateToURLContentInitiated(shell(), url2, true, true);
761
762 // There should be one history entry. url2 should have replaced url1.
763 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
764 EXPECT_EQ(1, controller.GetEntryCount());
765 EXPECT_EQ(0, controller.GetCurrentEntryIndex());
766 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
767 // Make sure the request succeeded.
768 EXPECT_TRUE(tracking_delegate().WaitForTrackedURLAndGetCompleted());
769
770 // Now navigate as before to a page on B.com, but normally (without
771 // replacement). This will still perform a double process-swap as above, via
772 // OpenURL and then transfer.
773 GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3");
774 replace_host.SetHostStr(b_com);
775 url3 = url3.ReplaceComponents(replace_host);
776 // Used to make sure the request for url3 succeeds, and there was only one of
777 // them.
778 tracking_delegate().SetTrackedURL(url3);
779 NavigateToURLContentInitiated(shell(), url3, false, true);
780
781 // There should be two history entries. url2 should have replaced url1. url2
782 // should not have replaced url3.
783 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
784 EXPECT_EQ(2, controller.GetEntryCount());
785 EXPECT_EQ(1, controller.GetCurrentEntryIndex());
786 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
787 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL());
788
789 // Make sure the request succeeded.
790 EXPECT_TRUE(tracking_delegate().WaitForTrackedURLAndGetCompleted());
791 }
792
793 // Tests that the |should_replace_current_entry| flag persists correctly across
794 // request transfers that began with a content-initiated in-process
795 // navigation. This test is the same as the test above, except transfering from
796 // in-process.
797 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
798 ReplaceEntryInProcessThenTranfers) {
799 const NavigationController& controller =
800 shell()->web_contents()->GetController();
801 ASSERT_TRUE(test_server()->Start());
802
803 // Navigate to a starting URL, so there is a history entry to replace.
804 GURL url = test_server()->GetURL("files/site_isolation/blank.html?1");
805 NavigateToURL(shell(), url);
806
807 // Force all future navigations to transfer. Note that this includes same-site
808 // navigiations which may cause double process swaps (via OpenURL and then via
809 // transfer). All navigations in this test are same-site, so it only swaps
810 // processes via request transfer.
811 ShellContentBrowserClient::SetSwapProcessesForRedirect(true);
812
813 // Navigate in-process with entry replacement. It will then be transferred
814 // into a new one due to the call above.
815 GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
816 NavigateToURLContentInitiated(shell(), url2, true, true);
817
818 // There should be one history entry. url2 should have replaced url1.
819 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
820 EXPECT_EQ(1, controller.GetEntryCount());
821 EXPECT_EQ(0, controller.GetCurrentEntryIndex());
822 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
823
824 // Now navigate as before, but without replacement.
825 GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3");
826 NavigateToURLContentInitiated(shell(), url3, false, true);
827
828 // There should be two history entries. url2 should have replaced url1. url2
829 // should not have replaced url3.
830 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
831 EXPECT_EQ(2, controller.GetEntryCount());
832 EXPECT_EQ(1, controller.GetCurrentEntryIndex());
833 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
834 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL());
835 }
836
837 // Tests that the |should_replace_current_entry| flag persists correctly across
838 // request transfers that cross processes twice from renderer policy.
839 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
840 ReplaceEntryCrossProcessTwice) {
841 const NavigationController& controller =
842 shell()->web_contents()->GetController();
843 host_resolver()->AddRule("*", "127.0.0.1");
844 ASSERT_TRUE(test_server()->Start());
845
846 // These must all stay in scope with replace_host.
847 GURL::Replacements replace_host;
848 std::string a_com("A.com");
849 std::string b_com("B.com");
850
851 // Navigate to a starting URL, so there is a history entry to replace.
852 GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
853 NavigateToURL(shell(), url1);
854
855 // Navigate to a page on A.com which redirects to B.com with entry
856 // replacement. This will switch processes via OpenURL twice. First to A.com,
857 // and second in response to the server redirect to B.com. The second swap is
858 // also renderer-initiated via OpenURL because decidePolicyForNavigation is
859 // currently applied on redirects.
860 GURL url2b = test_server()->GetURL("files/site_isolation/blank.html?2");
861 replace_host.SetHostStr(b_com);
862 url2b = url2b.ReplaceComponents(replace_host);
863 GURL url2a = test_server()->GetURL(
864 "server-redirect?" + net::EscapeQueryParamValue(url2b.spec(), false));
865 replace_host.SetHostStr(a_com);
866 url2a = url2a.ReplaceComponents(replace_host);
867 NavigateToURLContentInitiated(shell(), url2a, true, true);
868
869 // There should be one history entry. url2b should have replaced url1.
870 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
871 EXPECT_EQ(1, controller.GetEntryCount());
872 EXPECT_EQ(0, controller.GetCurrentEntryIndex());
873 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL());
874
875 // Now repeat without replacement.
876 GURL url3b = test_server()->GetURL("files/site_isolation/blank.html?3");
877 replace_host.SetHostStr(b_com);
878 url3b = url3b.ReplaceComponents(replace_host);
879 GURL url3a = test_server()->GetURL(
880 "server-redirect?" + net::EscapeQueryParamValue(url3b.spec(), false));
881 replace_host.SetHostStr(a_com);
882 url3a = url3a.ReplaceComponents(replace_host);
883 NavigateToURLContentInitiated(shell(), url3a, false, true);
884
885 // There should be two history entries. url2b should have replaced url1. url2b
886 // should not have replaced url3b.
887 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
888 EXPECT_EQ(2, controller.GetEntryCount());
889 EXPECT_EQ(1, controller.GetCurrentEntryIndex());
890 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL());
891 EXPECT_EQ(url3b, controller.GetEntryAtIndex(1)->GetURL());
892 }
893
894 // Tests that the request is destroyed when a cross process navigation is
895 // cancelled.
896 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, NoLeakOnCrossSiteCancel) {
897 const NavigationController& controller =
898 shell()->web_contents()->GetController();
899 host_resolver()->AddRule("*", "127.0.0.1");
900 ASSERT_TRUE(test_server()->Start());
901
902 // These must all stay in scope with replace_host.
903 GURL::Replacements replace_host;
904 std::string a_com("A.com");
905 std::string b_com("B.com");
906
907 // Navigate to a starting URL, so there is a history entry to replace.
908 GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
909 NavigateToURL(shell(), url1);
910
911 // Force all future navigations to transfer.
912 ShellContentBrowserClient::SetSwapProcessesForRedirect(true);
913
914 NoTransferRequestDelegate no_transfer_request_delegate;
915 WebContentsDelegate* old_delegate = shell()->web_contents()->GetDelegate();
916 shell()->web_contents()->SetDelegate(&no_transfer_request_delegate);
917
918 // Navigate to a page on A.com with entry replacement. This navigation is
919 // cross-site, so the renderer will send it to the browser via OpenURL to give
920 // to a new process. It will then be transferred into yet another process due
921 // to the call above.
922 GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
923 replace_host.SetHostStr(a_com);
924 url2 = url2.ReplaceComponents(replace_host);
925 // Used to make sure the second request is cancelled, and there is only one
926 // request for url2.
927 tracking_delegate().SetTrackedURL(url2);
928
929 // Don't wait for the navigation to complete, since that never happens in
930 // this case.
931 NavigateToURLContentInitiated(shell(), url2, false, false);
932
933 // There should be one history entry, with url1.
934 EXPECT_EQ(1, controller.GetEntryCount());
935 EXPECT_EQ(0, controller.GetCurrentEntryIndex());
936 EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL());
937
938 // Make sure the request for url2 did not complete.
939 EXPECT_FALSE(tracking_delegate().WaitForTrackedURLAndGetCompleted());
940
941 shell()->web_contents()->SetDelegate(old_delegate);
942 }
943
944 } // namespace content 518 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/cross_site_transfer_browsertest.cc ('k') | content/content_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698