Chromium Code Reviews| Index: chrome/browser/extensions/app_background_page_apitest.cc |
| diff --git a/chrome/browser/extensions/app_background_page_apitest.cc b/chrome/browser/extensions/app_background_page_apitest.cc |
| index 90db425dd3b4ba8648498fe9114bf4bcdb4d0cde..70a276c0f5d44b8918a0c3d1b7b27d881858acba 100644 |
| --- a/chrome/browser/extensions/app_background_page_apitest.cc |
| +++ b/chrome/browser/extensions/app_background_page_apitest.cc |
| @@ -2,6 +2,7 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| +#include "base/path_service.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/background/background_contents_service.h" |
| @@ -11,10 +12,13 @@ |
| #include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/extensions/extension_apitest.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| +#include "chrome/browser/extensions/extension_test_message_listener.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_dialogs.h" |
| #include "chrome/browser/ui/browser_window.h" |
| +#include "chrome/browser/ui/extensions/application_launch.h" |
| +#include "chrome/common/chrome_paths.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/test/test_notification_tracker.h" |
| @@ -23,6 +27,7 @@ |
| #include "extensions/common/switches.h" |
| #include "net/dns/mock_host_resolver.h" |
| #include "net/test/embedded_test_server/embedded_test_server.h" |
| +#include "ppapi/shared_impl/ppapi_switches.h" |
| #if defined(OS_MACOSX) |
| #include "base/mac/scoped_nsautorelease_pool.h" |
| @@ -109,6 +114,95 @@ class AppBackgroundPageApiTest : public ExtensionApiTest { |
| base::ScopedTempDir app_dir_; |
| }; |
| +namespace { |
| + |
| +// Fixture to assist in testing v2 app background pages containing |
| +// Native Client embeds. |
| +class AppBackgroundPageNaClTest : public AppBackgroundPageApiTest { |
| + public: |
| + AppBackgroundPageNaClTest() |
| + : extension_(NULL) { |
| + PathService::Get(chrome::DIR_GEN_TEST_DATA, &app_dir_); |
| + app_dir_ = app_dir_.AppendASCII( |
| + "ppapi/tests/extensions/background_keepalive/newlib"); |
| + } |
| + virtual ~AppBackgroundPageNaClTest() { |
| + } |
| + |
| + virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { |
| + AppBackgroundPageApiTest::SetUpCommandLine(command_line); |
| + command_line->AppendSwitchASCII( |
| + switches::kPpapiKeepAliveThrottle, "50"); |
| + command_line->AppendSwitchASCII( |
| + extensions::switches::kEventPageIdleTime, "1000"); |
| + command_line->AppendSwitchASCII( |
| + extensions::switches::kEventPageSuspendingTime, "1000"); |
| + } |
| + |
| + const Extension* extension() { return extension_; } |
| + |
| + protected: |
| + void LaunchTestingApp() { |
| + extension_ = LoadExtension(app_dir_); |
| + ASSERT_TRUE(extension_); |
| + } |
| + |
| + private: |
| + base::FilePath app_dir_; |
| + const Extension* extension_; |
| +}; |
| + |
| +// Produces an extensions::ProcessManager::ImpulseCallbackForTesting callback |
| +// that will match a specified goal and can be waited on. The callback |
| +// must be released when it returns true, as it holds a reference to the |
| +// internal message loop. |
| +class ImpulseCallbackCounter { |
| + public: |
| + explicit ImpulseCallbackCounter(const std::string& extension_id) |
| + : observed_(0), |
| + goal_(0), |
| + extension_id_(extension_id) { |
| + } |
| + |
| + extensions::ProcessManager::ImpulseCallbackForTesting |
| + SetGoalAndGetCallback(int goal) { |
| + observed_ = 0; |
| + goal_ = goal; |
| + message_loop_runner_ = new content::MessageLoopRunner(); |
| + return base::Bind(&ImpulseCallbackCounter::ImpulseCallback, |
| + base::Unretained(this), |
| + message_loop_runner_->QuitClosure(), |
| + extension_id_); |
| + } |
| + |
| + void Wait() { |
| + message_loop_runner_->Run(); |
| + // Assert that the callback produced in SetGoalAndGetCallback |
| + // has been destroyed and released its reference to the message loop. |
| + ASSERT_TRUE(message_loop_runner_->HasOneRef()); |
| + } |
| + private: |
| + bool ImpulseCallback( |
| + const base::Closure& quit_callback, |
| + const std::string& extension_id_from_test, |
| + const std::string& extension_id_from_manager) { |
| + if (extension_id_from_test == extension_id_from_manager) { |
| + if (++observed_ >= goal_) { |
| + quit_callback.Run(); |
| + return true; // Indicate the callback must be released. |
| + } |
| + } |
| + return false; |
| + } |
| + |
| + int observed_; |
| + int goal_; |
| + const std::string extension_id_; |
| + scoped_refptr<content::MessageLoopRunner> message_loop_runner_; |
| +}; |
| + |
| +} // namespace |
| + |
| // Disable on Mac only. http://crbug.com/95139 |
| #if defined(OS_MACOSX) |
| #define MAYBE_Basic DISABLED_Basic |
| @@ -503,3 +597,34 @@ IN_PROC_BROWSER_TEST_F(AppBackgroundPageApiTest, UnloadExtensionWhileHidden) { |
| content::RunAllPendingInMessageLoop(); |
| ASSERT_TRUE(WaitForBackgroundMode(false)); |
| } |
| + |
| +// Verify active NaCl embeds cause many keepalive impulses to be sent. |
| +IN_PROC_BROWSER_TEST_F(AppBackgroundPageNaClTest, BackgroundKeepaliveActive) { |
| + ExtensionTestMessageListener nacl_modules_loaded("nacl_modules_loaded", true); |
| + LaunchTestingApp(); |
| + extensions::ProcessManager* manager = |
| + extensions::ExtensionSystem::Get(browser()->profile())->process_manager(); |
| + ImpulseCallbackCounter active_impulse_counter(extension()->id()); |
| + EXPECT_TRUE(nacl_modules_loaded.WaitUntilSatisfied()); |
| + |
| + // Target .5 seconds: .5 seconds / 50ms throttle * 2 embeds == 20 impulses. |
| + manager->SetKeepaliveImpulseCallbackForTesting( |
| + active_impulse_counter.SetGoalAndGetCallback(20)); |
| + ASSERT_NO_FATAL_FAILURE(active_impulse_counter.Wait()); |
|
yzshen1
2014/01/03 22:10:10
Why do we need this? ASSERT_TRUE() in Wait() is su
scheib
2014/01/03 23:11:29
Correct gtest form is to wrap any subroutine call
yzshen1
2014/01/03 23:23:28
Thanks, I didn't know that!
On 2014/01/03 23:11:29
|
| +} |
| + |
| +// Verify that nacl modules that go idle will not send keepalive impulses. |
| +IN_PROC_BROWSER_TEST_F(AppBackgroundPageNaClTest, BackgroundKeepaliveIdle) { |
| + ExtensionTestMessageListener nacl_modules_loaded("nacl_modules_loaded", true); |
| + LaunchTestingApp(); |
| + extensions::ProcessManager* manager = |
| + extensions::ExtensionSystem::Get(browser()->profile())->process_manager(); |
| + ImpulseCallbackCounter idle_impulse_counter(extension()->id()); |
| + EXPECT_TRUE(nacl_modules_loaded.WaitUntilSatisfied()); |
| + |
| + manager->SetKeepaliveImpulseDecrementCallbackForTesting( |
| + idle_impulse_counter.SetGoalAndGetCallback(1)); |
| + nacl_modules_loaded.Reply("be idle"); |
| + ASSERT_NO_FATAL_FAILURE(idle_impulse_counter.Wait()); |
|
yzshen1
2014/01/03 22:10:10
ditto
scheib
2014/01/03 23:11:29
ditto
|
| +} |
| + |