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

Side by Side Diff: content/browser/tab_contents/render_view_host_manager_unittest.cc

Issue 8587029: Fixed race-condition in RenderViewHost(Manager) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments Created 9 years, 1 month 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
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « content/browser/tab_contents/render_view_host_manager.cc ('k') | content/browser/tab_contents/tab_contents.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698