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 { |
Yoyo Zhou
2014/08/01 22:13:09
Thanks for looking at this test - I had gotten a l
| |
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 static MockExtensionSystemFactory* GetInstance() { | |
106 return Singleton<MockExtensionSystemFactory>::get(); | |
107 } | |
108 | |
109 // BrowserContextKeyedServiceFactory overrides: | |
110 virtual KeyedService* BuildServiceInstanceFor( | |
111 BrowserContext* context) const OVERRIDE { | |
112 return new MockExtensionSystem(context); | |
113 } | |
114 | |
115 // ExtensionSystemProvider overrides: | |
116 virtual ExtensionSystem* GetForBrowserContext( | |
117 BrowserContext* context) OVERRIDE { | |
118 return static_cast<MockExtensionSystem*>( | |
119 GetInstance()->GetServiceForBrowserContext(context, true)); | |
120 } | |
121 | |
122 private: | |
123 friend struct DefaultSingletonTraits<MockExtensionSystemFactory>; | |
Yoyo Zhou
2014/08/01 22:13:09
nit: it's more or less equivalent but I prefer Laz
James Cook
2014/08/01 22:48:03
On closer inspection it doesn't need to be a singl
| |
124 | |
125 DISALLOW_COPY_AND_ASSIGN(MockExtensionSystemFactory); | |
126 }; | |
127 | |
128 } // namespace | |
129 | |
130 // Derives from ExtensionsTest to provide content module and keyed service | |
131 // initialization. | |
132 class LazyBackgroundTaskQueueTest : public ExtensionsTest { | |
133 public: | |
134 LazyBackgroundTaskQueueTest() | |
135 : notification_service_(content::NotificationService::Create()), | |
136 task_run_count_(0) { | |
137 extensions_browser_client()->set_extension_system_factory( | |
138 &extension_system_factory_); | |
139 } | |
54 virtual ~LazyBackgroundTaskQueueTest() {} | 140 virtual ~LazyBackgroundTaskQueueTest() {} |
55 | 141 |
56 int task_run_count() { return task_run_count_; } | 142 int task_run_count() { return task_run_count_; } |
57 | 143 |
58 // A simple callback for AddPendingTask. | 144 // A simple callback for AddPendingTask. |
59 void RunPendingTask(ExtensionHost* host) { | 145 void RunPendingTask(ExtensionHost* host) { |
60 task_run_count_++; | 146 task_run_count_++; |
61 } | 147 } |
62 | 148 |
63 // Creates and registers an extension without a background page. | 149 // Creates and registers an extension without a background page. |
64 scoped_refptr<Extension> CreateSimpleExtension() { | 150 scoped_refptr<Extension> CreateSimpleExtension() { |
65 scoped_refptr<Extension> extension = ExtensionBuilder() | 151 scoped_refptr<Extension> extension = ExtensionBuilder() |
66 .SetManifest(DictionaryBuilder() | 152 .SetManifest(DictionaryBuilder() |
67 .Set("name", "No background") | 153 .Set("name", "No background") |
68 .Set("version", "1") | 154 .Set("version", "1") |
69 .Set("manifest_version", 2)) | 155 .Set("manifest_version", 2)) |
70 .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") | 156 .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") |
71 .Build(); | 157 .Build(); |
72 service_->AddExtension(extension); | 158 ExtensionRegistry::Get(browser_context())->AddEnabled(extension); |
73 return extension; | 159 return extension; |
74 } | 160 } |
75 | 161 |
76 // Creates and registers an extension with a lazy background page. | 162 // Creates and registers an extension with a lazy background page. |
77 scoped_refptr<Extension> CreateLazyBackgroundExtension() { | 163 scoped_refptr<Extension> CreateLazyBackgroundExtension() { |
78 scoped_refptr<Extension> extension = ExtensionBuilder() | 164 scoped_refptr<Extension> extension = ExtensionBuilder() |
79 .SetManifest(DictionaryBuilder() | 165 .SetManifest(DictionaryBuilder() |
80 .Set("name", "Lazy background") | 166 .Set("name", "Lazy background") |
81 .Set("version", "1") | 167 .Set("version", "1") |
82 .Set("manifest_version", 2) | 168 .Set("manifest_version", 2) |
83 .Set("background", | 169 .Set("background", |
84 DictionaryBuilder() | 170 DictionaryBuilder() |
85 .Set("page", "background.html") | 171 .Set("page", "background.html") |
86 .SetBoolean("persistent", false))) | 172 .SetBoolean("persistent", false))) |
87 .SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") | 173 .SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") |
88 .Build(); | 174 .Build(); |
89 service_->AddExtension(extension); | 175 ExtensionRegistry::Get(browser_context())->AddEnabled(extension); |
90 return extension; | 176 return extension; |
91 } | 177 } |
92 | 178 |
93 private: | 179 private: |
180 scoped_ptr<content::NotificationService> notification_service_; | |
181 MockExtensionSystemFactory extension_system_factory_; | |
182 | |
94 // The total number of pending tasks that have been executed. | 183 // The total number of pending tasks that have been executed. |
95 int task_run_count_; | 184 int task_run_count_; |
96 | 185 |
97 DISALLOW_COPY_AND_ASSIGN(LazyBackgroundTaskQueueTest); | 186 DISALLOW_COPY_AND_ASSIGN(LazyBackgroundTaskQueueTest); |
98 }; | 187 }; |
99 | 188 |
100 // Tests that only extensions with background pages should have tasks queued. | 189 // Tests that only extensions with background pages should have tasks queued. |
101 TEST_F(LazyBackgroundTaskQueueTest, ShouldEnqueueTask) { | 190 TEST_F(LazyBackgroundTaskQueueTest, ShouldEnqueueTask) { |
102 InitializeEmptyExtensionService(); | 191 LazyBackgroundTaskQueue queue(browser_context()); |
103 InitializeProcessManager(); | |
104 | |
105 LazyBackgroundTaskQueue queue(profile_.get()); | |
106 | 192 |
107 // Build a simple extension with no background page. | 193 // Build a simple extension with no background page. |
108 scoped_refptr<Extension> no_background = CreateSimpleExtension(); | 194 scoped_refptr<Extension> no_background = CreateSimpleExtension(); |
109 EXPECT_FALSE(queue.ShouldEnqueueTask(profile_.get(), no_background.get())); | 195 EXPECT_FALSE(queue.ShouldEnqueueTask(browser_context(), no_background.get())); |
110 | 196 |
111 // Build another extension with a background page. | 197 // Build another extension with a background page. |
112 scoped_refptr<Extension> with_background = CreateLazyBackgroundExtension(); | 198 scoped_refptr<Extension> with_background = CreateLazyBackgroundExtension(); |
113 EXPECT_TRUE(queue.ShouldEnqueueTask(profile_.get(), with_background.get())); | 199 EXPECT_TRUE( |
200 queue.ShouldEnqueueTask(browser_context(), with_background.get())); | |
114 } | 201 } |
115 | 202 |
116 // Tests that adding tasks actually increases the pending task count, and that | 203 // Tests that adding tasks actually increases the pending task count, and that |
117 // multiple extensions can have pending tasks. | 204 // multiple extensions can have pending tasks. |
118 TEST_F(LazyBackgroundTaskQueueTest, AddPendingTask) { | 205 TEST_F(LazyBackgroundTaskQueueTest, AddPendingTask) { |
119 InitializeEmptyExtensionService(); | 206 // Get our TestProcessManager. |
207 MockExtensionSystem* extension_system = static_cast<MockExtensionSystem*>( | |
208 ExtensionSystem::Get(browser_context())); | |
209 TestProcessManager* process_manager = | |
210 static_cast<TestProcessManager*>(extension_system->process_manager()); | |
120 | 211 |
121 // Swap in our stub TestProcessManager. | 212 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 | 213 |
131 // Build a simple extension with no background page. | 214 // Build a simple extension with no background page. |
132 scoped_refptr<Extension> no_background = CreateSimpleExtension(); | 215 scoped_refptr<Extension> no_background = CreateSimpleExtension(); |
133 | 216 |
134 // Adding a pending task increases the number of extensions with tasks, but | 217 // Adding a pending task increases the number of extensions with tasks, but |
135 // doesn't run the task. | 218 // doesn't run the task. |
136 queue.AddPendingTask(profile_.get(), | 219 queue.AddPendingTask(browser_context(), |
137 no_background->id(), | 220 no_background->id(), |
138 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, | 221 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, |
139 base::Unretained(this))); | 222 base::Unretained(this))); |
140 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); | 223 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); |
141 EXPECT_EQ(0, task_run_count()); | 224 EXPECT_EQ(0, task_run_count()); |
142 | 225 |
143 // Another task on the same extension doesn't increase the number of | 226 // Another task on the same extension doesn't increase the number of |
144 // extensions that have tasks and doesn't run any tasks. | 227 // extensions that have tasks and doesn't run any tasks. |
145 queue.AddPendingTask(profile_.get(), | 228 queue.AddPendingTask(browser_context(), |
146 no_background->id(), | 229 no_background->id(), |
147 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, | 230 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, |
148 base::Unretained(this))); | 231 base::Unretained(this))); |
149 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); | 232 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); |
150 EXPECT_EQ(0, task_run_count()); | 233 EXPECT_EQ(0, task_run_count()); |
151 | 234 |
152 // Adding a task on an extension with a lazy background page tries to create | 235 // 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. | 236 // a background host, and if that fails, runs the task immediately. |
154 scoped_refptr<Extension> lazy_background = CreateLazyBackgroundExtension(); | 237 scoped_refptr<Extension> lazy_background = CreateLazyBackgroundExtension(); |
155 queue.AddPendingTask(profile_.get(), | 238 queue.AddPendingTask(browser_context(), |
156 lazy_background->id(), | 239 lazy_background->id(), |
157 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, | 240 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, |
158 base::Unretained(this))); | 241 base::Unretained(this))); |
159 EXPECT_EQ(2u, queue.extensions_with_pending_tasks()); | 242 EXPECT_EQ(2u, queue.extensions_with_pending_tasks()); |
160 // The process manager tried to create a background host. | 243 // The process manager tried to create a background host. |
161 EXPECT_EQ(1, process_manager->create_count()); | 244 EXPECT_EQ(1, process_manager->create_count()); |
162 // The task ran immediately because the creation failed. | 245 // The task ran immediately because the creation failed. |
163 EXPECT_EQ(1, task_run_count()); | 246 EXPECT_EQ(1, task_run_count()); |
164 } | 247 } |
165 | 248 |
166 // Tests that pending tasks are actually run. | 249 // Tests that pending tasks are actually run. |
167 TEST_F(LazyBackgroundTaskQueueTest, ProcessPendingTasks) { | 250 TEST_F(LazyBackgroundTaskQueueTest, ProcessPendingTasks) { |
168 InitializeEmptyExtensionService(); | 251 LazyBackgroundTaskQueue queue(browser_context()); |
169 | |
170 LazyBackgroundTaskQueue queue(profile_.get()); | |
171 | 252 |
172 // ProcessPendingTasks is a no-op if there are no tasks. | 253 // ProcessPendingTasks is a no-op if there are no tasks. |
173 scoped_refptr<Extension> extension = CreateSimpleExtension(); | 254 scoped_refptr<Extension> extension = CreateSimpleExtension(); |
174 queue.ProcessPendingTasks(NULL, profile_.get(), extension); | 255 queue.ProcessPendingTasks(NULL, browser_context(), extension); |
175 EXPECT_EQ(0, task_run_count()); | 256 EXPECT_EQ(0, task_run_count()); |
176 | 257 |
177 // Schedule a task to run. | 258 // Schedule a task to run. |
178 queue.AddPendingTask(profile_.get(), | 259 queue.AddPendingTask(browser_context(), |
179 extension->id(), | 260 extension->id(), |
180 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, | 261 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask, |
181 base::Unretained(this))); | 262 base::Unretained(this))); |
182 EXPECT_EQ(0, task_run_count()); | 263 EXPECT_EQ(0, task_run_count()); |
183 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); | 264 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); |
184 | 265 |
185 // Trying to run tasks for an unrelated profile should do nothing. | 266 // Trying to run tasks for an unrelated BrowserContext should do nothing. |
186 TestingProfile profile2; | 267 content::TestBrowserContext unrelated_context; |
187 queue.ProcessPendingTasks(NULL, &profile2, extension); | 268 queue.ProcessPendingTasks(NULL, &unrelated_context, extension); |
188 EXPECT_EQ(0, task_run_count()); | 269 EXPECT_EQ(0, task_run_count()); |
189 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); | 270 EXPECT_EQ(1u, queue.extensions_with_pending_tasks()); |
190 | 271 |
191 // Processing tasks when there is one pending runs the task and removes the | 272 // Processing tasks when there is one pending runs the task and removes the |
192 // extension from the list of extensions with pending tasks. | 273 // extension from the list of extensions with pending tasks. |
193 queue.ProcessPendingTasks(NULL, profile_.get(), extension); | 274 queue.ProcessPendingTasks(NULL, browser_context(), extension); |
194 EXPECT_EQ(1, task_run_count()); | 275 EXPECT_EQ(1, task_run_count()); |
195 EXPECT_EQ(0u, queue.extensions_with_pending_tasks()); | 276 EXPECT_EQ(0u, queue.extensions_with_pending_tasks()); |
196 } | 277 } |
197 | 278 |
198 } // namespace extensions | 279 } // namespace extensions |
OLD | NEW |