blob: 2bdef5c37ebcc536126f85dd19ed8567aa73e0ed [file] [log] [blame]
// Copyright (c) 2013 The Chromium OS 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 "power_manager/powerd/policy/dark_resume_policy.h"
#include <cmath>
#include <limits>
#include <map>
#include <string>
#include <base/files/scoped_temp_dir.h>
#include <base/file_util.h>
#include <base/logging.h>
#include <base/memory/scoped_ptr.h>
#include <base/strings/string_number_conversions.h>
#include <gtest/gtest.h>
#include "power_manager/common/fake_prefs.h"
#include "power_manager/common/power_constants.h"
#include "power_manager/powerd/system/power_supply.h"
#include "power_manager/powerd/system/udev_stub.h"
using std::map;
using std::string;
namespace {
const char kOnline[] = "1";
const char kOffline[] = "0";
const char kPresent[] = "1";
const char kACType[] = "Mains";
const char kBatteryType[] = "Battery";
const double kChargeFull = 2.40;
// sysfs stores doubles by multiplying them by 1000000 and storing as an int.
int ScaleDouble(double value) {
return round(value * 1000000);
}
} // namespace
namespace power_manager {
namespace policy {
class DarkResumePolicyTest : public ::testing::Test {
public:
DarkResumePolicyTest() {}
virtual void SetUp() {
temp_dir_generator_.reset(new base::ScopedTempDir());
ASSERT_TRUE(temp_dir_generator_->CreateUniqueTempDir());
ASSERT_TRUE(temp_dir_generator_->IsValid());
path_ = temp_dir_generator_->path();
base::CreateDirectory(path_.Append("ac"));
base::CreateDirectory(path_.Append("battery"));
power_supply_.reset(new system::PowerSupply);
dark_resume_policy_.reset(new DarkResumePolicy);
}
protected:
// Initializes |power_supply_| and |dark_resume_policy_|.
void Init() {
power_supply_->Init(path_, &prefs_, &udev_);
SetBattery(100.0, false);
dark_resume_policy_->Init(power_supply_.get(), &prefs_);
}
void SetBattery(double charge_percent, bool ac_online) {
map<string, string> values;
values["ac/type"] = kACType;
values["battery/type"] = kBatteryType;
values["battery/present"] = kPresent;
values["battery/charge_full"] = base::IntToString(ScaleDouble(kChargeFull));
values["battery/charge_full_design"] =
base::IntToString(ScaleDouble(kChargeFull));
values["battery/charge_now"] = base::IntToString(
ScaleDouble(charge_percent * kChargeFull / 100.0));
if (ac_online)
values["ac/online"] = kOnline;
else
values["ac/online"] = kOffline;
for (map<string, string>::iterator iter = values.begin();
iter != values.end();
++iter) {
base::WriteFile(path_.Append(iter->first),
iter->second.c_str(), iter->second.length());
}
ASSERT_TRUE(power_supply_->RefreshImmediately());
ASSERT_DOUBLE_EQ(charge_percent,
power_supply_->power_status().battery_percentage);
}
FakePrefs prefs_;
scoped_ptr<base::ScopedTempDir> temp_dir_generator_;
base::FilePath path_;
system::UdevStub udev_;
scoped_ptr<system::PowerSupply> power_supply_;
scoped_ptr<DarkResumePolicy> dark_resume_policy_;
};
// Test that GetAction will return SHUTDOWN if the preferences are correct.
TEST_F(DarkResumePolicyTest, TestShutdown) {
prefs_.SetString(kDarkResumeBatteryMarginsPref, "0.0 -1.0");
prefs_.SetString(kDarkResumeSuspendDurationsPref, "0.0 10");
Init();
EXPECT_EQ(DarkResumePolicy::SHUT_DOWN, dark_resume_policy_->GetAction());
}
// Test that GetAction will first return SUSPEND_FOR_DURATION then SHUT_DOWN
// after the battery charge changes and the power is unplugged.
TEST_F(DarkResumePolicyTest, TestSuspendFirst) {
prefs_.SetString(kDarkResumeBatteryMarginsPref, "0.0 0.0");
prefs_.SetString(kDarkResumeSuspendDurationsPref, "0.0 10");
Init();
EXPECT_EQ(DarkResumePolicy::SUSPEND_FOR_DURATION,
dark_resume_policy_->GetAction());
SetBattery(50.0, false);
EXPECT_EQ(DarkResumePolicy::SHUT_DOWN, dark_resume_policy_->GetAction());
}
// Test that state is not maintained after a user resume and that the proper
// suspend durations are returned.
TEST_F(DarkResumePolicyTest, TestUserResumes) {
prefs_.SetString(kDarkResumeBatteryMarginsPref, "0.0 0.0\n"
"20.0 2.0\n"
"50.0 5.0\n"
"80.0 8.0");
prefs_.SetString(kDarkResumeSuspendDurationsPref, "0.0 10\n"
"20.0 50\n"
"50.0 100\n"
"80.0 500");
Init();
EXPECT_EQ(DarkResumePolicy::SUSPEND_FOR_DURATION,
dark_resume_policy_->GetAction());
EXPECT_EQ(500, dark_resume_policy_->GetSuspendDuration().InSeconds());
dark_resume_policy_->HandleResume();
SetBattery(80.0, false);
EXPECT_EQ(DarkResumePolicy::SUSPEND_FOR_DURATION,
dark_resume_policy_->GetAction());
EXPECT_EQ(500, dark_resume_policy_->GetSuspendDuration().InSeconds());
dark_resume_policy_->HandleResume();
SetBattery(50.0, false);
EXPECT_EQ(DarkResumePolicy::SUSPEND_FOR_DURATION,
dark_resume_policy_->GetAction());
EXPECT_EQ(100, dark_resume_policy_->GetSuspendDuration().InSeconds());
dark_resume_policy_->HandleResume();
SetBattery(20.0, false);
EXPECT_EQ(DarkResumePolicy::SUSPEND_FOR_DURATION,
dark_resume_policy_->GetAction());
EXPECT_EQ(50, dark_resume_policy_->GetSuspendDuration().InSeconds());
dark_resume_policy_->HandleResume();
SetBattery(5.0, false);
EXPECT_EQ(DarkResumePolicy::SUSPEND_FOR_DURATION,
dark_resume_policy_->GetAction());
EXPECT_EQ(10, dark_resume_policy_->GetSuspendDuration().InSeconds());
}
// Check that we don't shutdown when the AC is online (regardless of battery
// life).
TEST_F(DarkResumePolicyTest, TestACOnline) {
prefs_.SetString(kDarkResumeBatteryMarginsPref, "0.0 0.0");
prefs_.SetString(kDarkResumeSuspendDurationsPref, "0.0 10");
Init();
EXPECT_EQ(DarkResumePolicy::SUSPEND_FOR_DURATION,
dark_resume_policy_->GetAction());
SetBattery(50.0, true);
EXPECT_EQ(DarkResumePolicy::SUSPEND_FOR_DURATION,
dark_resume_policy_->GetAction());
}
// Check that setting the pref disable_dark_resume to 1 disables dark resume and
// that setting it to 0 enables it.
TEST_F(DarkResumePolicyTest, TestDisable) {
prefs_.SetInt64(kDisableDarkResumePref, 1);
prefs_.SetString(kDarkResumeBatteryMarginsPref, "0.0 0.0");
prefs_.SetString(kDarkResumeSuspendDurationsPref, "0.0 10");
Init();
EXPECT_EQ(DarkResumePolicy::SUSPEND_INDEFINITELY,
dark_resume_policy_->GetAction());
}
TEST_F(DarkResumePolicyTest, TestEnable) {
prefs_.SetInt64(kDisableDarkResumePref, 0);
prefs_.SetString(kDarkResumeBatteryMarginsPref, "0.0 0.0");
prefs_.SetString(kDarkResumeSuspendDurationsPref, "0.0 10");
Init();
EXPECT_EQ(DarkResumePolicy::SUSPEND_FOR_DURATION,
dark_resume_policy_->GetAction());
}
} // namespace policy
} // namespace power_manager