1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "extensions/browser/process_manager.h" 6 7 #include "chrome/browser/chrome_notification_types.h" 8 #include "chrome/browser/extensions/extension_error_reporter.h" 9 #include "chrome/test/base/testing_profile.h" 10 #include "content/public/browser/notification_service.h" 11 #include "content/public/browser/render_process_host.h" 12 #include "content/public/browser/site_instance.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/platform_test.h" 15 16 using content::SiteInstance; 17 18 namespace extensions { 19 20 // TODO(jamescook): Convert this from TestingProfile to TestBrowserContext and 21 // move to extensions/browser. This is dependent on ExtensionPrefs being 22 // converted and ExtensionSystem being converted or eliminated. 23 // http://crbug.com/315855 24 25 // make the test a PlatformTest to setup autorelease pools properly on mac 26 class ProcessManagerTest : public testing::Test { 27 public: 28 static void SetUpTestCase() { 29 ExtensionErrorReporter::Init(false); // no noisy errors 30 } 31 32 virtual void SetUp() { 33 ExtensionErrorReporter::GetInstance()->ClearErrors(); 34 } 35 36 // Returns true if the notification |type| is registered for |manager| with 37 // source |profile|. Pass NULL for |profile| for all sources. 38 static bool IsRegistered(ProcessManager* manager, 39 int type, 40 TestingProfile* profile) { 41 return manager->registrar_.IsRegistered( 42 manager, type, content::Source<Profile>(profile)); 43 } 44 }; 45 46 // Test that notification registration works properly. 47 TEST_F(ProcessManagerTest, ExtensionNotificationRegistration) { 48 // Test for a normal profile. 49 scoped_ptr<TestingProfile> original_profile(new TestingProfile); 50 scoped_ptr<ProcessManager> manager1( 51 ProcessManager::Create(original_profile.get())); 52 53 EXPECT_EQ(original_profile.get(), manager1->GetBrowserContext()); 54 EXPECT_EQ(0u, manager1->background_hosts().size()); 55 56 // It observes other notifications from this profile. 57 EXPECT_TRUE(IsRegistered(manager1.get(), 58 chrome::NOTIFICATION_EXTENSIONS_READY, 59 original_profile.get())); 60 EXPECT_TRUE(IsRegistered(manager1.get(), 61 chrome::NOTIFICATION_EXTENSION_LOADED, 62 original_profile.get())); 63 EXPECT_TRUE(IsRegistered(manager1.get(), 64 chrome::NOTIFICATION_EXTENSION_UNLOADED, 65 original_profile.get())); 66 EXPECT_TRUE(IsRegistered(manager1.get(), 67 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, 68 original_profile.get())); 69 70 // Now add an incognito profile associated with the master above. 71 TestingProfile::Builder builder; 72 builder.SetIncognito(); 73 scoped_ptr<TestingProfile> incognito_profile = builder.Build(); 74 incognito_profile->SetOriginalProfile(original_profile.get()); 75 scoped_ptr<ProcessManager> manager2( 76 ProcessManager::Create(incognito_profile.get())); 77 78 EXPECT_EQ(incognito_profile.get(), manager2->GetBrowserContext()); 79 EXPECT_EQ(0u, manager2->background_hosts().size()); 80 81 // Some notifications are observed for the original profile. 82 EXPECT_TRUE(IsRegistered(manager2.get(), 83 chrome::NOTIFICATION_EXTENSION_LOADED, 84 original_profile.get())); 85 86 // Some notifications are observed for the incognito profile. 87 EXPECT_TRUE(IsRegistered(manager2.get(), 88 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, 89 incognito_profile.get())); 90 91 // Some notifications are observed for both incognito and original. 92 EXPECT_TRUE(IsRegistered(manager2.get(), 93 chrome::NOTIFICATION_PROFILE_DESTROYED, 94 original_profile.get())); 95 EXPECT_TRUE(IsRegistered(manager2.get(), 96 chrome::NOTIFICATION_PROFILE_DESTROYED, 97 incognito_profile.get())); 98 99 // Some are not observed at all. 100 EXPECT_FALSE(IsRegistered(manager2.get(), 101 chrome::NOTIFICATION_EXTENSIONS_READY, 102 original_profile.get())); 103 104 // This notification is observed for incognito profiles only. 105 EXPECT_TRUE(IsRegistered(manager2.get(), 106 chrome::NOTIFICATION_PROFILE_DESTROYED, 107 incognito_profile.get())); 108 } 109 110 // Test that extensions get grouped in the right SiteInstance (and therefore 111 // process) based on their URLs. 112 TEST_F(ProcessManagerTest, ProcessGrouping) { 113 // Extensions in different profiles should always be different SiteInstances. 114 // Note: we don't initialize these, since we're not testing that 115 // functionality. This means we can get away with a NULL UserScriptMaster. 116 TestingProfile profile1; 117 scoped_ptr<ProcessManager> manager1(ProcessManager::Create(&profile1)); 118 119 TestingProfile profile2; 120 scoped_ptr<ProcessManager> manager2(ProcessManager::Create(&profile2)); 121 122 // Extensions with common origins ("scheme://id/") should be grouped in the 123 // same SiteInstance. 124 GURL ext1_url1("chrome-extension://ext1_id/index.html"); 125 GURL ext1_url2("chrome-extension://ext1_id/monkey/monkey.html"); 126 GURL ext2_url1("chrome-extension://ext2_id/index.html"); 127 128 scoped_refptr<SiteInstance> site11 = 129 manager1->GetSiteInstanceForURL(ext1_url1); 130 scoped_refptr<SiteInstance> site12 = 131 manager1->GetSiteInstanceForURL(ext1_url2); 132 EXPECT_EQ(site11, site12); 133 134 scoped_refptr<SiteInstance> site21 = 135 manager1->GetSiteInstanceForURL(ext2_url1); 136 EXPECT_NE(site11, site21); 137 138 scoped_refptr<SiteInstance> other_profile_site = 139 manager2->GetSiteInstanceForURL(ext1_url1); 140 EXPECT_NE(site11, other_profile_site); 141 } 142 143 } // namespace extensions 144