Chromium Code Reviews| 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 "base/file_util.h" | 5 #include "base/file_util.h" |
| 6 #include "base/memory/ref_counted.h" | 6 #include "base/memory/ref_counted.h" |
| 7 #include "base/path_service.h" | 7 #include "base/path_service.h" |
| 8 #include "chrome/browser/ui/browser.h" | 8 #include "chrome/browser/ui/browser.h" |
| 9 #include "chrome/test/base/in_process_browser_test.h" | 9 #include "chrome/test/base/in_process_browser_test.h" |
| 10 #include "chrome/test/base/ui_test_utils.h" | 10 #include "chrome/test/base/ui_test_utils.h" |
| 11 #include "content/browser/renderer_host/render_view_host.h" | |
| 12 #include "content/browser/renderer_host/render_view_host_observer.h" | |
| 11 #include "content/browser/site_instance.h" | 13 #include "content/browser/site_instance.h" |
| 12 #include "content/browser/tab_contents/tab_contents.h" | 14 #include "content/browser/tab_contents/tab_contents.h" |
| 13 #include "content/common/content_notification_types.h" | 15 #include "content/common/content_notification_types.h" |
| 14 #include "content/common/notification_details.h" | 16 #include "content/common/notification_details.h" |
| 15 #include "content/common/notification_observer.h" | 17 #include "content/common/notification_observer.h" |
| 16 #include "content/common/notification_registrar.h" | 18 #include "content/common/notification_registrar.h" |
| 19 #include "content/common/url_constants.h" | |
| 17 #include "net/base/net_util.h" | 20 #include "net/base/net_util.h" |
| 18 #include "net/test/test_server.h" | 21 #include "net/test/test_server.h" |
| 19 | 22 |
| 20 class RenderViewHostManagerTest : public InProcessBrowserTest { | 23 class RenderViewHostManagerTest : public InProcessBrowserTest { |
| 21 public: | 24 public: |
| 22 RenderViewHostManagerTest() { | 25 RenderViewHostManagerTest() { |
| 23 EnableDOMAutomation(); | 26 EnableDOMAutomation(); |
| 24 } | 27 } |
| 25 | 28 |
| 26 static bool GetFilePathWithHostAndPortReplacement( | 29 static bool GetFilePathWithHostAndPortReplacement( |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 239 EXPECT_EQ(1, browser()->tab_count()); | 242 EXPECT_EQ(1, browser()->tab_count()); |
| 240 EXPECT_EQ(0, browser()->active_index()); | 243 EXPECT_EQ(0, browser()->active_index()); |
| 241 EXPECT_EQ("/files/title2.html", | 244 EXPECT_EQ("/files/title2.html", |
| 242 browser()->GetSelectedTabContents()->GetURL().path()); | 245 browser()->GetSelectedTabContents()->GetURL().path()); |
| 243 | 246 |
| 244 // Should have the same SiteInstance. | 247 // Should have the same SiteInstance. |
| 245 scoped_refptr<SiteInstance> noref_site_instance( | 248 scoped_refptr<SiteInstance> noref_site_instance( |
| 246 browser()->GetSelectedTabContents()->GetSiteInstance()); | 249 browser()->GetSelectedTabContents()->GetSiteInstance()); |
| 247 EXPECT_EQ(orig_site_instance, noref_site_instance); | 250 EXPECT_EQ(orig_site_instance, noref_site_instance); |
| 248 } | 251 } |
| 252 | |
| 253 // This class holds onto RenderViewHostObservers for as long as their observed | |
| 254 // RenderViewHosts are alive. This allows us to confirm that all hosts have | |
| 255 // properly been shutdown. | |
| 256 class RenderViewHostObserverArray { | |
| 257 public: | |
| 258 ~RenderViewHostObserverArray() { | |
| 259 // In case some would be left in there with a dead pointer to us. | |
| 260 for (std::list<RVHObserver*>::iterator iter = observers_.begin(); | |
| 261 iter != observers_.end(); ++iter) { | |
| 262 (*iter)->ClearParent(); | |
| 263 } | |
| 264 } | |
| 265 void AddObserverToRVH(RenderViewHost* rvh) { | |
| 266 observers_.push_back(new RVHObserver(this, rvh)); | |
| 267 } | |
| 268 size_t GetNumObservers() const { | |
| 269 return observers_.size(); | |
| 270 } | |
| 271 private: | |
| 272 friend class RVHObserver; | |
| 273 class RVHObserver : public RenderViewHostObserver { | |
| 274 public: | |
| 275 RVHObserver(RenderViewHostObserverArray* parent, RenderViewHost* rvh) | |
| 276 : RenderViewHostObserver(rvh), | |
| 277 parent_(parent) { | |
| 278 } | |
| 279 virtual void RenderViewHostDestroyed() OVERRIDE { | |
| 280 if (parent_) | |
| 281 parent_->RemoveObserver(this); | |
| 282 RenderViewHostObserver::RenderViewHostDestroyed(); | |
| 283 }; | |
| 284 void ClearParent() { | |
| 285 parent_ = NULL; | |
| 286 } | |
| 287 private: | |
| 288 RenderViewHostObserverArray* parent_; | |
| 289 }; | |
| 290 | |
| 291 void RemoveObserver(RVHObserver* observer) { | |
| 292 observers_.remove(observer); | |
| 293 } | |
| 294 | |
| 295 std::list<RVHObserver*> observers_; | |
| 296 }; | |
| 297 | |
| 298 // Test for crbug.com/90867. Make sure we don't leak render view hosts since | |
| 299 // they may cause crashes or memory corruptions when trying to call dead | |
| 300 // delegate_. | |
| 301 IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, LeakingRenderViewHosts) { | |
| 302 // Start two servers with different sites. | |
| 303 ASSERT_TRUE(test_server()->Start()); | |
| 304 net::TestServer https_server(net::TestServer::TYPE_HTTPS, | |
| 305 FilePath(FILE_PATH_LITERAL("chrome/test/data"))); | |
| 306 ASSERT_TRUE(https_server.Start()); | |
| 307 | |
| 308 // Create a new tab so that we can close the one we navigate and still have | |
| 309 // a running browser. | |
| 310 AddBlankTabAndShow(browser()); | |
| 311 | |
| 312 // Load a random page and then navigate to view-source: of it. | |
| 313 // This is one way to cause two rvh instances for the same instance id. | |
| 314 GURL navigated_url(test_server()->GetURL("files/title2.html")); | |
| 315 ui_test_utils::NavigateToURL(browser(), navigated_url); | |
| 316 | |
| 317 // Observe the newly created render_view_host to make sure it will not leak. | |
| 318 RenderViewHostObserverArray rvh_observers; | |
| 319 rvh_observers.AddObserverToRVH(browser()->GetSelectedTabContents()-> | |
| 320 render_view_host()); | |
| 321 | |
| 322 GURL view_source_url(chrome::kViewSourceScheme + std::string(":") + | |
| 323 navigated_url.spec()); | |
| 324 ui_test_utils::NavigateToURL(browser(), view_source_url); | |
| 325 rvh_observers.AddObserverToRVH(browser()->GetSelectedTabContents()-> | |
| 326 render_view_host()); | |
| 327 | |
| 328 // Now navigate to a different instance so that we swap out again. | |
| 329 ui_test_utils::NavigateToURL(browser(), | |
| 330 https_server.GetURL("files/title2.html")); | |
| 331 rvh_observers.AddObserverToRVH(browser()->GetSelectedTabContents()-> | |
| 332 render_view_host()); | |
|
Charlie Reis
2011/08/24 21:18:52
Maybe add an EXPECT_EQ(3, rvh_observers.GetNumObse
MAD
2011/08/24 21:31:07
Done.
| |
| 333 | |
| 334 // This used to leak a render view host. | |
| 335 browser()->CloseTabContents(browser()->GetSelectedTabContents()); | |
| 336 EXPECT_EQ(0, rvh_observers.GetNumObservers()); | |
| 337 } | |
| OLD | NEW |