root/extensions/browser/lazy_background_task_queue_unittest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. create_count_
  2. create_count
  3. CreateBackgroundHost
  4. task_run_count
  5. RunPendingTask
  6. CreateSimpleExtension
  7. CreateLazyBackgroundExtension
  8. TEST_F
  9. TEST_F
  10. TEST_F

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "extensions/browser/lazy_background_task_queue.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "chrome/browser/extensions/extension_service_unittest.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/browser/process_manager.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {

// A ProcessManager that doesn't create background host pages.
class TestProcessManager : public ProcessManager {
 public:
  explicit TestProcessManager(Profile* profile)
      : ProcessManager(profile, profile->GetOriginalProfile()),
        create_count_(0) {}
  virtual ~TestProcessManager() {}

  int create_count() { return create_count_; }

  // ProcessManager overrides:
  virtual bool CreateBackgroundHost(const Extension* extension,
                                    const GURL& url) OVERRIDE {
    // Don't actually try to create a web contents.
    create_count_++;
    return false;
  }

 private:
  int create_count_;

  DISALLOW_COPY_AND_ASSIGN(TestProcessManager);
};

// Derives from ExtensionServiceTestBase because ExtensionService is difficult
// to initialize alone.
class LazyBackgroundTaskQueueTest : public ExtensionServiceTestBase {
 public:
  LazyBackgroundTaskQueueTest() : task_run_count_(0) {}
  virtual ~LazyBackgroundTaskQueueTest() {}

  int task_run_count() { return task_run_count_; }

  // A simple callback for AddPendingTask.
  void RunPendingTask(ExtensionHost* host) {
    task_run_count_++;
  }

  // Creates and registers an extension without a background page.
  scoped_refptr<Extension> CreateSimpleExtension() {
    scoped_refptr<Extension> extension = ExtensionBuilder()
        .SetManifest(DictionaryBuilder()
                     .Set("name", "No background")
                     .Set("version", "1")
                     .Set("manifest_version", 2))
        .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
        .Build();
    service_->AddExtension(extension);
    return extension;
  }

  // Creates and registers an extension with a lazy background page.
  scoped_refptr<Extension> CreateLazyBackgroundExtension() {
    scoped_refptr<Extension> extension = ExtensionBuilder()
        .SetManifest(DictionaryBuilder()
            .Set("name", "Lazy background")
            .Set("version", "1")
            .Set("manifest_version", 2)
            .Set("background",
                  DictionaryBuilder()
                  .Set("page", "background.html")
                  .SetBoolean("persistent", false)))
        .SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
        .Build();
    service_->AddExtension(extension);
    return extension;
  }

 private:
  // The total number of pending tasks that have been executed.
  int task_run_count_;

  DISALLOW_COPY_AND_ASSIGN(LazyBackgroundTaskQueueTest);
};

// Tests that only extensions with background pages should have tasks queued.
TEST_F(LazyBackgroundTaskQueueTest, ShouldEnqueueTask) {
  InitializeEmptyExtensionService();
  InitializeProcessManager();

  LazyBackgroundTaskQueue queue(profile_.get());

  // Build a simple extension with no background page.
  scoped_refptr<Extension> no_background = CreateSimpleExtension();
  EXPECT_FALSE(queue.ShouldEnqueueTask(profile_.get(), no_background.get()));

  // Build another extension with a background page.
  scoped_refptr<Extension> with_background = CreateLazyBackgroundExtension();
  EXPECT_TRUE(queue.ShouldEnqueueTask(profile_.get(), with_background.get()));
}

// Tests that adding tasks actually increases the pending task count, and that
// multiple extensions can have pending tasks.
TEST_F(LazyBackgroundTaskQueueTest, AddPendingTask) {
  InitializeEmptyExtensionService();

  // Swap in our stub TestProcessManager.
  TestExtensionSystem* extension_system =
      static_cast<extensions::TestExtensionSystem*>(
          ExtensionSystem::Get(profile_.get()));
  // Owned by |extension_system|.
  TestProcessManager* process_manager = new TestProcessManager(profile_.get());
  extension_system->SetProcessManager(process_manager);

  LazyBackgroundTaskQueue queue(profile_.get());

  // Build a simple extension with no background page.
  scoped_refptr<Extension> no_background = CreateSimpleExtension();

  // Adding a pending task increases the number of extensions with tasks, but
  // doesn't run the task.
  queue.AddPendingTask(profile_.get(),
                       no_background->id(),
                       base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
                                  base::Unretained(this)));
  EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
  EXPECT_EQ(0, task_run_count());

  // Another task on the same extension doesn't increase the number of
  // extensions that have tasks and doesn't run any tasks.
  queue.AddPendingTask(profile_.get(),
                       no_background->id(),
                       base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
                                  base::Unretained(this)));
  EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
  EXPECT_EQ(0, task_run_count());

  // Adding a task on an extension with a lazy background page tries to create
  // a background host, and if that fails, runs the task immediately.
  scoped_refptr<Extension> lazy_background = CreateLazyBackgroundExtension();
  queue.AddPendingTask(profile_.get(),
                       lazy_background->id(),
                       base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
                                  base::Unretained(this)));
  EXPECT_EQ(2u, queue.extensions_with_pending_tasks());
  // The process manager tried to create a background host.
  EXPECT_EQ(1, process_manager->create_count());
  // The task ran immediately because the creation failed.
  EXPECT_EQ(1, task_run_count());
}

// Tests that pending tasks are actually run.
TEST_F(LazyBackgroundTaskQueueTest, ProcessPendingTasks) {
  InitializeEmptyExtensionService();

  LazyBackgroundTaskQueue queue(profile_.get());

  // ProcessPendingTasks is a no-op if there are no tasks.
  scoped_refptr<Extension> extension = CreateSimpleExtension();
  queue.ProcessPendingTasks(NULL, profile_.get(), extension);
  EXPECT_EQ(0, task_run_count());

  // Schedule a task to run.
  queue.AddPendingTask(profile_.get(),
                       extension->id(),
                       base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
                                  base::Unretained(this)));
  EXPECT_EQ(0, task_run_count());
  EXPECT_EQ(1u, queue.extensions_with_pending_tasks());

  // Trying to run tasks for an unrelated profile should do nothing.
  TestingProfile profile2;
  queue.ProcessPendingTasks(NULL, &profile2, extension);
  EXPECT_EQ(0, task_run_count());
  EXPECT_EQ(1u, queue.extensions_with_pending_tasks());

  // Processing tasks when there is one pending runs the task and removes the
  // extension from the list of extensions with pending tasks.
  queue.ProcessPendingTasks(NULL, profile_.get(), extension);
  EXPECT_EQ(1, task_run_count());
  EXPECT_EQ(0u, queue.extensions_with_pending_tasks());
}

}  // namespace extensions

/* [<][>][^][v][top][bottom][index][help] */