OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "extensions/browser/lazy_background_task_queue.h" | 5 #include "extensions/browser/lazy_background_task_queue.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "components/keyed_service/content/browser_context_dependency_manager.h" |
9 #include "chrome/browser/extensions/extension_service.h" | 9 #include "content/public/browser/notification_service.h" |
10 #include "chrome/browser/extensions/extension_service_test_base.h" | 10 #include "content/public/test/test_browser_context.h" |
11 #include "chrome/browser/extensions/test_extension_system.h" | |
12 #include "chrome/test/base/testing_profile.h" | |
13 #include "content/public/test/test_browser_thread_bundle.h" | |
14 #include "extensions/browser/extension_registry.h" | 11 #include "extensions/browser/extension_registry.h" |
| 12 #include "extensions/browser/extension_registry_factory.h" |
| 13 #include "extensions/browser/extension_system.h" |
| 14 #include "extensions/browser/extension_system_provider.h" |
| 15 #include "extensions/browser/extensions_test.h" |
15 #include "extensions/browser/process_manager.h" | 16 #include "extensions/browser/process_manager.h" |
| 17 #include "extensions/browser/test_extensions_browser_client.h" |
16 #include "extensions/common/extension.h" | 18 #include "extensions/common/extension.h" |
17 #include "extensions/common/extension_builder.h" | 19 #include "extensions/common/extension_builder.h" |
| 20 #include "extensions/common/one_shot_event.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
19 | 22 |
| 23 using content::BrowserContext; |
| 24 |
20 namespace extensions { | 25 namespace extensions { |
| 26 namespace { |
21 | 27 |
22 // A ProcessManager that doesn't create background host pages. | 28 // A ProcessManager that doesn't create background host pages. |
23 class TestProcessManager : public ProcessManager { | 29 class TestProcessManager : public ProcessManager { |
24 public: | 30 public: |
25 explicit TestProcessManager(Profile* profile) | 31 explicit TestProcessManager(BrowserContext* context) |
26 : ProcessManager(profile, | 32 : ProcessManager(context, context, ExtensionRegistry::Get(context)), |
27 profile->GetOriginalProfile(), | 33 create_count_(0) { |
28 ExtensionRegistry::Get(profile)), | 34 // ProcessManager constructor above assumes non-incognito. |
29 create_count_(0) {} | 35 DCHECK(!context->IsOffTheRecord()); |
| 36 } |
30 virtual ~TestProcessManager() {} | 37 virtual ~TestProcessManager() {} |
31 | 38 |
32 int create_count() { return create_count_; } | 39 int create_count() { return create_count_; } |
33 | 40 |
34 // ProcessManager overrides: | 41 // ProcessManager overrides: |
35 virtual bool CreateBackgroundHost(const Extension* extension, | 42 virtual bool CreateBackgroundHost(const Extension* extension, |
36 const GURL& url) OVERRIDE { | 43 const GURL& url) OVERRIDE { |
37 // Don't actually try to create a web contents. | 44 // Don't actually try to create a web contents. |
38 create_count_++; | 45 create_count_++; |
39 return false; | 46 return false; |
40 } | 47 } |
41 | 48 |
42 private: | 49 private: |
43 int create_count_; | 50 int create_count_; |
44 | 51 |
45 DISALLOW_COPY_AND_ASSIGN(TestProcessManager); | 52 DISALLOW_COPY_AND_ASSIGN(TestProcessManager); |
46 }; | 53 }; |
47 | 54 |
48 // Derives from ExtensionServiceTestBase because ExtensionService is difficult | 55 // A simple ExtensionSystem that returns a TestProcessManager. |
49 // to initialize alone. | 56 class MockExtensionSystem : public ExtensionSystem { |
50 class LazyBackgroundTaskQueueTest | |
51 : public extensions::ExtensionServiceTestBase { | |
52 public: | 57 public: |
53 LazyBackgroundTaskQueueTest() : task_run_count_(0) {} | 58 explicit MockExtensionSystem(BrowserContext* context) |
| 59 : test_process_manager_(context) {} |
| 60 virtual ~MockExtensionSystem() {} |
| 61 |
| 62 virtual void InitForRegularProfile(bool extensions_enabled) OVERRIDE {} |
| 63 virtual ExtensionService* extension_service() OVERRIDE { return NULL; } |
| 64 virtual RuntimeData* runtime_data() OVERRIDE { return NULL; } |
| 65 virtual ManagementPolicy* management_policy() OVERRIDE { return NULL; } |
| 66 virtual UserScriptMaster* user_script_master() OVERRIDE { return NULL; } |
| 67 virtual ProcessManager* process_manager() OVERRIDE { |
| 68 return &test_process_manager_; |
| 69 } |
| 70 virtual StateStore* state_store() OVERRIDE { return NULL; } |
| 71 virtual StateStore* rules_store() OVERRIDE { return NULL; } |
| 72 virtual InfoMap* info_map() OVERRIDE { return NULL; } |
| 73 virtual LazyBackgroundTaskQueue* lazy_background_task_queue() OVERRIDE { |
| 74 return NULL; |
| 75 } |
| 76 virtual EventRouter* event_router() OVERRIDE { return NULL; } |
| 77 virtual ExtensionWarningService* warning_service() OVERRIDE { return NULL; } |
| 78 virtual Blacklist* blacklist() OVERRIDE { return NULL; } |
| 79 virtual ErrorConsole* error_console() OVERRIDE { return NULL; } |
| 80 virtual InstallVerifier* install_verifier() OVERRIDE { return NULL; } |
| 81 virtual QuotaService* quota_service() OVERRIDE { return NULL; } |
| 82 virtual const OneShotEvent& ready() const OVERRIDE { return ready_; } |
| 83 virtual ContentVerifier* content_verifier() OVERRIDE { return NULL; } |
| 84 virtual scoped_ptr<ExtensionSet> GetDependentExtensions( |
| 85 const Extension* extension) OVERRIDE { |
| 86 return scoped_ptr<ExtensionSet>(); |
| 87 } |
| 88 |
| 89 private: |
| 90 TestProcessManager test_process_manager_; |
| 91 OneShotEvent ready_; |
| 92 }; |
| 93 |
| 94 // A factory to create a MockExtensionSystem. |
| 95 class MockExtensionSystemFactory : public ExtensionSystemProvider { |
| 96 public: |
| 97 MockExtensionSystemFactory() |
| 98 : ExtensionSystemProvider( |
| 99 "MockExtensionSystem", |
| 100 BrowserContextDependencyManager::GetInstance()) { |
| 101 DependsOn(ExtensionRegistryFactory::GetInstance()); |
| 102 } |
| 103 virtual ~MockExtensionSystemFactory() {} |
| 104 |
| 105 // BrowserContextKeyedServiceFactory overrides: |
| 106 virtual KeyedService* BuildServiceInstanceFor( |
| 107 BrowserContext* context) const OVERRIDE { |
| 108 return new MockExtensionSystem(context); |
| 109 } |
| 110 |
| 111 // ExtensionSystemProvider overrides: |
| 112 virtual ExtensionSystem* GetForBrowserContext( |
| 113 BrowserContext* context) OVERRIDE { |
| 114 return static_cast<MockExtensionSystem*>( |
| 115 GetServiceForBrowserContext(context, true)); |
| 116 } |
| 117 |
| 118 private: |
| 119 DISALLOW_COPY_AND_ASSIGN(MockExtensionSystemFactory); |
| 120 }; |
| 121 |
| 122 } // namespace |
| 123 |
| 124 // Derives from ExtensionsTest to provide content module and keyed service |
| 125 // initialization. |
| 126 class LazyBackgroundTaskQueueTest : public ExtensionsTest { |
| 127 public: |
| 128 LazyBackgroundTaskQueueTest() |
| 129 : notification_service_(content::NotificationService::Create()), |
| 130 task_run_count_(0) { |
| 131 extensions_browser_client()->set_extension_system_factory( |
| 132 &extension_system_factory_); |
| 133 } |
54 virtual ~LazyBackgroundTaskQueueTest() {} | 134 virtual ~LazyBackgroundTaskQueueTest() {} |
55 | 135 |
56 int task_run_count() { return task_run_count_; } | 136 int task_run_count() { return task_run_count_; } |
57 | 137 |
58 // A simple callback for AddPendingTask. | 138 // A simple callback for AddPendingTask. |
59 void RunPendingTask(ExtensionHost* host) { | 139 void RunPendingTask(ExtensionHost* host) { |
60 task_run_count_++; | 140 task_run_count_++; |
61 } | 141 } |
62 | 142 |
63 // Creates and registers an extension without a background page. | 143 // Creates and registers an extension without a background page. |
64 scoped_refptr<Extension> CreateSimpleExtension() { | 144 scoped_refptr<Extension> CreateSimpleExtension() { |
65 scoped_refptr<Extension> extension = ExtensionBuilder() | 145 scoped_refptr<Extension> extension = ExtensionBuilder() |
66 .SetManifest(DictionaryBuilder() | 146 .SetManifest(DictionaryBuilder() |
67 .Set("name", "No background") | 147 .Set("name", "No background") |
68 .Set("version", "1") | 148 .Set("version", "1") |
69 .Set("manifest_version", 2)) | 149 .Set("manifest_version", 2)) |
70 .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") | 150 .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") |
71 .Build(); | 151 .Build(); |
72 service_->AddExtension(extension); | 152 ExtensionRegistry::Get(browser_context())->AddEnabled(extension); |
73 return extension; | 153 return extension; |
74 } | 154 } |
75 | 155 |
76 // Creates and registers an extension with a lazy background page. | 156 // Creates and registers an extension with a lazy background page. |
77 scoped_refptr<Extension> CreateLazyBackgroundExtension() { | 157 scoped_refptr<Extension> CreateLazyBackgroundExtension() { |
78 scoped_refptr<Extension> extension = ExtensionBuilder() | 158 scoped_refptr<Extension> extension = ExtensionBuilder() |
79 .SetManifest(DictionaryBuilder() | 159 .SetManifest(DictionaryBuilder() |
80 .Set("name", "Lazy background") | 160 .Set("name", "Lazy background") |
81 .Set("version", "1") | 161 .Set("version", "1") |
82 .Set("manifest_version", 2) | 162 .Set("manifest_version", 2) |
83 .Set("background", | 163 .Set("background", |
84 DictionaryBuilder() | 164 DictionaryBuilder() |
85 .Set("page", "background.html") | 165 .Set("page", "background.html") |
86 .SetBoolean("persistent", false))) | 166 .SetBoolean("persistent", false))) |
87 .SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") | 167 .SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") |
88 .Build(); | 168 .Build(); |
89 service_->AddExtension(extension); | 169 ExtensionRegistry::Get(browser_context())->AddEnabled(extension); |
90 return extension; | 170 return extension; |
91 } | 171 } |
92 | 172 |
93 private: | 173 private: |
| 174 scoped_ptr<content::NotificationService> notification_service_; |
| 175 MockExtensionSystemFactory extension_system_factory_; |
| 176 |
94 // The total number of pending tasks that have been executed. | 177 // The total number of pending tasks that have been executed. |
95 int task_run_count_; | 178 int task_run_count_; |
96 | 179 |
97 DISALLOW_COPY_AND_ASSIGN(LazyBackgroundTaskQueueTest); | 180 DISALLOW_COPY_AND_ASSIGN(LazyBackgroundTaskQueueTest); |
98 }; | 181 }; |
99 | 182 |
100 // Tests that only extensions with background pages should have tasks queued. | 183 // Tests that only extensions with background pages should have tasks queued. |
101 TEST_F(LazyBackgroundTaskQueueTest, ShouldEnqueueTask) { | 184 TEST_F(LazyBackgroundTaskQueueTest, ShouldEnqueueTask) { |
102 InitializeEmptyExtensionService(); | 185 LazyBackgroundTaskQueue queue(browser_context()); |
103 InitializeProcessManager(); | |
104 | |
105 LazyBackgroundTaskQueue queue(profile_.get()); | |
106 | 186 |
107 // Build a simple extension with no background page. | 187 // Build a simple extension with no background page. |
108 scoped_refptr<Extension> no_background = CreateSimpleExtension(); | 188 scoped_refptr<Extension> no_background = CreateSimpleExtension(); |
109 EXPECT_FALSE(queue.ShouldEnqueueTask(profile_.get(), no_background.get())); | 189 EXPECT_FALSE(queue.ShouldEnqueueTask(browser_context(), no_background.get())); |
110 | 190 |
111 // Build another extension with a background page. | 191 // Build another extension with a background page. |
112 scoped_refptr<Extension> with_background = CreateLazyBackgroundExtension(); | 192 scoped_refptr<Extension> with_background = CreateLazyBackgroundExtension(); |
113 EXPECT_TRUE(queue.ShouldEnqueueTask(profile_.get(), with_background.get())); | 193 EXPECT_TRUE( |
| 194 queue.ShouldEnqueueTask(browser_context(), with_background.get())); |
114 } | 195 } |
115 | 196 |
116 // Tests that adding tasks actually increases the pending task count, and that | 197 // Tests that adding tasks actually increases the pending task count, and that |
117 // multiple extensions can have pending tasks. | 198 // multiple extensions can have pending tasks. |
118 TEST_F(LazyBackgroundTaskQueueTest, AddPendingTask) { | 199 TEST_F(LazyBackgroundTaskQueueTest, AddPendingTask) { |
119 InitializeEmptyExtensionService(); | 200 // Get our TestProcessManager. |
| 201 MockExtensionSystem* extension_system = static_cast<MockExtensionSystem*>( |
| 202 ExtensionSystem::Get(browser_context())); |
| 203 TestProcessManager* process_manager = |
| 204 static_cast<TestProcessManager*>(extension_system->process_manager()); |
120 | 205 |
121 // Swap in our stub TestProcessManager. | 206 LazyBackgroundTaskQueue queue(browser_context()); |
122 TestExtensionSystem* extension_system = | |
123 static_cast<extensions::TestExtensionSystem*>( | |
124 ExtensionSystem::Get(profile_.get())); | |
125 // Owned by |extension_system|. | |
126 TestProcessManager* process_manager = new TestProcessManager(profile_.get()); | |
127 extension_system->SetProcessManager(process_manager); | |
128 | |
129 LazyBackgroundTaskQueue queue(profile_.get()); | |
130 | 207 |
131 // Build a simple extension with no background page. | 208 // Build a simple extension with no background page. |
132 scoped_refptr<Extension> no_background = CreateSimpleExtension(); | 209 scoped_refptr<Extension> no_background = CreateSimpleExtension(); |
133 | 210 |
134 // Adding a pending task increases the number of extensions with tasks, but | 211 // Adding a pending task increases the number of extensions with tasks, but |
135 // doesn't run the task. | 212 // doesn't run the task. |
136 queue.AddPendingTask(profile_.get(), | 213 queue.AddPendingTask(browser_context(), |
137 no_background->id(), | 214 no_background->id(), |
138 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, | 215 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, |
139 base::Unretained(this))); | 216 base::Unretained(this))); |
140 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); | 217 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); |
141 EXPECT_EQ(0, task_run_count()); | 218 EXPECT_EQ(0, task_run_count()); |
142 | 219 |
143 // Another task on the same extension doesn't increase the number of | 220 // Another task on the same extension doesn't increase the number of |
144 // extensions that have tasks and doesn't run any tasks. | 221 // extensions that have tasks and doesn't run any tasks. |
145 queue.AddPendingTask(profile_.get(), | 222 queue.AddPendingTask(browser_context(), |
146 no_background->id(), | 223 no_background->id(), |
147 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, | 224 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, |
148 base::Unretained(this))); | 225 base::Unretained(this))); |
149 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); | 226 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); |
150 EXPECT_EQ(0, task_run_count()); | 227 EXPECT_EQ(0, task_run_count()); |
151 | 228 |
152 // Adding a task on an extension with a lazy background page tries to create | 229 // Adding a task on an extension with a lazy background page tries to create |
153 // a background host, and if that fails, runs the task immediately. | 230 // a background host, and if that fails, runs the task immediately. |
154 scoped_refptr<Extension> lazy_background = CreateLazyBackgroundExtension(); | 231 scoped_refptr<Extension> lazy_background = CreateLazyBackgroundExtension(); |
155 queue.AddPendingTask(profile_.get(), | 232 queue.AddPendingTask(browser_context(), |
156 lazy_background->id(), | 233 lazy_background->id(), |
157 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, | 234 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, |
158 base::Unretained(this))); | 235 base::Unretained(this))); |
159 EXPECT_EQ(2u, queue.extensions_with_pending_tasks()); | 236 EXPECT_EQ(2u, queue.extensions_with_pending_tasks()); |
160 // The process manager tried to create a background host. | 237 // The process manager tried to create a background host. |
161 EXPECT_EQ(1, process_manager->create_count()); | 238 EXPECT_EQ(1, process_manager->create_count()); |
162 // The task ran immediately because the creation failed. | 239 // The task ran immediately because the creation failed. |
163 EXPECT_EQ(1, task_run_count()); | 240 EXPECT_EQ(1, task_run_count()); |
164 } | 241 } |
165 | 242 |
166 // Tests that pending tasks are actually run. | 243 // Tests that pending tasks are actually run. |
167 TEST_F(LazyBackgroundTaskQueueTest, ProcessPendingTasks) { | 244 TEST_F(LazyBackgroundTaskQueueTest, ProcessPendingTasks) { |
168 InitializeEmptyExtensionService(); | 245 LazyBackgroundTaskQueue queue(browser_context()); |
169 | |
170 LazyBackgroundTaskQueue queue(profile_.get()); | |
171 | 246 |
172 // ProcessPendingTasks is a no-op if there are no tasks. | 247 // ProcessPendingTasks is a no-op if there are no tasks. |
173 scoped_refptr<Extension> extension = CreateSimpleExtension(); | 248 scoped_refptr<Extension> extension = CreateSimpleExtension(); |
174 queue.ProcessPendingTasks(NULL, profile_.get(), extension); | 249 queue.ProcessPendingTasks(NULL, browser_context(), extension); |
175 EXPECT_EQ(0, task_run_count()); | 250 EXPECT_EQ(0, task_run_count()); |
176 | 251 |
177 // Schedule a task to run. | 252 // Schedule a task to run. |
178 queue.AddPendingTask(profile_.get(), | 253 queue.AddPendingTask(browser_context(), |
179 extension->id(), | 254 extension->id(), |
180 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, | 255 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, |
181 base::Unretained(this))); | 256 base::Unretained(this))); |
182 EXPECT_EQ(0, task_run_count()); | 257 EXPECT_EQ(0, task_run_count()); |
183 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); | 258 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); |
184 | 259 |
185 // Trying to run tasks for an unrelated profile should do nothing. | 260 // Trying to run tasks for an unrelated BrowserContext should do nothing. |
186 TestingProfile profile2; | 261 content::TestBrowserContext unrelated_context; |
187 queue.ProcessPendingTasks(NULL, &profile2, extension); | 262 queue.ProcessPendingTasks(NULL, &unrelated_context, extension); |
188 EXPECT_EQ(0, task_run_count()); | 263 EXPECT_EQ(0, task_run_count()); |
189 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); | 264 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); |
190 | 265 |
191 // Processing tasks when there is one pending runs the task and removes the | 266 // Processing tasks when there is one pending runs the task and removes the |
192 // extension from the list of extensions with pending tasks. | 267 // extension from the list of extensions with pending tasks. |
193 queue.ProcessPendingTasks(NULL, profile_.get(), extension); | 268 queue.ProcessPendingTasks(NULL, browser_context(), extension); |
194 EXPECT_EQ(1, task_run_count()); | 269 EXPECT_EQ(1, task_run_count()); |
195 EXPECT_EQ(0u, queue.extensions_with_pending_tasks()); | 270 EXPECT_EQ(0u, queue.extensions_with_pending_tasks()); |
196 } | 271 } |
197 | 272 |
198 } // namespace extensions | 273 } // namespace extensions |
OLD | NEW |