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_process_manager.h"
10 #include "chrome/browser/extensions/extension_service_unittest.h"
11 #include "chrome/browser/extensions/test_extension_system.h"
12 #include "chrome/common/extensions/extension.h"
13 #include "chrome/common/extensions/extension_builder.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 namespace extensions {
20 // An ExtensionProcessManager that doesn't create background host pages.
21 class TestExtensionProcessManager : public ExtensionProcessManager {
23 explicit TestExtensionProcessManager(Profile* profile)
24 : ExtensionProcessManager(profile),
26 virtual ~TestExtensionProcessManager() {}
28 int create_count() { return create_count_; }
30 // ExtensionProcessManager overrides:
31 virtual extensions::ExtensionHost* CreateBackgroundHost(
32 const extensions::Extension* extension,
33 const GURL& url) OVERRIDE {
34 // Don't actually try to create a web contents.
42 DISALLOW_COPY_AND_ASSIGN(TestExtensionProcessManager);
45 // Derives from ExtensionServiceTestBase because ExtensionService is difficult
46 // to initialize alone.
47 class LazyBackgroundTaskQueueTest : public ExtensionServiceTestBase {
49 LazyBackgroundTaskQueueTest() : task_run_count_(0) {}
50 virtual ~LazyBackgroundTaskQueueTest() {}
52 int task_run_count() { return task_run_count_; }
54 // A simple callback for AddPendingTask.
55 void RunPendingTask(ExtensionHost* host) {
59 // Creates and registers an extension without a background page.
60 scoped_refptr<Extension> CreateSimpleExtension() {
61 scoped_refptr<Extension> extension = ExtensionBuilder()
62 .SetManifest(DictionaryBuilder()
63 .Set("name", "No background")
65 .Set("manifest_version", 2))
66 .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
68 service_->AddExtension(extension);
72 // Creates and registers an extension with a lazy background page.
73 scoped_refptr<Extension> CreateLazyBackgroundExtension() {
74 scoped_refptr<Extension> extension = ExtensionBuilder()
75 .SetManifest(DictionaryBuilder()
76 .Set("name", "Lazy background")
78 .Set("manifest_version", 2)
81 .Set("page", "background.html")
82 .SetBoolean("persistent", false)))
83 .SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
85 service_->AddExtension(extension);
90 // The total number of pending tasks that have been executed.
93 DISALLOW_COPY_AND_ASSIGN(LazyBackgroundTaskQueueTest);
96 // Tests that only extensions with background pages should have tasks queued.
97 TEST_F(LazyBackgroundTaskQueueTest, ShouldEnqueueTask) {
98 InitializeEmptyExtensionService();
99 InitializeExtensionProcessManager();
101 LazyBackgroundTaskQueue queue(profile_.get());
103 // Build a simple extension with no background page.
104 scoped_refptr<Extension> no_background = CreateSimpleExtension();
105 EXPECT_FALSE(queue.ShouldEnqueueTask(profile_.get(), no_background.get()));
107 // Build another extension with a background page.
108 scoped_refptr<Extension> with_background = CreateLazyBackgroundExtension();
109 EXPECT_TRUE(queue.ShouldEnqueueTask(profile_.get(), with_background.get()));
112 // Tests that adding tasks actually increases the pending task count, and that
113 // multiple extensions can have pending tasks.
114 TEST_F(LazyBackgroundTaskQueueTest, AddPendingTask) {
115 InitializeEmptyExtensionService();
117 // Swap in our stub TestExtensionProcessManager.
118 TestExtensionSystem* extension_system =
119 static_cast<extensions::TestExtensionSystem*>(
120 ExtensionSystem::Get(profile_.get()));
121 // Owned by |extension_system|.
122 TestExtensionProcessManager* process_manager =
123 new TestExtensionProcessManager(profile_.get());
124 extension_system->SetExtensionProcessManager(process_manager);
126 LazyBackgroundTaskQueue queue(profile_.get());
128 // Build a simple extension with no background page.
129 scoped_refptr<Extension> no_background = CreateSimpleExtension();
131 // Adding a pending task increases the number of extensions with tasks, but
132 // doesn't run the task.
133 queue.AddPendingTask(profile_.get(),
135 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
136 base::Unretained(this)));
137 EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
138 EXPECT_EQ(0, task_run_count());
140 // Another task on the same extension doesn't increase the number of
141 // extensions that have tasks and doesn't run any tasks.
142 queue.AddPendingTask(profile_.get(),
144 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
145 base::Unretained(this)));
146 EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
147 EXPECT_EQ(0, task_run_count());
149 // Adding a task on an extension with a lazy background page tries to create
150 // a background host, and if that fails, runs the task immediately.
151 scoped_refptr<Extension> lazy_background = CreateLazyBackgroundExtension();
152 queue.AddPendingTask(profile_.get(),
153 lazy_background->id(),
154 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
155 base::Unretained(this)));
156 EXPECT_EQ(2u, queue.extensions_with_pending_tasks());
157 // The process manager tried to create a background host.
158 EXPECT_EQ(1, process_manager->create_count());
159 // The task ran immediately because the creation failed.
160 EXPECT_EQ(1, task_run_count());
163 // Tests that pending tasks are actually run.
164 TEST_F(LazyBackgroundTaskQueueTest, ProcessPendingTasks) {
165 InitializeEmptyExtensionService();
167 LazyBackgroundTaskQueue queue(profile_.get());
169 // ProcessPendingTasks is a no-op if there are no tasks.
170 scoped_refptr<Extension> extension = CreateSimpleExtension();
171 queue.ProcessPendingTasks(NULL, profile_.get(), extension);
172 EXPECT_EQ(0, task_run_count());
174 // Schedule a task to run.
175 queue.AddPendingTask(profile_.get(),
177 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
178 base::Unretained(this)));
179 EXPECT_EQ(0, task_run_count());
180 EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
182 // Trying to run tasks for an unrelated profile should do nothing.
183 TestingProfile profile2;
184 queue.ProcessPendingTasks(NULL, &profile2, extension);
185 EXPECT_EQ(0, task_run_count());
186 EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
188 // Processing tasks when there is one pending runs the task and removes the
189 // extension from the list of extensions with pending tasks.
190 queue.ProcessPendingTasks(NULL, profile_.get(), extension);
191 EXPECT_EQ(1, task_run_count());
192 EXPECT_EQ(0u, queue.extensions_with_pending_tasks());
195 } // namespace extensions