Chromium Code Reviews| Index: content/browser/site_instance_impl_unittest.cc |
| diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc |
| index f2cd603b8332be96f9627be3f9cc00d22cd1faa7..913ded3235d4e21a41abdc065e94ca269071cae4 100644 |
| --- a/content/browser/site_instance_impl_unittest.cc |
| +++ b/content/browser/site_instance_impl_unittest.cc |
| @@ -34,14 +34,15 @@ |
| #include "url/url_util.h" |
| namespace content { |
| -namespace { |
| const char kPrivilegedScheme[] = "privileged"; |
| class SiteInstanceTestBrowserClient : public TestContentBrowserClient { |
| public: |
| - SiteInstanceTestBrowserClient() |
| - : privileged_process_id_(-1) { |
| + explicit SiteInstanceTestBrowserClient() |
| + : privileged_process_id_(-1), |
| + site_instance_delete_count_(0), |
| + browsing_instance_delete_count_(0) { |
| WebUIControllerFactory::RegisterFactory( |
| ContentWebUIControllerFactory::GetInstance()); |
| } |
| @@ -61,10 +62,35 @@ class SiteInstanceTestBrowserClient : public TestContentBrowserClient { |
| privileged_process_id_ = process_id; |
| } |
| + void SiteInstanceDeleting(content::SiteInstance* site_instance) override { |
|
Charlie Reis
2016/04/01 21:50:41
Cool! Nice use of this method, which we didn't ha
ncarter (slow)
2016/04/04 21:47:33
Done.
|
| + site_instance_delete_count_++; |
| + // Infer deletion of the browsing instance. |
| + if (static_cast<SiteInstanceImpl*>(site_instance) |
| + ->browsing_instance_->HasOneRef()) { |
| + browsing_instance_delete_count_++; |
| + } |
| + } |
| + |
| + int GetAndClearSiteInstanceDeleteCount() { |
| + int result = site_instance_delete_count_; |
| + site_instance_delete_count_ = 0; |
| + return result; |
| + } |
| + int GetAndClearBrowsingInstanceDeleteCount() { |
| + int result = browsing_instance_delete_count_; |
| + browsing_instance_delete_count_ = 0; |
| + return result; |
| + } |
| + |
| private: |
| int privileged_process_id_; |
| + |
| + int site_instance_delete_count_; |
| + int browsing_instance_delete_count_; |
| }; |
| +namespace { |
| + |
| class SiteInstanceTest : public testing::Test { |
| public: |
| SiteInstanceTest() |
| @@ -114,6 +140,8 @@ class SiteInstanceTest : public testing::Test { |
| message_loop_.RunUntilIdle(); |
| } |
| + SiteInstanceTestBrowserClient* browser_client() { return &browser_client_; } |
| + |
| private: |
| base::MessageLoopForUI message_loop_; |
| TestBrowserThread ui_thread_; |
| @@ -125,48 +153,6 @@ class SiteInstanceTest : public testing::Test { |
| MockRenderProcessHostFactory rph_factory_; |
| }; |
| -// Subclass of BrowsingInstance that updates a counter when deleted and |
| -// returns TestSiteInstances from GetSiteInstanceForURL. |
| -class TestBrowsingInstance : public BrowsingInstance { |
| - public: |
| - TestBrowsingInstance(BrowserContext* browser_context, int* delete_counter) |
| - : BrowsingInstance(browser_context), |
| - delete_counter_(delete_counter) { |
| - } |
| - |
| - // Make a few methods public for tests. |
| - using BrowsingInstance::browser_context; |
| - using BrowsingInstance::HasSiteInstance; |
| - using BrowsingInstance::GetSiteInstanceForURL; |
| - using BrowsingInstance::RegisterSiteInstance; |
| - using BrowsingInstance::UnregisterSiteInstance; |
| - |
| - private: |
| - ~TestBrowsingInstance() override { (*delete_counter_)++; } |
| - |
| - int* delete_counter_; |
| -}; |
| - |
| -// Subclass of SiteInstanceImpl that updates a counter when deleted. |
| -class TestSiteInstance : public SiteInstanceImpl { |
| - public: |
| - static TestSiteInstance* CreateTestSiteInstance( |
| - BrowserContext* browser_context, |
| - int* site_delete_counter, |
| - int* browsing_delete_counter) { |
| - TestBrowsingInstance* browsing_instance = |
| - new TestBrowsingInstance(browser_context, browsing_delete_counter); |
| - return new TestSiteInstance(browsing_instance, site_delete_counter); |
| - } |
| - |
| - private: |
| - TestSiteInstance(BrowsingInstance* browsing_instance, int* delete_counter) |
| - : SiteInstanceImpl(browsing_instance), delete_counter_(delete_counter) {} |
| - ~TestSiteInstance() override { (*delete_counter_)++; } |
| - |
| - int* delete_counter_; |
| -}; |
| - |
| } // namespace |
| // Test to ensure no memory leaks for SiteInstance objects. |
| @@ -174,15 +160,11 @@ TEST_F(SiteInstanceTest, SiteInstanceDestructor) { |
| // The existence of this object will cause WebContentsImpl to create our |
| // test one instead of the real one. |
| RenderViewHostTestEnabler rvh_test_enabler; |
| - int site_delete_counter = 0; |
| - int browsing_delete_counter = 0; |
| const GURL url("test:foo"); |
| // Ensure that instances are deleted when their NavigationEntries are gone. |
| - TestSiteInstance* instance = |
| - TestSiteInstance::CreateTestSiteInstance(NULL, &site_delete_counter, |
| - &browsing_delete_counter); |
| - EXPECT_EQ(0, site_delete_counter); |
| + scoped_refptr<SiteInstanceImpl> instance = SiteInstanceImpl::Create(NULL); |
|
Charlie Reis
2016/04/01 21:50:41
nit: nullptr while we're at it? (Same below.)
ncarter (slow)
2016/04/04 21:47:33
NULL->nullptr replaced globally in the file.
|
| + EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| NavigationEntryImpl* e1 = new NavigationEntryImpl( |
| instance, 0, url, Referrer(), base::string16(), ui::PAGE_TRANSITION_LINK, |
| @@ -190,43 +172,45 @@ TEST_F(SiteInstanceTest, SiteInstanceDestructor) { |
| // Redundantly setting e1's SiteInstance shouldn't affect the ref count. |
| e1->set_site_instance(instance); |
| - EXPECT_EQ(0, site_delete_counter); |
| + EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| // Add a second reference |
| NavigationEntryImpl* e2 = new NavigationEntryImpl( |
| instance, 0, url, Referrer(), base::string16(), ui::PAGE_TRANSITION_LINK, |
| false); |
| + instance = nullptr; |
| + EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| + |
| // Now delete both entries and be sure the SiteInstance goes away. |
| delete e1; |
| - EXPECT_EQ(0, site_delete_counter); |
| - EXPECT_EQ(0, browsing_delete_counter); |
| + EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| delete e2; |
| - EXPECT_EQ(1, site_delete_counter); |
| // instance is now deleted |
| - EXPECT_EQ(1, browsing_delete_counter); |
| + EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(1, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| // browsing_instance is now deleted |
| // Ensure that instances are deleted when their RenderViewHosts are gone. |
| scoped_ptr<TestBrowserContext> browser_context(new TestBrowserContext()); |
| - instance = |
| - TestSiteInstance::CreateTestSiteInstance(browser_context.get(), |
| - &site_delete_counter, |
| - &browsing_delete_counter); |
| { |
| scoped_ptr<WebContentsImpl> web_contents(static_cast<WebContentsImpl*>( |
| WebContents::Create(WebContents::CreateParams( |
| - browser_context.get(), instance)))); |
| - EXPECT_EQ(1, site_delete_counter); |
| - EXPECT_EQ(1, browsing_delete_counter); |
| + browser_context.get(), |
| + SiteInstance::Create(browser_context.get()))))); |
| + EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| } |
| // Make sure that we flush any messages related to the above WebContentsImpl |
| // destruction. |
| DrainMessageLoops(); |
| - EXPECT_EQ(2, site_delete_counter); |
| - EXPECT_EQ(2, browsing_delete_counter); |
| + EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(1, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| // contents is now deleted, along with instance and browsing_instance |
| } |
| @@ -234,40 +218,31 @@ TEST_F(SiteInstanceTest, SiteInstanceDestructor) { |
| // SiteInstances can be changed afterwards. Also tests that the ref counts are |
| // updated properly after the change. |
| TEST_F(SiteInstanceTest, CloneNavigationEntry) { |
| - int site_delete_counter1 = 0; |
| - int site_delete_counter2 = 0; |
| - int browsing_delete_counter = 0; |
| const GURL url("test:foo"); |
| - SiteInstanceImpl* instance1 = |
| - TestSiteInstance::CreateTestSiteInstance(NULL, &site_delete_counter1, |
| - &browsing_delete_counter); |
| - SiteInstanceImpl* instance2 = |
| - TestSiteInstance::CreateTestSiteInstance(NULL, &site_delete_counter2, |
| - &browsing_delete_counter); |
| - |
| scoped_ptr<NavigationEntryImpl> e1 = make_scoped_ptr(new NavigationEntryImpl( |
| - instance1, 0, url, Referrer(), base::string16(), ui::PAGE_TRANSITION_LINK, |
| - false)); |
| + SiteInstanceImpl::Create(NULL), 0, url, Referrer(), base::string16(), |
| + ui::PAGE_TRANSITION_LINK, false)); |
| + |
| // Clone the entry. |
| scoped_ptr<NavigationEntryImpl> e2 = e1->Clone(); |
| // Should be able to change the SiteInstance of the cloned entry. |
| - e2->set_site_instance(instance2); |
| + e2->set_site_instance(SiteInstanceImpl::Create(NULL)); |
| + |
| + EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| - // The first SiteInstance should go away after resetting e1, since e2 should |
| - // no longer be referencing it. |
| + // The first SiteInstance and BrowsingInstance should go away after resetting |
| + // e1, since e2 should no longer be referencing it. |
| e1.reset(); |
| - EXPECT_EQ(1, site_delete_counter1); |
| - EXPECT_EQ(0, site_delete_counter2); |
| + EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(1, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| // The second SiteInstance should go away after resetting e2. |
| e2.reset(); |
| - EXPECT_EQ(1, site_delete_counter1); |
| - EXPECT_EQ(1, site_delete_counter2); |
| - |
| - // Both BrowsingInstances are also now deleted. |
| - EXPECT_EQ(2, browsing_delete_counter); |
| + EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(1, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| DrainMessageLoops(); |
| } |
| @@ -408,10 +383,9 @@ TEST_F(SiteInstanceTest, IsSameWebSite) { |
| TEST_F(SiteInstanceTest, OneSiteInstancePerSite) { |
| ASSERT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kProcessPerSite)); |
| - int delete_counter = 0; |
| scoped_ptr<TestBrowserContext> browser_context(new TestBrowserContext()); |
| - TestBrowsingInstance* browsing_instance = |
| - new TestBrowsingInstance(browser_context.get(), &delete_counter); |
| + BrowsingInstance* browsing_instance = |
| + new BrowsingInstance(browser_context.get()); |
| const GURL url_a1("http://www.google.com/1.html"); |
| scoped_refptr<SiteInstanceImpl> site_instance_a1( |
| @@ -440,8 +414,8 @@ TEST_F(SiteInstanceTest, OneSiteInstancePerSite) { |
| // A visit to the original site in a new BrowsingInstance (same or different |
| // browser context) should return a different SiteInstance. |
| - TestBrowsingInstance* browsing_instance2 = |
| - new TestBrowsingInstance(browser_context.get(), &delete_counter); |
| + BrowsingInstance* browsing_instance2 = |
| + new BrowsingInstance(browser_context.get()); |
| // Ensure the new SiteInstance is ref counted so that it gets deleted. |
| scoped_refptr<SiteInstanceImpl> site_instance_a2_2( |
| browsing_instance2->GetSiteInstanceForURL(url_a2)); |
| @@ -480,10 +454,9 @@ TEST_F(SiteInstanceTest, OneSiteInstancePerSite) { |
| TEST_F(SiteInstanceTest, OneSiteInstancePerSiteInBrowserContext) { |
| base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| switches::kProcessPerSite); |
| - int delete_counter = 0; |
| scoped_ptr<TestBrowserContext> browser_context(new TestBrowserContext()); |
| - TestBrowsingInstance* browsing_instance = |
| - new TestBrowsingInstance(browser_context.get(), &delete_counter); |
| + scoped_refptr<BrowsingInstance> browsing_instance = |
| + new BrowsingInstance(browser_context.get()); |
| const GURL url_a1("http://www.google.com/1.html"); |
| scoped_refptr<SiteInstanceImpl> site_instance_a1( |
| @@ -512,8 +485,8 @@ TEST_F(SiteInstanceTest, OneSiteInstancePerSiteInBrowserContext) { |
| // A visit to the original site in a new BrowsingInstance (same browser |
| // context) should return a different SiteInstance with the same process. |
| - TestBrowsingInstance* browsing_instance2 = |
| - new TestBrowsingInstance(browser_context.get(), &delete_counter); |
| + BrowsingInstance* browsing_instance2 = |
| + new BrowsingInstance(browser_context.get()); |
| scoped_refptr<SiteInstanceImpl> site_instance_a1_2( |
| browsing_instance2->GetSiteInstanceForURL(url_a1)); |
| EXPECT_TRUE(site_instance_a1.get() != NULL); |
| @@ -523,8 +496,8 @@ TEST_F(SiteInstanceTest, OneSiteInstancePerSiteInBrowserContext) { |
| // A visit to the original site in a new BrowsingInstance (different browser |
| // context) should return a different SiteInstance with a different process. |
| scoped_ptr<TestBrowserContext> browser_context2(new TestBrowserContext()); |
| - TestBrowsingInstance* browsing_instance3 = |
| - new TestBrowsingInstance(browser_context2.get(), &delete_counter); |
| + BrowsingInstance* browsing_instance3 = |
| + new BrowsingInstance(browser_context2.get()); |
| scoped_refptr<SiteInstanceImpl> site_instance_a2_3( |
| browsing_instance3->GetSiteInstanceForURL(url_a2)); |
| EXPECT_TRUE(site_instance_a2_3.get() != NULL); |
| @@ -775,4 +748,50 @@ TEST_F(SiteInstanceTest, NoProcessPerSiteForEmptySite) { |
| DrainMessageLoops(); |
| } |
| +TEST_F(SiteInstanceTest, DefaultSubframeSiteInstance) { |
| + base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| + switches::kTopDocumentIsolation); |
|
Charlie Reis
2016/04/01 21:50:41
Does this need to return early for --site-per-proc
ncarter (slow)
2016/04/04 21:47:33
Good catch. Done.
|
| + |
| + scoped_ptr<TestBrowserContext> browser_context(new TestBrowserContext()); |
| + scoped_refptr<SiteInstanceImpl> main_instance = |
| + SiteInstanceImpl::Create(browser_context.get()); |
| + scoped_refptr<SiteInstanceImpl> subframe_instance = |
| + main_instance->GetDefaultSubframeSiteInstance(); |
| + int subframe_instance_id = subframe_instance->GetId(); |
| + |
| + EXPECT_NE(main_instance, subframe_instance); |
| + EXPECT_EQ(subframe_instance, main_instance->GetDefaultSubframeSiteInstance()); |
| + EXPECT_FALSE(main_instance->is_default_subframe_site_instance()); |
| + EXPECT_TRUE(subframe_instance->is_default_subframe_site_instance()); |
| + |
| + EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| + |
| + // Free the subframe instance. |
| + subframe_instance = nullptr; |
| + EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| + |
| + // Calling GetDefaultSubframeSiteInstance again should return a new |
| + // SiteInstance with a different ID from the original. |
| + subframe_instance = main_instance->GetDefaultSubframeSiteInstance(); |
| + EXPECT_NE(subframe_instance->GetId(), subframe_instance_id); |
| + EXPECT_FALSE(main_instance->is_default_subframe_site_instance()); |
| + EXPECT_TRUE(subframe_instance->is_default_subframe_site_instance()); |
| + EXPECT_EQ(subframe_instance->GetDefaultSubframeSiteInstance(), |
| + subframe_instance); |
| + EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| + |
| + // Free the main instance. |
| + main_instance = nullptr; |
| + EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| + |
| + // Free the subframe instance, which should free the browsing instance. |
| + subframe_instance = nullptr; |
| + EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount()); |
| + EXPECT_EQ(1, browser_client()->GetAndClearBrowsingInstanceDeleteCount()); |
| +} |
| + |
| } // namespace content |