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.
5 #include "extensions/browser/lazy_background_task_queue.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/prefs/testing_pref_service.h"
10 #include "components/keyed_service/content/browser_context_dependency_manager.h"
11 #include "components/user_prefs/user_prefs.h"
12 #include "content/public/browser/notification_service.h"
13 #include "content/public/test/test_browser_context.h"
14 #include "extensions/browser/extension_registry.h"
15 #include "extensions/browser/extension_registry_factory.h"
16 #include "extensions/browser/extensions_test.h"
17 #include "extensions/browser/process_manager.h"
18 #include "extensions/browser/process_manager_factory.h"
19 #include "extensions/browser/test_extensions_browser_client.h"
20 #include "extensions/common/extension.h"
21 #include "extensions/common/extension_builder.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 using content::BrowserContext
;
26 namespace extensions
{
29 // A ProcessManager that doesn't create background host pages.
30 class TestProcessManager
: public ProcessManager
{
32 explicit TestProcessManager(BrowserContext
* context
)
33 : ProcessManager(context
, context
, ExtensionRegistry::Get(context
)),
35 // ProcessManager constructor above assumes non-incognito.
36 DCHECK(!context
->IsOffTheRecord());
38 ~TestProcessManager() override
{}
40 int create_count() { return create_count_
; }
42 // ProcessManager overrides:
43 bool CreateBackgroundHost(const Extension
* extension
,
44 const GURL
& url
) override
{
45 // Don't actually try to create a web contents.
53 DISALLOW_COPY_AND_ASSIGN(TestProcessManager
);
56 scoped_ptr
<KeyedService
> CreateTestProcessManager(BrowserContext
* context
) {
57 return make_scoped_ptr(new TestProcessManager(context
));
62 // Derives from ExtensionsTest to provide content module and keyed service
64 class LazyBackgroundTaskQueueTest
: public ExtensionsTest
{
66 LazyBackgroundTaskQueueTest()
67 : notification_service_(content::NotificationService::Create()),
70 ~LazyBackgroundTaskQueueTest() override
{}
72 int task_run_count() { return task_run_count_
; }
74 // A simple callback for AddPendingTask.
75 void RunPendingTask(ExtensionHost
* host
) {
79 // Creates and registers an extension without a background page.
80 scoped_refptr
<Extension
> CreateSimpleExtension() {
81 scoped_refptr
<Extension
> extension
= ExtensionBuilder()
82 .SetManifest(DictionaryBuilder()
83 .Set("name", "No background")
85 .Set("manifest_version", 2))
86 .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
88 ExtensionRegistry::Get(browser_context())->AddEnabled(extension
);
92 // Creates and registers an extension with a lazy background page.
93 scoped_refptr
<Extension
> CreateLazyBackgroundExtension() {
94 scoped_refptr
<Extension
> extension
= ExtensionBuilder()
95 .SetManifest(DictionaryBuilder()
96 .Set("name", "Lazy background")
98 .Set("manifest_version", 2)
101 .Set("page", "background.html")
102 .SetBoolean("persistent", false)))
103 .SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
105 ExtensionRegistry::Get(browser_context())->AddEnabled(extension
);
110 void SetUp() override
{
111 user_prefs::UserPrefs::Set(browser_context(), &testing_pref_service_
);
115 scoped_ptr
<content::NotificationService
> notification_service_
;
117 TestingPrefServiceSimple testing_pref_service_
;
119 // The total number of pending tasks that have been executed.
122 DISALLOW_COPY_AND_ASSIGN(LazyBackgroundTaskQueueTest
);
125 // Tests that only extensions with background pages should have tasks queued.
126 TEST_F(LazyBackgroundTaskQueueTest
, ShouldEnqueueTask
) {
127 LazyBackgroundTaskQueue
queue(browser_context());
129 // Build a simple extension with no background page.
130 scoped_refptr
<Extension
> no_background
= CreateSimpleExtension();
131 EXPECT_FALSE(queue
.ShouldEnqueueTask(browser_context(), no_background
.get()));
133 // Build another extension with a background page.
134 scoped_refptr
<Extension
> with_background
= CreateLazyBackgroundExtension();
136 queue
.ShouldEnqueueTask(browser_context(), with_background
.get()));
139 // Tests that adding tasks actually increases the pending task count, and that
140 // multiple extensions can have pending tasks.
141 TEST_F(LazyBackgroundTaskQueueTest
, AddPendingTask
) {
142 // Get our TestProcessManager.
143 TestProcessManager
* process_manager
= static_cast<TestProcessManager
*>(
144 ProcessManagerFactory::GetInstance()->SetTestingFactoryAndUse(
145 browser_context(), CreateTestProcessManager
));
147 LazyBackgroundTaskQueue
queue(browser_context());
149 // Build a simple extension with no background page.
150 scoped_refptr
<Extension
> no_background
= CreateSimpleExtension();
152 // Adding a pending task increases the number of extensions with tasks, but
153 // doesn't run the task.
154 queue
.AddPendingTask(browser_context(),
156 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask
,
157 base::Unretained(this)));
158 EXPECT_EQ(1u, queue
.extensions_with_pending_tasks());
159 EXPECT_EQ(0, task_run_count());
161 // Another task on the same extension doesn't increase the number of
162 // extensions that have tasks and doesn't run any tasks.
163 queue
.AddPendingTask(browser_context(),
165 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask
,
166 base::Unretained(this)));
167 EXPECT_EQ(1u, queue
.extensions_with_pending_tasks());
168 EXPECT_EQ(0, task_run_count());
170 // Adding a task on an extension with a lazy background page tries to create
171 // a background host, and if that fails, runs the task immediately.
172 scoped_refptr
<Extension
> lazy_background
= CreateLazyBackgroundExtension();
173 queue
.AddPendingTask(browser_context(),
174 lazy_background
->id(),
175 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask
,
176 base::Unretained(this)));
177 EXPECT_EQ(2u, queue
.extensions_with_pending_tasks());
178 // The process manager tried to create a background host.
179 EXPECT_EQ(1, process_manager
->create_count());
180 // The task ran immediately because the creation failed.
181 EXPECT_EQ(1, task_run_count());
184 // Tests that pending tasks are actually run.
185 TEST_F(LazyBackgroundTaskQueueTest
, ProcessPendingTasks
) {
186 LazyBackgroundTaskQueue
queue(browser_context());
188 // ProcessPendingTasks is a no-op if there are no tasks.
189 scoped_refptr
<Extension
> extension
= CreateSimpleExtension();
190 queue
.ProcessPendingTasks(NULL
, browser_context(), extension
.get());
191 EXPECT_EQ(0, task_run_count());
193 // Schedule a task to run.
194 queue
.AddPendingTask(browser_context(),
196 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask
,
197 base::Unretained(this)));
198 EXPECT_EQ(0, task_run_count());
199 EXPECT_EQ(1u, queue
.extensions_with_pending_tasks());
201 // Trying to run tasks for an unrelated BrowserContext should do nothing.
202 content::TestBrowserContext unrelated_context
;
203 queue
.ProcessPendingTasks(NULL
, &unrelated_context
, extension
.get());
204 EXPECT_EQ(0, task_run_count());
205 EXPECT_EQ(1u, queue
.extensions_with_pending_tasks());
207 // Processing tasks when there is one pending runs the task and removes the
208 // extension from the list of extensions with pending tasks.
209 queue
.ProcessPendingTasks(NULL
, browser_context(), extension
.get());
210 EXPECT_EQ(1, task_run_count());
211 EXPECT_EQ(0u, queue
.extensions_with_pending_tasks());
214 } // namespace extensions