Index: chrome/browser/chromeos/power/renderer_freezer_unittest.cc |
diff --git a/chrome/browser/chromeos/power/renderer_freezer_unittest.cc b/chrome/browser/chromeos/power/renderer_freezer_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6ae9ba2b460e5acafe9a7fa91c56501712dba1dc |
--- /dev/null |
+++ b/chrome/browser/chromeos/power/renderer_freezer_unittest.cc |
@@ -0,0 +1,223 @@ |
+// Copyright 2014 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 "chrome/browser/chromeos/power/renderer_freezer.h" |
+ |
+#include <string> |
+ |
+#include "base/message_loop/message_loop.h" |
+#include "base/run_loop.h" |
+#include "chromeos/dbus/dbus_thread_manager.h" |
+#include "chromeos/dbus/fake_power_manager_client.h" |
+#include "testing/gtest/include/gtest/gtest-death-test.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace chromeos { |
+ |
+namespace { |
+// Class that delegates used in testing can inherit from to record calls that |
+// are made by the code being tested. |
+class ActionRecorder { |
+ public: |
+ ActionRecorder() {} |
+ virtual ~ActionRecorder() {} |
+ |
+ // Returns a comma-separated string describing the actions that were |
+ // requested since the previous call to GetActions() (i.e. results are |
+ // non-repeatable). |
+ std::string GetActions() { |
+ std::string actions = actions_; |
+ actions_.clear(); |
+ return actions; |
+ } |
+ |
+ protected: |
+ // Appends |new_action| to |actions_|, using a comma as a separator if |
+ // other actions are already listed. |
+ void AppendAction(const std::string& new_action) { |
+ if (!actions_.empty()) |
+ actions_ += ","; |
+ actions_ += new_action; |
+ } |
+ |
+ private: |
+ // Comma-separated list of actions that have been performed. |
+ std::string actions_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ActionRecorder); |
+}; |
+ |
+// Actions that can be returned by TestDelegate::GetActions(). |
+const char kFreezeRenderers[] = "freeze_renderers"; |
+const char kThawRenderers[] = "thaw_renderers"; |
+const char kNoActions[] = ""; |
+ |
+// Test implementation of RendererFreezer::Delegate that records the actions it |
+// was asked to perform. |
+class TestDelegate : public RendererFreezer::Delegate, public ActionRecorder { |
+ public: |
+ TestDelegate() |
+ : can_freeze_renderers_(true), |
+ freeze_renderers_result_(true), |
+ thaw_renderers_result_(true) {} |
+ |
+ virtual ~TestDelegate() {} |
+ |
+ // RendererFreezer::Delegate overrides. |
+ virtual bool FreezeRenderers() OVERRIDE { |
+ AppendAction(kFreezeRenderers); |
+ |
+ return freeze_renderers_result_; |
+ } |
+ virtual bool ThawRenderers() OVERRIDE { |
+ AppendAction(kThawRenderers); |
+ |
+ return thaw_renderers_result_; |
+ } |
+ virtual bool CanFreezeRenderers() OVERRIDE { return can_freeze_renderers_; } |
+ |
+ void set_freeze_renderers_result(bool result) { |
+ freeze_renderers_result_ = result; |
+ } |
+ |
+ void set_thaw_renderers_result(bool result) { |
+ thaw_renderers_result_ = result; |
+ } |
+ |
+ // Sets whether the delegate is capable of freezing renderers. This also |
+ // changes |freeze_renderers_result_| and |thaw_renderers_result_|. |
+ void set_can_freeze_renderers(bool can_freeze) { |
+ can_freeze_renderers_ = can_freeze; |
+ |
+ // If the delegate cannot freeze renderers, then the result of trying to do |
+ // so will be false. |
+ freeze_renderers_result_ = can_freeze; |
+ thaw_renderers_result_ = can_freeze; |
+ } |
+ |
+ private: |
+ bool can_freeze_renderers_; |
+ bool freeze_renderers_result_; |
+ bool thaw_renderers_result_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TestDelegate); |
+}; |
+ |
+} // namespace |
+ |
+class RendererFreezerTest : public testing::Test { |
+ public: |
+ RendererFreezerTest() |
+ : power_manager_client_(new FakePowerManagerClient()), |
+ test_delegate_(new TestDelegate()) { |
+ DBusThreadManager::GetSetterForTesting()->SetPowerManagerClient( |
+ scoped_ptr<PowerManagerClient>(power_manager_client_)); |
+ } |
+ |
+ virtual ~RendererFreezerTest() { |
+ renderer_freezer_.reset(); |
+ |
+ // This should never be false since all tests should be calling Init() but |
+ // it doesn't hurt to check. |
Daniel Erat
2014/09/12 22:53:22
your call to DBusThreadManager::GetSetterForTestin
Chirantan Ekbote
2014/09/16 02:51:40
You're right. This is no longer necessary.
|
+ if (DBusThreadManager::IsInitialized()) |
+ DBusThreadManager::Shutdown(); |
+ } |
+ |
+ void Init() { |
+ renderer_freezer_.reset(new RendererFreezer( |
+ scoped_ptr<RendererFreezer::Delegate>(test_delegate_))); |
+ } |
+ |
+ protected: |
+ FakePowerManagerClient* power_manager_client_; |
+ TestDelegate* test_delegate_; |
+ |
+ scoped_ptr<RendererFreezer> renderer_freezer_; |
+ |
+ private: |
+ base::MessageLoop message_loop_; |
+ DISALLOW_COPY_AND_ASSIGN(RendererFreezerTest); |
+}; |
+ |
+// Tests that the RendererFreezer freezes renderers on suspend and thaws them on |
+// resume. |
+TEST_F(RendererFreezerTest, SuspendResume) { |
+ Init(); |
+ |
+ power_manager_client_->SendSuspendImminent(); |
+ |
+ // The RendererFreezer should have grabbed an asynchronous callback and done |
+ // nothing else. |
+ EXPECT_EQ(1, power_manager_client_->GetNumPendingSuspendReadinessCallbacks()); |
+ EXPECT_EQ(kNoActions, test_delegate_->GetActions()); |
+ |
+ // The RendererFreezer should eventually freeze the renderers and run the |
+ // callback. |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks()); |
+ EXPECT_EQ(kFreezeRenderers, test_delegate_->GetActions()); |
+ |
+ // The renderers should be thawed when we resume. |
+ power_manager_client_->SendSuspendDone(); |
+ EXPECT_EQ(kThawRenderers, test_delegate_->GetActions()); |
+} |
+ |
+// Tests that the renderer freezer does nothing if the delegate cannot freeze |
+// renderers. |
+TEST_F(RendererFreezerTest, DelegateCannotFreezeRenderers) { |
+ test_delegate_->set_can_freeze_renderers(false); |
+ Init(); |
+ |
+ power_manager_client_->SendSuspendImminent(); |
+ |
+ // The RendererFreezer should not have grabbed a callback or done anything |
+ // else. |
+ EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks()); |
+ EXPECT_EQ(kNoActions, test_delegate_->GetActions()); |
+ |
+ // There should be nothing in the message loop. |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_EQ(kNoActions, test_delegate_->GetActions()); |
+ |
+ // Nothing happens on resume. |
+ power_manager_client_->SendSuspendDone(); |
+ EXPECT_EQ(kNoActions, test_delegate_->GetActions()); |
+} |
+ |
+// Tests that the RendererFreezer does nothing on resume if the freezing |
+// operation was unsuccessful. |
+TEST_F(RendererFreezerTest, ErrorFreezingRenderers) { |
+ Init(); |
+ test_delegate_->set_freeze_renderers_result(false); |
+ |
+ power_manager_client_->SendSuspendImminent(); |
+ EXPECT_EQ(1, power_manager_client_->GetNumPendingSuspendReadinessCallbacks()); |
+ |
+ // The freezing operation should fail, but we should still report readiness. |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_EQ(kFreezeRenderers, test_delegate_->GetActions()); |
+ EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks()); |
+ |
+ // Since the delegate reported that the freezing was unsuccessful, don't do |
+ // anything on resume. |
+ power_manager_client_->SendSuspendDone(); |
+ EXPECT_EQ(kNoActions, test_delegate_->GetActions()); |
+} |
+ |
+#if defined(GTEST_HAS_DEATH_TEST) |
+// Tests that the RendererFreezer crashes the browser if the freezing operation |
+// was successful but the thawing operation failed. |
+TEST_F(RendererFreezerTest, ErrorThawingRenderers) { |
+ Init(); |
+ test_delegate_->set_thaw_renderers_result(false); |
+ |
+ power_manager_client_->SendSuspendImminent(); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_EQ(kFreezeRenderers, test_delegate_->GetActions()); |
+ |
+ EXPECT_DEATH(power_manager_client_->SendSuspendDone(), "Unable to thaw"); |
+} |
+#endif // GTEST_HAS_DEATH_TEST |
+ |
+} // namespace chromeos |