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/command_line.h"
9 #include "chrome/browser/extensions/extension_service_unittest.h"
10 #include "chrome/browser/extensions/test_extension_system.h"
11 #include "chrome/test/base/testing_profile.h"
12 #include "content/public/test/test_browser_thread_bundle.h"
13 #include "extensions/browser/process_manager.h"
14 #include "extensions/common/extension.h"
15 #include "extensions/common/extension_builder.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 namespace extensions
{
20 // A ProcessManager that doesn't create background host pages.
21 class TestProcessManager
: public ProcessManager
{
23 explicit TestProcessManager(Profile
* profile
)
24 : ProcessManager(profile
, profile
->GetOriginalProfile()),
26 virtual ~TestProcessManager() {}
28 int create_count() { return create_count_
; }
30 // ProcessManager overrides:
31 virtual ExtensionHost
* CreateBackgroundHost(const Extension
* extension
,
32 const GURL
& url
) OVERRIDE
{
33 // Don't actually try to create a web contents.
41 DISALLOW_COPY_AND_ASSIGN(TestProcessManager
);
44 // Derives from ExtensionServiceTestBase because ExtensionService is difficult
45 // to initialize alone.
46 class LazyBackgroundTaskQueueTest
: public ExtensionServiceTestBase
{
48 LazyBackgroundTaskQueueTest() : task_run_count_(0) {}
49 virtual ~LazyBackgroundTaskQueueTest() {}
51 int task_run_count() { return task_run_count_
; }
53 // A simple callback for AddPendingTask.
54 void RunPendingTask(ExtensionHost
* host
) {
58 // Creates and registers an extension without a background page.
59 scoped_refptr
<Extension
> CreateSimpleExtension() {
60 scoped_refptr
<Extension
> extension
= ExtensionBuilder()
61 .SetManifest(DictionaryBuilder()
62 .Set("name", "No background")
64 .Set("manifest_version", 2))
65 .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
67 service_
->AddExtension(extension
);
71 // Creates and registers an extension with a lazy background page.
72 scoped_refptr
<Extension
> CreateLazyBackgroundExtension() {
73 scoped_refptr
<Extension
> extension
= ExtensionBuilder()
74 .SetManifest(DictionaryBuilder()
75 .Set("name", "Lazy background")
77 .Set("manifest_version", 2)
80 .Set("page", "background.html")
81 .SetBoolean("persistent", false)))
82 .SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
84 service_
->AddExtension(extension
);
89 // The total number of pending tasks that have been executed.
92 DISALLOW_COPY_AND_ASSIGN(LazyBackgroundTaskQueueTest
);
95 // Tests that only extensions with background pages should have tasks queued.
96 TEST_F(LazyBackgroundTaskQueueTest
, ShouldEnqueueTask
) {
97 InitializeEmptyExtensionService();
98 InitializeProcessManager();
100 LazyBackgroundTaskQueue
queue(profile_
.get());
102 // Build a simple extension with no background page.
103 scoped_refptr
<Extension
> no_background
= CreateSimpleExtension();
104 EXPECT_FALSE(queue
.ShouldEnqueueTask(profile_
.get(), no_background
.get()));
106 // Build another extension with a background page.
107 scoped_refptr
<Extension
> with_background
= CreateLazyBackgroundExtension();
108 EXPECT_TRUE(queue
.ShouldEnqueueTask(profile_
.get(), with_background
.get()));
111 // Tests that adding tasks actually increases the pending task count, and that
112 // multiple extensions can have pending tasks.
113 TEST_F(LazyBackgroundTaskQueueTest
, AddPendingTask
) {
114 InitializeEmptyExtensionService();
116 // Swap in our stub TestProcessManager.
117 TestExtensionSystem
* extension_system
=
118 static_cast<extensions::TestExtensionSystem
*>(
119 ExtensionSystem::Get(profile_
.get()));
120 // Owned by |extension_system|.
121 TestProcessManager
* process_manager
= new TestProcessManager(profile_
.get());
122 extension_system
->SetProcessManager(process_manager
);
124 LazyBackgroundTaskQueue
queue(profile_
.get());
126 // Build a simple extension with no background page.
127 scoped_refptr
<Extension
> no_background
= CreateSimpleExtension();
129 // Adding a pending task increases the number of extensions with tasks, but
130 // doesn't run the task.
131 queue
.AddPendingTask(profile_
.get(),
133 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask
,
134 base::Unretained(this)));
135 EXPECT_EQ(1u, queue
.extensions_with_pending_tasks());
136 EXPECT_EQ(0, task_run_count());
138 // Another task on the same extension doesn't increase the number of
139 // extensions that have tasks and doesn't run any tasks.
140 queue
.AddPendingTask(profile_
.get(),
142 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask
,
143 base::Unretained(this)));
144 EXPECT_EQ(1u, queue
.extensions_with_pending_tasks());
145 EXPECT_EQ(0, task_run_count());
147 // Adding a task on an extension with a lazy background page tries to create
148 // a background host, and if that fails, runs the task immediately.
149 scoped_refptr
<Extension
> lazy_background
= CreateLazyBackgroundExtension();
150 queue
.AddPendingTask(profile_
.get(),
151 lazy_background
->id(),
152 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask
,
153 base::Unretained(this)));
154 EXPECT_EQ(2u, queue
.extensions_with_pending_tasks());
155 // The process manager tried to create a background host.
156 EXPECT_EQ(1, process_manager
->create_count());
157 // The task ran immediately because the creation failed.
158 EXPECT_EQ(1, task_run_count());
161 // Tests that pending tasks are actually run.
162 TEST_F(LazyBackgroundTaskQueueTest
, ProcessPendingTasks
) {
163 InitializeEmptyExtensionService();
165 LazyBackgroundTaskQueue
queue(profile_
.get());
167 // ProcessPendingTasks is a no-op if there are no tasks.
168 scoped_refptr
<Extension
> extension
= CreateSimpleExtension();
169 queue
.ProcessPendingTasks(NULL
, profile_
.get(), extension
);
170 EXPECT_EQ(0, task_run_count());
172 // Schedule a task to run.
173 queue
.AddPendingTask(profile_
.get(),
175 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask
,
176 base::Unretained(this)));
177 EXPECT_EQ(0, task_run_count());
178 EXPECT_EQ(1u, queue
.extensions_with_pending_tasks());
180 // Trying to run tasks for an unrelated profile should do nothing.
181 TestingProfile profile2
;
182 queue
.ProcessPendingTasks(NULL
, &profile2
, extension
);
183 EXPECT_EQ(0, task_run_count());
184 EXPECT_EQ(1u, queue
.extensions_with_pending_tasks());
186 // Processing tasks when there is one pending runs the task and removes the
187 // extension from the list of extensions with pending tasks.
188 queue
.ProcessPendingTasks(NULL
, profile_
.get(), extension
);
189 EXPECT_EQ(1, task_run_count());
190 EXPECT_EQ(0u, queue
.extensions_with_pending_tasks());
193 } // namespace extensions