Home | History | Annotate | Download | only in browser
      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.
      4 
      5 #include "extensions/browser/lazy_background_task_queue.h"
      6 
      7 #include "base/bind.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"
     17 
     18 namespace extensions {
     19 
     20 // A ProcessManager that doesn't create background host pages.
     21 class TestProcessManager : public ProcessManager {
     22  public:
     23   explicit TestProcessManager(Profile* profile)
     24       : ProcessManager(profile, profile->GetOriginalProfile()),
     25         create_count_(0) {}
     26   virtual ~TestProcessManager() {}
     27 
     28   int create_count() { return create_count_; }
     29 
     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.
     34     create_count_++;
     35     return NULL;
     36   }
     37 
     38  private:
     39   int create_count_;
     40 
     41   DISALLOW_COPY_AND_ASSIGN(TestProcessManager);
     42 };
     43 
     44 // Derives from ExtensionServiceTestBase because ExtensionService is difficult
     45 // to initialize alone.
     46 class LazyBackgroundTaskQueueTest : public ExtensionServiceTestBase {
     47  public:
     48   LazyBackgroundTaskQueueTest() : task_run_count_(0) {}
     49   virtual ~LazyBackgroundTaskQueueTest() {}
     50 
     51   int task_run_count() { return task_run_count_; }
     52 
     53   // A simple callback for AddPendingTask.
     54   void RunPendingTask(ExtensionHost* host) {
     55     task_run_count_++;
     56   }
     57 
     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")
     63                      .Set("version", "1")
     64                      .Set("manifest_version", 2))
     65         .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
     66         .Build();
     67     service_->AddExtension(extension);
     68     return extension;
     69   }
     70 
     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")
     76             .Set("version", "1")
     77             .Set("manifest_version", 2)
     78             .Set("background",
     79                   DictionaryBuilder()
     80                   .Set("page", "background.html")
     81                   .SetBoolean("persistent", false)))
     82         .SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
     83         .Build();
     84     service_->AddExtension(extension);
     85     return extension;
     86   }
     87 
     88  private:
     89   // The total number of pending tasks that have been executed.
     90   int task_run_count_;
     91 
     92   DISALLOW_COPY_AND_ASSIGN(LazyBackgroundTaskQueueTest);
     93 };
     94 
     95 // Tests that only extensions with background pages should have tasks queued.
     96 TEST_F(LazyBackgroundTaskQueueTest, ShouldEnqueueTask) {
     97   InitializeEmptyExtensionService();
     98   InitializeProcessManager();
     99 
    100   LazyBackgroundTaskQueue queue(profile_.get());
    101 
    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()));
    105 
    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()));
    109 }
    110 
    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();
    115 
    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);
    123 
    124   LazyBackgroundTaskQueue queue(profile_.get());
    125 
    126   // Build a simple extension with no background page.
    127   scoped_refptr<Extension> no_background = CreateSimpleExtension();
    128 
    129   // Adding a pending task increases the number of extensions with tasks, but
    130   // doesn't run the task.
    131   queue.AddPendingTask(profile_.get(),
    132                        no_background->id(),
    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());
    137 
    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(),
    141                        no_background->id(),
    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());
    146 
    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());
    159 }
    160 
    161 // Tests that pending tasks are actually run.
    162 TEST_F(LazyBackgroundTaskQueueTest, ProcessPendingTasks) {
    163   InitializeEmptyExtensionService();
    164 
    165   LazyBackgroundTaskQueue queue(profile_.get());
    166 
    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());
    171 
    172   // Schedule a task to run.
    173   queue.AddPendingTask(profile_.get(),
    174                        extension->id(),
    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());
    179 
    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());
    185 
    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());
    191 }
    192 
    193 }  // namespace extensions
    194