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

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

Issue 782093002: Ensure that before creating proxy of site A, RVH of site A is initialized. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleaned up test files to load the tree structure directly from html Created 5 years, 11 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
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 "content/browser/site_per_process_browsertest.h" 5 #include "content/browser/site_per_process_browsertest.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "content/browser/frame_host/cross_process_frame_connector.h" 10 #include "content/browser/frame_host/cross_process_frame_connector.h"
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 371
372 // Navigate back to the parent's origin and ensure we return to the 372 // Navigate back to the parent's origin and ensure we return to the
373 // parent's process. 373 // parent's process.
374 NavigateFrameToURL(child, http_url); 374 NavigateFrameToURL(child, http_url);
375 EXPECT_EQ(http_url, observer.navigation_url()); 375 EXPECT_EQ(http_url, observer.navigation_url());
376 EXPECT_TRUE(observer.navigation_succeeded()); 376 EXPECT_TRUE(observer.navigation_succeeded());
377 EXPECT_EQ(shell()->web_contents()->GetSiteInstance(), 377 EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
378 child->current_frame_host()->GetSiteInstance()); 378 child->current_frame_host()->GetSiteInstance());
379 } 379 }
380 380
381 // This test checks that killing a renderer process of a remote frame
382 // and then navigating some other frame to the same SiteInstance of the killed
383 // process works properly.
384 // This can be illustrated as follows,
385 // where 1/2/3 are FrameTreeNode-s and A/B are processes and B* is the killed
386 // B process:
387 //
388 // 1 A A A
389 // / \ -> / \ -> Kill B -> / \ -> Navigate 3 to B -> / \ .
390 // 2 3 B A B* A B* B
391 //
392 // Initially, node1.proxy_hosts_ = {B}
393 // After we kill B, we make sure B stays in node1.proxy_hosts_, then we navigate
394 // 3 to B and we expect that to complete normally.
395 // See http://crbug.com/432107.
396 //
397 // Note that due to http://crbug.com/450681, node2 cannot be re-navigated to
398 // site B and stays in not rendered state.
399 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
400 NavigateRemoteFrameToKilledProcess) {
401 GURL main_url(embedded_test_server()->GetURL(
402 "/frame_tree/page_with_two_frames.html"));
403 NavigateToURL(shell(), main_url);
404
405 // It is safe to obtain the root frame tree node here, as it doesn't change.
406 FrameTreeNode* root =
407 static_cast<WebContentsImpl*>(shell()->web_contents())->
408 GetFrameTree()->root();
409
410 SitePerProcessWebContentsObserver observer(shell()->web_contents());
411 ASSERT_EQ(2U, root->child_count());
412
413 // Make sure node2 points to the correct cross-site page.
414 GURL site_b_url = embedded_test_server()->GetURL("bar.com", "/title1.html");
415 FrameTreeNode* node2 = root->child_at(0);
416 EXPECT_EQ(site_b_url, node2->current_url());
417
418 // Kill that cross-site renderer.
419 RenderProcessHost* child_process =
420 node2->current_frame_host()->GetProcess();
421 RenderProcessHostWatcher crash_observer(
422 child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
423 child_process->Shutdown(0, false);
424 crash_observer.Wait();
425
426 // Now navigate the second iframe (node3) to the same site as the node2.
427 FrameTreeNode* node3 = root->child_at(1);
428 NavigateFrameToURL(node3, site_b_url);
429 EXPECT_TRUE(observer.navigation_succeeded());
430 EXPECT_EQ(site_b_url, observer.navigation_url());
431 }
432
433 // This test is similar to
434 // SitePerProcessBrowserTest.NavigateRemoteFrameToKilledProcess with
435 // addition that node2 also has a cross-origin frame to site C.
436 //
437 // 1 A A A
438 // / \ / \ / \ / \ .
439 // 2 3 -> B A -> Kill B -> B* A -> Navigate 3 -> B* B
440 // / /
441 // 4 C
442 //
443 // Initially, node1.proxy_hosts_ = {B, C}
444 // After we kill B, we make sure B stays in node1.proxy_hosts_, but
445 // C gets cleared from node1.proxy_hosts_.
446 //
447 // Note that due to another bug node2 does not re-navigate to site B and stays
nasko 2015/02/02 22:47:09 nit: cite the bug number here, as you've done in t
lazyboy 2015/02/03 00:22:42 Done.
448 // in not rendered state.
449 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
450 NavigateRemoteFrameToKilledProcessWithSubtree) {
451 GURL main_url(
452 embedded_test_server()->GetURL(
453 "/frame_tree/page_with_two_frames_nested.html"));
454 NavigateToURL(shell(), main_url);
455
456 // It is safe to obtain the root frame tree node here, as it doesn't change.
457 FrameTreeNode* root =
458 static_cast<WebContentsImpl*>(shell()->web_contents())->
459 GetFrameTree()->root();
460 SitePerProcessWebContentsObserver observer(shell()->web_contents());
461
462 ASSERT_EQ(2U, root->child_count());
463
464 GURL site_b_url(
465 embedded_test_server()->GetURL(
466 "bar.com", "/frame_tree/page_with_one_frame.html"));
467 // We can't use a SitePerProcessWebContentsObserver to verify the URL here,
468 // since the frame has children that may have clobbered it in the observer.
469 EXPECT_EQ(site_b_url, root->child_at(0)->current_url());
470
471 // Ensure that a new process is created for node2.
472 EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
473 root->child_at(0)->current_frame_host()->GetSiteInstance());
474 // Ensure that a new process is *not* created for node3.
475 EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
476 root->child_at(1)->current_frame_host()->GetSiteInstance());
477
478 ASSERT_EQ(1U, root->child_at(0)->child_count());
lazyboy 2015/01/22 23:32:35 This is the part I was worried about: whether the
nasko 2015/02/02 22:47:09 This should work. It waits for DidStopLoading, whi
lazyboy 2015/02/03 00:22:42 Acknowledged.
479
480 // Make sure node4 points to the correct cross-site page.
481 FrameTreeNode* node4 = root->child_at(0)->child_at(0);
482 GURL site_c_url(embedded_test_server()->GetURL("baz.com", "/title1.html"));
483 EXPECT_EQ(site_c_url, node4->current_url());
484
485 // |site_instance_c| is expected to go away once we kill |child_process_b|
486 // below, so create a local scope so we can extend the lifetime of
487 // |site_instance_c| with a refptr.
488 {
489 SiteInstance* site_instance_b =
490 root->child_at(0)->current_frame_host()->GetSiteInstance();
491 // |site_c| will go away, so extend its lifetime with a refptr.
492 scoped_refptr<SiteInstanceImpl> site_instance_c =
493 node4->current_frame_host()->GetSiteInstance();
494
495 // Initially proxies for both B and C will be present in the root and node3.
496 EXPECT_TRUE(root->render_manager()->GetRenderFrameProxyHost(
497 site_instance_b));
498 EXPECT_TRUE(root->render_manager()->GetRenderFrameProxyHost(
499 site_instance_c.get()));
500 FrameTreeNode* node3 = root->child_at(1);
501 EXPECT_TRUE(node3->render_manager()->GetRenderFrameProxyHost(
502 site_instance_b));
503 EXPECT_TRUE(node3->render_manager()->GetRenderFrameProxyHost(
504 site_instance_c.get()));
505
506 // Kill that cross-site renderer/process B.
507 RenderProcessHost* child_process_b =
508 root->child_at(0)->current_frame_host()->GetProcess();
509 RenderProcessHostWatcher crash_observer(
510 child_process_b, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
511 child_process_b->Shutdown(0, false);
512 crash_observer.Wait();
513
514 // Make sure proxy B stays around in root and node3.
515 EXPECT_TRUE(root->render_manager()->GetRenderFrameProxyHost(
516 site_instance_b));
517 EXPECT_TRUE(node3->render_manager()->GetRenderFrameProxyHost(
518 site_instance_b));
519 // Make sure proxy C goes away from root and node3.
520 EXPECT_FALSE(root->render_manager()->GetRenderFrameProxyHost(
521 site_instance_c.get()));
522 EXPECT_FALSE(node3->render_manager()->GetRenderFrameProxyHost(
523 site_instance_c.get()));
524 }
525
526 // Now navigate the second iframe (node3) to the same site as the node2.
527 FrameTreeNode* node3 = root->child_at(1);
528 GURL url = embedded_test_server()->GetURL("bar.com", "/title1.html");
529 NavigateFrameToURL(node3, url);
530 EXPECT_TRUE(observer.navigation_succeeded());
531 EXPECT_EQ(url, observer.navigation_url());
532 }
533
381 // In A-embed-B-embed-C scenario, verify that killing process B clears proxies 534 // In A-embed-B-embed-C scenario, verify that killing process B clears proxies
382 // of C from the tree. 535 // of C from the tree.
383 // 536 //
384 // 1 A A 537 // 1 A A
385 // / \ / \ / \ . 538 // / \ / \ / \ .
386 // 2 3 -> B A -> Kill B -> B* A 539 // 2 3 -> B A -> Kill B -> B* A
387 // / / 540 // / /
388 // 4 C 541 // 4 C
389 // 542 //
390 // node1 is the root. 543 // node1 is the root.
391 // Initially, both node1.proxy_hosts_ and node3.proxy_hosts_ contain C. 544 // Initially, both node1.proxy_hosts_ and node3.proxy_hosts_ contain C.
392 // After we kill B, make sure proxies for C are cleared. 545 // After we kill B, make sure proxies for C are cleared.
393 //
394 // TODO(lazyboy): Once http://crbug.com/432107 is fixed, we should also make
395 // sure that proxies for B are not cleared when we kill B.
396 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, 546 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
397 KillingRendererClearsDescendantProxies) { 547 KillingRendererClearsDescendantProxies) {
398 GURL main_url( 548 GURL main_url(
399 embedded_test_server()->GetURL("/frame_tree/page_with_two_frames.html")); 549 embedded_test_server()->GetURL(
550 "/frame_tree/page_with_two_frames_nested.html"));
400 NavigateToURL(shell(), main_url); 551 NavigateToURL(shell(), main_url);
401 552
402 // It is safe to obtain the root frame tree node here, as it doesn't change. 553 // It is safe to obtain the root frame tree node here, as it doesn't change.
403 FrameTreeNode* root = 554 FrameTreeNode* root =
404 static_cast<WebContentsImpl*>(shell()->web_contents())-> 555 static_cast<WebContentsImpl*>(shell()->web_contents())->
405 GetFrameTree()->root(); 556 GetFrameTree()->root();
406 SitePerProcessWebContentsObserver observer(shell()->web_contents()); 557 SitePerProcessWebContentsObserver observer(shell()->web_contents());
407 558
408 ASSERT_EQ(2U, root->child_count()); 559 ASSERT_EQ(2U, root->child_count());
409 560
410 // Navigate the second subframe (node3) to a local frame.
411 GURL site_a_url(embedded_test_server()->GetURL("/title1.html"));
412 NavigateFrameToURL(root->child_at(1), site_a_url);
413
414 // Navigate the first subframe (node2) to a cross-site page with two
415 // subframes.
416 // NavigateFrameToURL can't be used here because it doesn't guarantee that
417 // FrameTreeNodes will have been created for child frames when it returns.
418 RenderFrameHostCreatedObserver frame_observer(shell()->web_contents(), 3);
419 GURL site_b_url( 561 GURL site_b_url(
420 embedded_test_server()->GetURL( 562 embedded_test_server()->GetURL(
421 "bar.com", "/frame_tree/page_with_one_frame.html")); 563 "bar.com", "/frame_tree/page_with_one_frame.html"));
422 NavigationController::LoadURLParams params_b(site_b_url);
423 params_b.transition_type = ui::PAGE_TRANSITION_LINK;
424 params_b.frame_tree_node_id = root->child_at(0)->frame_tree_node_id();
425 root->child_at(0)->navigator()->GetController()->LoadURLWithParams(params_b);
426 frame_observer.Wait();
427
428 // We can't use a SitePerProcessWebContentsObserver to verify the URL here, 564 // We can't use a SitePerProcessWebContentsObserver to verify the URL here,
429 // since the frame has children that may have clobbered it in the observer. 565 // since the frame has children that may have clobbered it in the observer.
430 EXPECT_EQ(site_b_url, root->child_at(0)->current_url()); 566 EXPECT_EQ(site_b_url, root->child_at(0)->current_url());
431 567
432 // Ensure that a new process is created for node2. 568 // Ensure that a new process is created for node2.
433 EXPECT_NE(shell()->web_contents()->GetSiteInstance(), 569 EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
434 root->child_at(0)->current_frame_host()->GetSiteInstance()); 570 root->child_at(0)->current_frame_host()->GetSiteInstance());
435 // Ensure that a new process is *not* created for node3. 571 // Ensure that a new process is *not* created for node3.
436 EXPECT_EQ(shell()->web_contents()->GetSiteInstance(), 572 EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
437 root->child_at(1)->current_frame_host()->GetSiteInstance()); 573 root->child_at(1)->current_frame_host()->GetSiteInstance());
438 574
439 ASSERT_EQ(1U, root->child_at(0)->child_count()); 575 ASSERT_EQ(1U, root->child_at(0)->child_count());
440 576
441 // Navigate node4 to cross-site-page. 577 // Make sure node4 points to the correct cross-site-page.
442 FrameTreeNode* node4 = root->child_at(0)->child_at(0); 578 FrameTreeNode* node4 = root->child_at(0)->child_at(0);
443 GURL site_c_url(embedded_test_server()->GetURL("baz.com", "/title2.html")); 579 GURL site_c_url(embedded_test_server()->GetURL("baz.com", "/title1.html"));
444 NavigateFrameToURL(node4, site_c_url); 580 EXPECT_EQ(site_c_url, node4->current_url());
445 EXPECT_TRUE(observer.navigation_succeeded());
446 EXPECT_EQ(site_c_url, observer.navigation_url());
447 581
448 // |site_instance_c| is expected to go away once we kill |child_process_b| 582 // |site_instance_c| is expected to go away once we kill |child_process_b|
449 // below, so create a local scope so we can extend the lifetime of 583 // below, so create a local scope so we can extend the lifetime of
450 // |site_instance_c| with a refptr. 584 // |site_instance_c| with a refptr.
451 { 585 {
452 SiteInstance* site_instance_b = 586 SiteInstance* site_instance_b =
453 root->child_at(0)->current_frame_host()->GetSiteInstance(); 587 root->child_at(0)->current_frame_host()->GetSiteInstance();
454 scoped_refptr<SiteInstanceImpl> site_instance_c = 588 scoped_refptr<SiteInstanceImpl> site_instance_c =
455 node4->current_frame_host()->GetSiteInstance(); 589 node4->current_frame_host()->GetSiteInstance();
456 590
(...skipping 10 matching lines...) Expand all
467 child_process_b, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); 601 child_process_b, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
468 child_process_b->Shutdown(0, false); 602 child_process_b->Shutdown(0, false);
469 crash_observer.Wait(); 603 crash_observer.Wait();
470 604
471 // Make sure proxy C has gone from root. 605 // Make sure proxy C has gone from root.
472 EXPECT_FALSE(root->render_manager()->GetRenderFrameProxyHost( 606 EXPECT_FALSE(root->render_manager()->GetRenderFrameProxyHost(
473 site_instance_c.get())); 607 site_instance_c.get()));
474 // Make sure proxy C has gone from node3 as well. 608 // Make sure proxy C has gone from node3 as well.
475 EXPECT_FALSE(root->child_at(1)->render_manager()->GetRenderFrameProxyHost( 609 EXPECT_FALSE(root->child_at(1)->render_manager()->GetRenderFrameProxyHost(
476 site_instance_c.get())); 610 site_instance_c.get()));
477 // TODO(lazyboy): Once http://crbug.com/432107 is fixed, we should also 611 // Make sure proxy B stays around in root and node3.
478 // check that proxy B exists in both root and node3. 612 EXPECT_TRUE(root->render_manager()->GetRenderFrameProxyHost(
613 site_instance_b));
614 EXPECT_TRUE(root->child_at(1)->render_manager()->GetRenderFrameProxyHost(
615 site_instance_b));
479 } 616 }
480 } 617 }
481 618
482 // Crash a subframe and ensures its children are cleared from the FrameTree. 619 // Crash a subframe and ensures its children are cleared from the FrameTree.
483 // See http://crbug.com/338508. 620 // See http://crbug.com/338508.
484 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrashSubframe) { 621 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrashSubframe) {
485 GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html")); 622 GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
486 NavigateToURL(shell(), main_url); 623 NavigateToURL(shell(), main_url);
487 624
488 StartFrameAtDataURL(); 625 StartFrameAtDataURL();
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 params.frame_tree_node_id = child->frame_tree_node_id(); 1219 params.frame_tree_node_id = child->frame_tree_node_id();
1083 child->navigator()->GetController()->LoadURLWithParams(params); 1220 child->navigator()->GetController()->LoadURLWithParams(params);
1084 nav_observer.Wait(); 1221 nav_observer.Wait();
1085 1222
1086 // Verify that the navigation succeeded and the expected URL was loaded. 1223 // Verify that the navigation succeeded and the expected URL was loaded.
1087 EXPECT_TRUE(observer.navigation_succeeded()); 1224 EXPECT_TRUE(observer.navigation_succeeded());
1088 EXPECT_EQ(url, observer.navigation_url()); 1225 EXPECT_EQ(url, observer.navigation_url());
1089 } 1226 }
1090 1227
1091 } // namespace content 1228 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698