OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/test/base/chrome_render_view_host_test_harness.h" | 5 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
6 #include "chrome/test/base/testing_profile.h" | 6 #include "chrome/test/base/testing_profile.h" |
7 #include "content/browser/browser_thread_impl.h" | 7 #include "content/browser/browser_thread_impl.h" |
8 #include "content/browser/browser_url_handler.h" | 8 #include "content/browser/browser_url_handler.h" |
9 #include "content/browser/site_instance.h" | 9 #include "content/browser/site_instance.h" |
10 #include "content/browser/tab_contents/navigation_controller.h" | 10 #include "content/browser/tab_contents/navigation_controller.h" |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 ASSERT_TRUE(host); | 265 ASSERT_TRUE(host); |
266 EXPECT_TRUE(host->site_instance()->has_site()); | 266 EXPECT_TRUE(host->site_instance()->has_site()); |
267 // Check the pending RenderViewHost has been committed. | 267 // Check the pending RenderViewHost has been committed. |
268 EXPECT_FALSE(manager.pending_render_view_host()); | 268 EXPECT_FALSE(manager.pending_render_view_host()); |
269 | 269 |
270 // We should observe a notification. | 270 // We should observe a notification. |
271 EXPECT_TRUE(notifications.Check1AndReset( | 271 EXPECT_TRUE(notifications.Check1AndReset( |
272 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED)); | 272 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED)); |
273 } | 273 } |
274 | 274 |
| 275 // Tests the Navigate function. In this unit test we verify that the Navigate |
| 276 // function can handle a new navigation event before the previous navigation |
| 277 // has been committed. This is also a regression test for |
| 278 // http://crbug.com/104600. |
| 279 TEST_F(RenderViewHostManagerTest, NavigateWithEarlyReNavigation) { |
| 280 TestNotificationTracker notifications; |
| 281 |
| 282 SiteInstance* instance = SiteInstance::CreateSiteInstance(profile()); |
| 283 |
| 284 TestTabContents tab_contents(profile(), instance); |
| 285 notifications.ListenFor( |
| 286 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, |
| 287 content::Source<NavigationController>(&tab_contents.controller())); |
| 288 |
| 289 // Create. |
| 290 RenderViewHostManager manager(&tab_contents, &tab_contents); |
| 291 |
| 292 manager.Init(profile(), instance, MSG_ROUTING_NONE); |
| 293 |
| 294 // 1) The first navigation. -------------------------- |
| 295 const GURL kUrl1("http://www.google.com/"); |
| 296 NavigationEntry entry1(NULL /* instance */, -1 /* page_id */, kUrl1, |
| 297 GURL() /* referrer */, string16() /* title */, |
| 298 content::PAGE_TRANSITION_TYPED, |
| 299 false /* is_renderer_init */); |
| 300 RenderViewHost* host = manager.Navigate(entry1); |
| 301 |
| 302 // The RenderViewHost created in Init will be reused. |
| 303 EXPECT_TRUE(host == manager.current_host()); |
| 304 EXPECT_FALSE(manager.pending_render_view_host()); |
| 305 |
| 306 // We should observe a notification. |
| 307 EXPECT_TRUE(notifications.Check1AndReset( |
| 308 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED)); |
| 309 notifications.Reset(); |
| 310 |
| 311 // Commit. |
| 312 manager.DidNavigateMainFrame(host); |
| 313 |
| 314 // Commit to SiteInstance should be delayed until RenderView commit. |
| 315 EXPECT_TRUE(host == manager.current_host()); |
| 316 ASSERT_TRUE(host); |
| 317 EXPECT_FALSE(host->site_instance()->has_site()); |
| 318 host->site_instance()->SetSite(kUrl1); |
| 319 |
| 320 // 2) Cross-site navigate to next site. ------------------------- |
| 321 const GURL kUrl2("http://www.example.com"); |
| 322 NavigationEntry entry2(NULL /* instance */, -1 /* page_id */, kUrl2, |
| 323 GURL() /* referrer */, string16() /* title */, |
| 324 content::PAGE_TRANSITION_TYPED, |
| 325 false /* is_renderer_init */); |
| 326 RenderViewHost* host2 = manager.Navigate(entry2); |
| 327 |
| 328 // A new RenderViewHost should be created. |
| 329 EXPECT_TRUE(manager.pending_render_view_host()); |
| 330 ASSERT_EQ(host2, manager.pending_render_view_host()); |
| 331 |
| 332 // Check that the navigation is still suspended because the old RVH |
| 333 // is not swapped out, yet. |
| 334 MockRenderProcessHost* test_process_host2 = |
| 335 static_cast<MockRenderProcessHost*>(host2->process()); |
| 336 test_process_host2->sink().ClearMessages(); |
| 337 host2->NavigateToURL(kUrl2); |
| 338 EXPECT_FALSE(test_process_host2->sink().GetUniqueMessageMatching( |
| 339 ViewMsg_Navigate::ID)); |
| 340 |
| 341 // Allow closing the current Render View (precondition for swapping out |
| 342 // the RVH): Simulate response from RenderView for ViewMsg_ShouldClose sent by |
| 343 // FirePageBeforeUnload |
| 344 TestRenderViewHost* test_host = static_cast<TestRenderViewHost*>(host); |
| 345 MockRenderProcessHost* test_process_host = |
| 346 static_cast<MockRenderProcessHost*>(test_host->process()); |
| 347 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching( |
| 348 ViewMsg_ShouldClose::ID)); |
| 349 test_host->SendShouldCloseACK(true); |
| 350 |
| 351 // CrossSiteResourceHandler::StartCrossSiteTransition can trigger a |
| 352 // call of RenderViewHostManager::OnCrossSiteResponse before |
| 353 // RenderViewHostManager::DidNavigateMainFrame is called. In this case the |
| 354 // RVH is swapped out. |
| 355 manager.OnCrossSiteResponse(host2->process()->GetID(), |
| 356 host2->GetPendingRequestId()); |
| 357 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching( |
| 358 ViewMsg_SwapOut::ID)); |
| 359 test_host->OnSwapOutACK(); |
| 360 |
| 361 EXPECT_EQ(host, manager.current_host()); |
| 362 EXPECT_TRUE(manager.current_host()->is_swapped_out()); |
| 363 EXPECT_EQ(host2, manager.pending_render_view_host()); |
| 364 // There should be still no navigation messages being sent. |
| 365 EXPECT_FALSE(test_process_host2->sink().GetUniqueMessageMatching( |
| 366 ViewMsg_Navigate::ID)); |
| 367 |
| 368 // 3) Cross-site navigate to next site before 2) has committed. -------------- |
| 369 const GURL kUrl3("http://webkit.org/"); |
| 370 NavigationEntry entry3(NULL /* instance */, -1 /* page_id */, kUrl3, |
| 371 GURL() /* referrer */, string16() /* title */, |
| 372 content::PAGE_TRANSITION_TYPED, |
| 373 false /* is_renderer_init */); |
| 374 RenderViewHost* host3 = manager.Navigate(entry3); |
| 375 |
| 376 // A new RenderViewHost should be created. |
| 377 EXPECT_TRUE(manager.pending_render_view_host()); |
| 378 ASSERT_EQ(host3, manager.pending_render_view_host()); |
| 379 |
| 380 EXPECT_EQ(host, manager.current_host()); |
| 381 EXPECT_TRUE(manager.current_host()->is_swapped_out()); |
| 382 |
| 383 // The navigation should not be suspended because the RVH |host| has been |
| 384 // swapped out already. Therefore, the RVH should send a navigation event |
| 385 // immediately. |
| 386 MockRenderProcessHost* test_process_host3 = |
| 387 static_cast<MockRenderProcessHost*>(host3->process()); |
| 388 test_process_host3->sink().ClearMessages(); |
| 389 |
| 390 // Usually TabContents::NavigateToEntry would call |
| 391 // RenderViewHostManager::Navigate followed by RenderViewHost::Navigate. |
| 392 // Here we need to call the latter ourselves. |
| 393 host3->NavigateToURL(kUrl3); |
| 394 EXPECT_TRUE(test_process_host3->sink().GetUniqueMessageMatching( |
| 395 ViewMsg_Navigate::ID)); |
| 396 |
| 397 // Commit. |
| 398 manager.DidNavigateMainFrame(host3); |
| 399 EXPECT_TRUE(host3 == manager.current_host()); |
| 400 ASSERT_TRUE(host3); |
| 401 EXPECT_TRUE(host3->site_instance()->has_site()); |
| 402 // Check the pending RenderViewHost has been committed. |
| 403 EXPECT_FALSE(manager.pending_render_view_host()); |
| 404 |
| 405 // We should observe a notification. |
| 406 EXPECT_TRUE(notifications.Check1AndReset( |
| 407 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED)); |
| 408 } |
| 409 |
275 // Tests WebUI creation. | 410 // Tests WebUI creation. |
276 TEST_F(RenderViewHostManagerTest, WebUI) { | 411 TEST_F(RenderViewHostManagerTest, WebUI) { |
277 BrowserThreadImpl ui_thread(BrowserThread::UI, MessageLoop::current()); | 412 BrowserThreadImpl ui_thread(BrowserThread::UI, MessageLoop::current()); |
278 SiteInstance* instance = SiteInstance::CreateSiteInstance(profile()); | 413 SiteInstance* instance = SiteInstance::CreateSiteInstance(profile()); |
279 | 414 |
280 TestTabContents tab_contents(profile(), instance); | 415 TestTabContents tab_contents(profile(), instance); |
281 RenderViewHostManager manager(&tab_contents, &tab_contents); | 416 RenderViewHostManager manager(&tab_contents, &tab_contents); |
282 | 417 |
283 manager.Init(profile(), instance, MSG_ROUTING_NONE); | 418 manager.Init(profile(), instance, MSG_ROUTING_NONE); |
284 | 419 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 // current one. | 514 // current one. |
380 EXPECT_TRUE(contents()->render_manager_for_testing()-> | 515 EXPECT_TRUE(contents()->render_manager_for_testing()-> |
381 pending_render_view_host() == NULL); | 516 pending_render_view_host() == NULL); |
382 EXPECT_EQ(evil_rvh, contents()->render_manager_for_testing()->current_host()); | 517 EXPECT_EQ(evil_rvh, contents()->render_manager_for_testing()->current_host()); |
383 | 518 |
384 // Also we should not have a pending navigation entry. | 519 // Also we should not have a pending navigation entry. |
385 NavigationEntry* entry = contents()->controller().GetActiveEntry(); | 520 NavigationEntry* entry = contents()->controller().GetActiveEntry(); |
386 ASSERT_TRUE(entry != NULL); | 521 ASSERT_TRUE(entry != NULL); |
387 EXPECT_EQ(kUrl2, entry->url()); | 522 EXPECT_EQ(kUrl2, entry->url()); |
388 } | 523 } |
OLD | NEW |