blob: 42b85c6ec2e45481c68845717429c0d41a20bcd2 [file] [log] [blame]
Gary Morain43bc6272012-01-30 14:01:15 -08001// Copyright (c) 2012 The Chromium OS 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 "shill/power_manager.h"
6
7#include <string>
8
Eric Shienbrood3e20a232012-02-16 11:35:56 -05009#include <base/bind.h>
10#include <base/memory/scoped_ptr.h>
Gary Morain43bc6272012-01-30 14:01:15 -080011#include <gmock/gmock.h>
12#include <gtest/gtest.h>
13
Darin Petkov3ec55342012-09-28 14:04:44 +020014#include "shill/mock_event_dispatcher.h"
Gary Morain43bc6272012-01-30 14:01:15 -080015#include "shill/mock_power_manager_proxy.h"
16#include "shill/power_manager_proxy_interface.h"
17#include "shill/proxy_factory.h"
18
Eric Shienbrood3e20a232012-02-16 11:35:56 -050019using base::Bind;
20using base::Unretained;
Gary Morain52fabab2012-08-22 09:27:31 -070021using std::map;
Gary Morain43bc6272012-01-30 14:01:15 -080022using std::string;
23using testing::_;
Daniel Erat0818cca2012-12-14 10:16:21 -080024using testing::Return;
Gary Morain43bc6272012-01-30 14:01:15 -080025using testing::Test;
26
27namespace shill {
28
Gary Morain43bc6272012-01-30 14:01:15 -080029namespace {
30
31class FakeProxyFactory : public ProxyFactory {
32 public:
Gary Morain52fabab2012-08-22 09:27:31 -070033 FakeProxyFactory()
34 : delegate_(NULL),
35 proxy_(new MockPowerManagerProxy) {}
Gary Morain43bc6272012-01-30 14:01:15 -080036
37 virtual PowerManagerProxyInterface *CreatePowerManagerProxy(
38 PowerManagerProxyDelegate *delegate) {
39 delegate_ = delegate;
Gary Morain52fabab2012-08-22 09:27:31 -070040 return proxy_;
Gary Morain43bc6272012-01-30 14:01:15 -080041 }
42 PowerManagerProxyDelegate *delegate() const { return delegate_; }
Gary Morain52fabab2012-08-22 09:27:31 -070043 MockPowerManagerProxy *proxy() const { return proxy_; }
Gary Morain43bc6272012-01-30 14:01:15 -080044
45 private:
46 PowerManagerProxyDelegate *delegate_;
Gary Morain52fabab2012-08-22 09:27:31 -070047 MockPowerManagerProxy *const proxy_;
Gary Morain43bc6272012-01-30 14:01:15 -080048};
49
50} // namespace
51
52class PowerManagerTest : public Test {
53 public:
Gary Morain52fabab2012-08-22 09:27:31 -070054 static const char kKey1[];
55 static const char kKey2[];
Daniel Erat0818cca2012-12-14 10:16:21 -080056 static const int kSuspendId1 = 123;
57 static const int kSuspendId2 = 456;
Gary Morain52fabab2012-08-22 09:27:31 -070058
Gary Morain43bc6272012-01-30 14:01:15 -080059 PowerManagerTest()
Darin Petkov3ec55342012-09-28 14:04:44 +020060 : power_manager_(&dispatcher_, &factory_),
Gary Morain52fabab2012-08-22 09:27:31 -070061 delegate_(factory_.delegate()) {
62 state_change_callback1_ =
63 Bind(&PowerManagerTest::StateChangeAction1, Unretained(this));
64 state_change_callback2_ =
65 Bind(&PowerManagerTest::StateChangeAction2, Unretained(this));
66 suspend_delay_callback1_ =
67 Bind(&PowerManagerTest::SuspendDelayAction1, Unretained(this));
68 suspend_delay_callback2_ =
69 Bind(&PowerManagerTest::SuspendDelayAction2, Unretained(this));
70 }
Gary Morain43bc6272012-01-30 14:01:15 -080071
Gary Morain52fabab2012-08-22 09:27:31 -070072 MOCK_METHOD1(StateChangeAction1, void(PowerManager::SuspendState));
73 MOCK_METHOD1(StateChangeAction2, void(PowerManager::SuspendState));
Daniel Erat0818cca2012-12-14 10:16:21 -080074 MOCK_METHOD1(SuspendDelayAction1, void(int));
75 MOCK_METHOD1(SuspendDelayAction2, void(int));
Eric Shienbrood3e20a232012-02-16 11:35:56 -050076
Gary Morain43bc6272012-01-30 14:01:15 -080077 protected:
Daniel Erat0818cca2012-12-14 10:16:21 -080078 void OnSuspendImminent(int suspend_id) {
Darin Petkov3ec55342012-09-28 14:04:44 +020079 EXPECT_CALL(dispatcher_,
80 PostDelayedTask(_, PowerManager::kSuspendTimeoutMilliseconds));
Daniel Erat0818cca2012-12-14 10:16:21 -080081 factory_.delegate()->OnSuspendImminent(suspend_id);
Darin Petkov3ec55342012-09-28 14:04:44 +020082 EXPECT_EQ(PowerManagerProxyDelegate::kSuspending,
83 power_manager_.power_state());
84 }
85
86 void OnSuspendTimeout() {
87 power_manager_.OnSuspendTimeout();
88 }
89
90 MockEventDispatcher dispatcher_;
Gary Morain43bc6272012-01-30 14:01:15 -080091 FakeProxyFactory factory_;
92 PowerManager power_manager_;
93 PowerManagerProxyDelegate *const delegate_;
Gary Morain52fabab2012-08-22 09:27:31 -070094 PowerManager::PowerStateCallback state_change_callback1_;
95 PowerManager::PowerStateCallback state_change_callback2_;
96 PowerManager::SuspendDelayCallback suspend_delay_callback1_;
97 PowerManager::SuspendDelayCallback suspend_delay_callback2_;
Gary Morain43bc6272012-01-30 14:01:15 -080098};
99
Gary Morain52fabab2012-08-22 09:27:31 -0700100const char PowerManagerTest::kKey1[] = "Zaphod";
101const char PowerManagerTest::kKey2[] = "Beeblebrox";
102
Darin Petkovca621542012-07-25 14:25:56 +0200103TEST_F(PowerManagerTest, OnPowerStateChanged) {
104 EXPECT_EQ(PowerManagerProxyDelegate::kUnknown, power_manager_.power_state());
105 power_manager_.OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
106 EXPECT_EQ(PowerManagerProxyDelegate::kOn, power_manager_.power_state());
107}
108
Gary Morain52fabab2012-08-22 09:27:31 -0700109TEST_F(PowerManagerTest, AddStateChangeCallback) {
110 EXPECT_CALL(*this, StateChangeAction1(PowerManagerProxyDelegate::kOn));
111 power_manager_.AddStateChangeCallback(kKey1, state_change_callback1_);
Gary Morain43bc6272012-01-30 14:01:15 -0800112 factory_.delegate()->OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
Gary Morain52fabab2012-08-22 09:27:31 -0700113 power_manager_.RemoveStateChangeCallback(kKey1);
Gary Morain43bc6272012-01-30 14:01:15 -0800114}
115
Gary Morain52fabab2012-08-22 09:27:31 -0700116TEST_F(PowerManagerTest, AddSuspendDelayCallback) {
Daniel Erat0818cca2012-12-14 10:16:21 -0800117 EXPECT_CALL(*this, SuspendDelayAction1(kSuspendId1));
Gary Morain52fabab2012-08-22 09:27:31 -0700118 power_manager_.AddSuspendDelayCallback(kKey1, suspend_delay_callback1_);
Darin Petkov3ec55342012-09-28 14:04:44 +0200119 EXPECT_EQ(PowerManagerProxyDelegate::kUnknown, power_manager_.power_state());
Daniel Erat0818cca2012-12-14 10:16:21 -0800120 OnSuspendImminent(kSuspendId1);
Gary Morain52fabab2012-08-22 09:27:31 -0700121 power_manager_.RemoveSuspendDelayCallback(kKey1);
122}
Gary Morain43bc6272012-01-30 14:01:15 -0800123
Gary Morain52fabab2012-08-22 09:27:31 -0700124TEST_F(PowerManagerTest, AddMultipleStateChangeRunMultiple) {
125 EXPECT_CALL(*this, StateChangeAction1(PowerManagerProxyDelegate::kOn));
126 EXPECT_CALL(*this, StateChangeAction1(PowerManagerProxyDelegate::kMem));
127 power_manager_.AddStateChangeCallback(kKey1, state_change_callback1_);
128
129 EXPECT_CALL(*this, StateChangeAction2(PowerManagerProxyDelegate::kOn));
130 EXPECT_CALL(*this, StateChangeAction2(PowerManagerProxyDelegate::kMem));
131 power_manager_.AddStateChangeCallback(kKey2, state_change_callback2_);
Gary Morain43bc6272012-01-30 14:01:15 -0800132
133 factory_.delegate()->OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
134 factory_.delegate()->OnPowerStateChanged(PowerManagerProxyDelegate::kMem);
135}
136
Gary Morain52fabab2012-08-22 09:27:31 -0700137TEST_F(PowerManagerTest, AddMultipleSuspendDelayRunMultiple) {
Daniel Erat0818cca2012-12-14 10:16:21 -0800138 EXPECT_CALL(*this, SuspendDelayAction1(kSuspendId1));
139 EXPECT_CALL(*this, SuspendDelayAction1(kSuspendId2));
Gary Morain52fabab2012-08-22 09:27:31 -0700140 power_manager_.AddSuspendDelayCallback(kKey1, suspend_delay_callback1_);
Gary Morain43bc6272012-01-30 14:01:15 -0800141
Daniel Erat0818cca2012-12-14 10:16:21 -0800142 EXPECT_CALL(*this, SuspendDelayAction2(kSuspendId1));
143 EXPECT_CALL(*this, SuspendDelayAction2(kSuspendId2));
Gary Morain52fabab2012-08-22 09:27:31 -0700144 power_manager_.AddSuspendDelayCallback(kKey2, suspend_delay_callback2_);
145
Daniel Erat0818cca2012-12-14 10:16:21 -0800146 OnSuspendImminent(kSuspendId1);
147 OnSuspendImminent(kSuspendId2);
Gary Morain52fabab2012-08-22 09:27:31 -0700148}
149
150TEST_F(PowerManagerTest, RemoveStateChangeCallback) {
151 EXPECT_CALL(*this, StateChangeAction1(PowerManagerProxyDelegate::kOn));
152 EXPECT_CALL(*this, StateChangeAction1(PowerManagerProxyDelegate::kMem));
153 power_manager_.AddStateChangeCallback(kKey1, state_change_callback1_);
154
155 EXPECT_CALL(*this, StateChangeAction2(PowerManagerProxyDelegate::kOn));
156 EXPECT_CALL(*this, StateChangeAction2(PowerManagerProxyDelegate::kMem))
157 .Times(0);
158 power_manager_.AddStateChangeCallback(kKey2, state_change_callback2_);
Gary Morain43bc6272012-01-30 14:01:15 -0800159
160 factory_.delegate()->OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
161
162 power_manager_.RemoveStateChangeCallback(kKey2);
163 factory_.delegate()->OnPowerStateChanged(PowerManagerProxyDelegate::kMem);
164
165 power_manager_.RemoveStateChangeCallback(kKey1);
166 factory_.delegate()->OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
167}
168
Gary Morain52fabab2012-08-22 09:27:31 -0700169TEST_F(PowerManagerTest, RemoveSuspendDelayCallback) {
Daniel Erat0818cca2012-12-14 10:16:21 -0800170 EXPECT_CALL(*this, SuspendDelayAction1(kSuspendId1));
171 EXPECT_CALL(*this, SuspendDelayAction1(kSuspendId2));
Gary Morain52fabab2012-08-22 09:27:31 -0700172 power_manager_.AddSuspendDelayCallback(kKey1, suspend_delay_callback1_);
173
Daniel Erat0818cca2012-12-14 10:16:21 -0800174 EXPECT_CALL(*this, SuspendDelayAction2(kSuspendId1));
175 EXPECT_CALL(*this, SuspendDelayAction2(kSuspendId2)).Times(0);
Gary Morain52fabab2012-08-22 09:27:31 -0700176 power_manager_.AddSuspendDelayCallback(kKey2, suspend_delay_callback2_);
177
Daniel Erat0818cca2012-12-14 10:16:21 -0800178 OnSuspendImminent(kSuspendId1);
Gary Morain52fabab2012-08-22 09:27:31 -0700179
180 power_manager_.RemoveSuspendDelayCallback(kKey2);
Daniel Erat0818cca2012-12-14 10:16:21 -0800181 OnSuspendImminent(kSuspendId2);
Gary Morain52fabab2012-08-22 09:27:31 -0700182
183 power_manager_.RemoveSuspendDelayCallback(kKey1);
Daniel Erat0818cca2012-12-14 10:16:21 -0800184 OnSuspendImminent(kSuspendId1);
Gary Morain43bc6272012-01-30 14:01:15 -0800185}
186
187typedef PowerManagerTest PowerManagerDeathTest;
188
Gary Morain52fabab2012-08-22 09:27:31 -0700189TEST_F(PowerManagerDeathTest, AddStateChangeCallbackDuplicateKey) {
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500190 power_manager_.AddStateChangeCallback(
Gary Morain52fabab2012-08-22 09:27:31 -0700191 kKey1, Bind(&PowerManagerTest::StateChangeAction1, Unretained(this)));
Gary Morain43bc6272012-01-30 14:01:15 -0800192
193#ifndef NDEBUG
194 // Adding another callback with the same key is an error and causes a crash in
195 // debug mode.
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500196 EXPECT_DEATH(power_manager_.AddStateChangeCallback(
Gary Morain52fabab2012-08-22 09:27:31 -0700197 kKey1, Bind(&PowerManagerTest::StateChangeAction2, Unretained(this))),
Gary Morain43bc6272012-01-30 14:01:15 -0800198 "Inserting duplicate key");
199#else // NDEBUG
Gary Morain52fabab2012-08-22 09:27:31 -0700200 EXPECT_CALL(*this, StateChangeAction2(PowerManagerProxyDelegate::kOn));
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500201 power_manager_.AddStateChangeCallback(
Gary Morain52fabab2012-08-22 09:27:31 -0700202 kKey1, Bind(&PowerManagerTest::StateChangeAction2, Unretained(this)));
Gary Morain43bc6272012-01-30 14:01:15 -0800203 factory_.delegate()->OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
204#endif // NDEBUG
205}
206
Gary Morain52fabab2012-08-22 09:27:31 -0700207TEST_F(PowerManagerDeathTest, RemoveStateChangeCallbackUnknownKey) {
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500208 power_manager_.AddStateChangeCallback(
Gary Morain52fabab2012-08-22 09:27:31 -0700209 kKey1, Bind(&PowerManagerTest::StateChangeAction1, Unretained(this)));
Gary Morain43bc6272012-01-30 14:01:15 -0800210
211#ifndef NDEBUG
212 // Attempting to remove a callback key that was not added is an error and
213 // crashes in debug mode.
214 EXPECT_DEATH(power_manager_.RemoveStateChangeCallback(kKey2),
215 "Removing unknown key");
216#else // NDEBUG
Gary Morain52fabab2012-08-22 09:27:31 -0700217 EXPECT_CALL(*this, StateChangeAction1(PowerManagerProxyDelegate::kOn));
Gary Morain43bc6272012-01-30 14:01:15 -0800218
219 // In non-debug mode, removing an unknown key does nothing.
220 power_manager_.RemoveStateChangeCallback(kKey2);
221 factory_.delegate()->OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
222#endif // NDEBUG
223}
224
Gary Morain52fabab2012-08-22 09:27:31 -0700225TEST_F(PowerManagerTest, RegisterSuspendDelay) {
Daniel Erat0818cca2012-12-14 10:16:21 -0800226 const base::TimeDelta kTimeout = base::TimeDelta::FromMilliseconds(100);
Daniel Eratf9753672013-01-24 10:17:02 -0800227 const char kDescription[] = "description";
Daniel Erat0818cca2012-12-14 10:16:21 -0800228 int delay_id = 0;
Daniel Eratf9753672013-01-24 10:17:02 -0800229 EXPECT_CALL(*factory_.proxy(), RegisterSuspendDelay(kTimeout, kDescription,
230 &delay_id))
Daniel Erat0818cca2012-12-14 10:16:21 -0800231 .WillOnce(Return(true));
Daniel Eratf9753672013-01-24 10:17:02 -0800232 EXPECT_TRUE(power_manager_.RegisterSuspendDelay(kTimeout, kDescription,
233 &delay_id));
Gary Morain52fabab2012-08-22 09:27:31 -0700234}
235
Darin Petkov3ec55342012-09-28 14:04:44 +0200236TEST_F(PowerManagerTest, UnregisterSuspendDelay) {
Daniel Erat0818cca2012-12-14 10:16:21 -0800237 const int kDelayId = 123;
238 EXPECT_CALL(*factory_.proxy(), UnregisterSuspendDelay(kDelayId))
239 .WillOnce(Return(true));
240 EXPECT_TRUE(power_manager_.UnregisterSuspendDelay(kDelayId));
Darin Petkov3ec55342012-09-28 14:04:44 +0200241}
242
Daniel Erat0818cca2012-12-14 10:16:21 -0800243TEST_F(PowerManagerTest, ReportSuspendReadiness) {
244 const int kDelayId = 678;
245 const int kSuspendId = 12345;
246 EXPECT_CALL(*factory_.proxy(), ReportSuspendReadiness(kDelayId, kSuspendId))
247 .WillOnce(Return(true));
248 EXPECT_TRUE(power_manager_.ReportSuspendReadiness(kDelayId, kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +0200249}
250
251TEST_F(PowerManagerTest, OnSuspendTimeout) {
252 EXPECT_EQ(PowerManagerProxyDelegate::kUnknown, power_manager_.power_state());
253 OnSuspendTimeout();
254 EXPECT_EQ(PowerManagerProxyDelegate::kOn, power_manager_.power_state());
255}
Gary Morain52fabab2012-08-22 09:27:31 -0700256
Gary Morain43bc6272012-01-30 14:01:15 -0800257} // namespace shill