blob: 208d8e5bffae1cb6fa2c23a1bbf6df36794e1f03 [file] [log] [blame]
// Copyright (c) 2010 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 <utime.h>
#include <string>
#include <vector>
#include <base/file_util.h>
#include <base/stringprintf.h>
#include <gtest/gtest.h>
#include "counter_mock.h"
#include "metrics_daemon.h"
#include "metrics_library_mock.h"
using base::Time;
using base::TimeTicks;
using chromeos_metrics::FrequencyCounter;
using chromeos_metrics::FrequencyCounterMock;
using chromeos_metrics::TaggedCounterMock;
using chromeos_metrics::TaggedCounterReporter;
using chromeos_metrics::TaggedCounterReporterMock;
using std::string;
using std::vector;
using ::testing::_;
using ::testing::Return;
using ::testing::StrictMock;
static const int kSecondsPerDay = 24 * 60 * 60;
static const char kTestDir[] = "test";
static const char kLastFile[] = "test/last";
static const char kCurrentFile[] = "test/current";
static const char kFakeDiskStatsPath[] = "fake-disk-stats";
static const char kFakeDiskStatsFormat[] =
" 1793 1788 %d 105580 "
" 196 175 %d 30290 "
" 0 44060 135850\n";
static string kFakeDiskStats[2];
static const int kFakeReadSectors[] = {80000, 100000};
static const int kFakeWriteSectors[] = {3000, 4000};
// This class allows a TimeTicks object to be initialized with seconds
// (rather than microseconds) through the protected TimeTicks(int64)
// constructor.
class TestTicks : public TimeTicks {
public:
TestTicks(int64 seconds)
: TimeTicks(seconds * Time::kMicrosecondsPerSecond) {}
};
// Overloaded for test failure printing purposes.
static std::ostream& operator<<(std::ostream& o, const Time& time) {
o << time.ToInternalValue() << "us";
return o;
};
class MetricsDaemonTest : public testing::Test {
protected:
virtual void SetUp() {
EXPECT_EQ(NULL, daemon_.daily_use_.get());
EXPECT_EQ(NULL, daemon_.kernel_crash_interval_.get());
EXPECT_EQ(NULL, daemon_.user_crash_interval_.get());
kFakeDiskStats[0] = StringPrintf(kFakeDiskStatsFormat,
kFakeReadSectors[0], kFakeWriteSectors[0]);
kFakeDiskStats[1] = StringPrintf(kFakeDiskStatsFormat,
kFakeReadSectors[1], kFakeWriteSectors[1]);
CreateFakeDiskStatsFile(kFakeDiskStats[0].c_str());
daemon_.Init(true, &metrics_lib_, kFakeDiskStatsPath);
// Check configuration of a few histograms.
FrequencyCounter* frequency_counter =
daemon_.frequency_counters_[MetricsDaemon::kMetricAnyCrashesDailyName];
const TaggedCounterReporter* reporter = GetReporter(frequency_counter);
EXPECT_EQ(MetricsDaemon::kMetricAnyCrashesDailyName,
reporter->histogram_name());
EXPECT_EQ(chromeos_metrics::kSecondsPerDay,
frequency_counter->cycle_duration());
EXPECT_EQ(MetricsDaemon::kMetricCrashFrequencyMin, reporter->min());
EXPECT_EQ(MetricsDaemon::kMetricCrashFrequencyMax, reporter->max());
EXPECT_EQ(MetricsDaemon::kMetricCrashFrequencyBuckets, reporter->buckets());
frequency_counter =
daemon_.frequency_counters_[MetricsDaemon::kMetricAnyCrashesWeeklyName];
reporter = GetReporter(frequency_counter);
EXPECT_EQ(MetricsDaemon::kMetricAnyCrashesWeeklyName,
reporter->histogram_name());
EXPECT_EQ(chromeos_metrics::kSecondsPerWeek,
frequency_counter->cycle_duration());
EXPECT_EQ(MetricsDaemon::kMetricKernelCrashIntervalName,
daemon_.kernel_crash_interval_->histogram_name());
EXPECT_EQ(MetricsDaemon::kMetricCrashIntervalMin,
daemon_.kernel_crash_interval_->min());
EXPECT_EQ(MetricsDaemon::kMetricCrashIntervalMax,
daemon_.kernel_crash_interval_->max());
EXPECT_EQ(MetricsDaemon::kMetricCrashIntervalBuckets,
daemon_.kernel_crash_interval_->buckets());
EXPECT_EQ(MetricsDaemon::kMetricUncleanShutdownIntervalName,
daemon_.unclean_shutdown_interval_->histogram_name());
// Tests constructor initialization. Switches to mock counters.
EXPECT_TRUE(NULL != daemon_.daily_use_.get());
EXPECT_TRUE(NULL != daemon_.kernel_crash_interval_.get());
EXPECT_TRUE(NULL != daemon_.user_crash_interval_.get());
// Allocates mock counter and transfers ownership.
daily_use_ = new StrictMock<TaggedCounterMock>();
daemon_.daily_use_.reset(daily_use_);
kernel_crash_interval_ = new StrictMock<TaggedCounterReporterMock>();
daemon_.kernel_crash_interval_.reset(kernel_crash_interval_);
user_crash_interval_ = new StrictMock<TaggedCounterReporterMock>();
daemon_.user_crash_interval_.reset(user_crash_interval_);
unclean_shutdown_interval_ = new StrictMock<TaggedCounterReporterMock>();
daemon_.unclean_shutdown_interval_.reset(unclean_shutdown_interval_);
// Reset all frequency counter reporters to mocks for further testing.
MetricsDaemon::FrequencyCounters::iterator i;
for (i = daemon_.frequency_counters_.begin();
i != daemon_.frequency_counters_.end(); ++i) {
delete i->second;
i->second = new StrictMock<FrequencyCounterMock>();
}
EXPECT_FALSE(daemon_.user_active_);
EXPECT_TRUE(daemon_.user_active_last_.is_null());
EXPECT_EQ(MetricsDaemon::kUnknownPowerState, daemon_.power_state_);
EXPECT_EQ(MetricsDaemon::kUnknownSessionState, daemon_.session_state_);
file_util::Delete(FilePath(kTestDir), true);
file_util::CreateDirectory(FilePath(kTestDir));
}
virtual void TearDown() {
EXPECT_EQ(unlink(kFakeDiskStatsPath), 0);
}
const TaggedCounterReporter*
GetReporter(FrequencyCounter* frequency_counter) const {
return static_cast<const TaggedCounterReporter*>(
&frequency_counter->tagged_counter());
}
void ExpectFrequencyFlushCalls() {
MetricsDaemon::FrequencyCounters::iterator i;
for (i = daemon_.frequency_counters_.begin();
i != daemon_.frequency_counters_.end(); ++i) {
FrequencyCounterMock* mock =
static_cast<FrequencyCounterMock*>(i->second);
EXPECT_CALL(*mock, FlushFinishedCycles());
}
}
// Adds active use aggregation counters update expectations that the
// specified tag/count update will be generated.
void ExpectActiveUseUpdate(int daily_tag, int count) {
EXPECT_CALL(*daily_use_, Update(daily_tag, count))
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*kernel_crash_interval_, Update(0, count))
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*user_crash_interval_, Update(0, count))
.Times(1)
.RetiresOnSaturation();
ExpectFrequencyFlushCalls();
}
// Adds active use aggregation counters update expectations that
// ignore the update arguments.
void IgnoreActiveUseUpdate() {
EXPECT_CALL(*daily_use_, Update(_, _))
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*kernel_crash_interval_, Update(_, _))
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*user_crash_interval_, Update(_, _))
.Times(1)
.RetiresOnSaturation();
ExpectFrequencyFlushCalls();
}
// Adds a metrics library mock expectation that the specified metric
// will be generated.
void ExpectMetric(const string& name, int sample,
int min, int max, int buckets) {
EXPECT_CALL(metrics_lib_, SendToUMA(name, sample, min, max, buckets))
.Times(1)
.WillOnce(Return(true))
.RetiresOnSaturation();
}
// Adds a metrics library mock expectation that the specified daily
// use time metric will be generated.
void ExpectDailyUseTimeMetric(int sample) {
ExpectMetric(MetricsDaemon::kMetricDailyUseTimeName, sample,
MetricsDaemon::kMetricDailyUseTimeMin,
MetricsDaemon::kMetricDailyUseTimeMax,
MetricsDaemon::kMetricDailyUseTimeBuckets);
}
// Converts from seconds to a Time object.
Time TestTime(int64 seconds) {
return Time::FromInternalValue(seconds * Time::kMicrosecondsPerSecond);
}
// Creates a new DBus signal message with zero or more string arguments.
// The message can be deallocated through DeleteDBusMessage.
//
// |path| is the object emitting the signal.
// |interface| is the interface the signal is emitted from.
// |name| is the name of the signal.
// |arg_values| contains the values of the string arguments.
DBusMessage* NewDBusSignalString(const string& path,
const string& interface,
const string& name,
const vector<string>& arg_values) {
DBusMessage* msg = dbus_message_new_signal(path.c_str(),
interface.c_str(),
name.c_str());
DBusMessageIter iter;
dbus_message_iter_init_append(msg, &iter);
for (vector<string>::const_iterator it = arg_values.begin();
it != arg_values.end(); ++it) {
const char* str_value = it->c_str();
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &str_value);
}
return msg;
}
// Deallocates the DBus message |msg| previously allocated through
// dbus_message_new*.
void DeleteDBusMessage(DBusMessage* msg) {
dbus_message_unref(msg);
}
// Gets the frequency counter for the given name.
FrequencyCounterMock& GetFrequencyMock(const char* histogram_name) {
return *static_cast<FrequencyCounterMock*>(
daemon_.frequency_counters_[histogram_name]);
}
// Creates or overwrites an input file containing fake disk stats.
void CreateFakeDiskStatsFile(const char* fake_stats) {
if (unlink(kFakeDiskStatsPath) < 0) {
EXPECT_EQ(errno, ENOENT);
}
FILE* f = fopen(kFakeDiskStatsPath, "w");
EXPECT_EQ(1, fwrite(fake_stats, strlen(fake_stats), 1, f));
EXPECT_EQ(0, fclose(f));
}
// The MetricsDaemon under test.
MetricsDaemon daemon_;
// Metrics library mock. It's a strict mock so that all unexpected
// metric generation calls are marked as failures.
StrictMock<MetricsLibraryMock> metrics_lib_;
// Counter mocks. They are strict mocks so that all unexpected
// update calls are marked as failures. They are pointers so that
// they can replace the scoped_ptr's allocated by the daemon.
StrictMock<TaggedCounterMock>* daily_use_;
StrictMock<TaggedCounterReporterMock>* kernel_crash_interval_;
StrictMock<TaggedCounterReporterMock>* user_crash_interval_;
StrictMock<TaggedCounterReporterMock>* unclean_shutdown_interval_;
};
TEST_F(MetricsDaemonTest, CheckSystemCrash) {
static const char kKernelCrashDetected[] = "test-kernel-crash-detected";
EXPECT_FALSE(daemon_.CheckSystemCrash(kKernelCrashDetected));
FilePath crash_detected(kKernelCrashDetected);
file_util::WriteFile(crash_detected, "", 0);
EXPECT_TRUE(file_util::PathExists(crash_detected));
EXPECT_TRUE(daemon_.CheckSystemCrash(kKernelCrashDetected));
EXPECT_FALSE(file_util::PathExists(crash_detected));
EXPECT_FALSE(daemon_.CheckSystemCrash(kKernelCrashDetected));
EXPECT_FALSE(file_util::PathExists(crash_detected));
file_util::Delete(crash_detected, false);
}
TEST_F(MetricsDaemonTest, ReportDailyUse) {
ExpectDailyUseTimeMetric(/* sample */ 2);
MetricsDaemon::ReportDailyUse(&daemon_, /* tag */ 20, /* count */ 90);
ExpectDailyUseTimeMetric(/* sample */ 1);
MetricsDaemon::ReportDailyUse(&daemon_, /* tag */ 23, /* count */ 89);
// There should be no metrics generated for the calls below.
MetricsDaemon::ReportDailyUse(&daemon_, /* tag */ 50, /* count */ 0);
MetricsDaemon::ReportDailyUse(&daemon_, /* tag */ 60, /* count */ -5);
}
TEST_F(MetricsDaemonTest, LookupPowerState) {
EXPECT_EQ(MetricsDaemon::kPowerStateOn,
daemon_.LookupPowerState("on"));
EXPECT_EQ(MetricsDaemon::kPowerStateMem,
daemon_.LookupPowerState("mem"));
EXPECT_EQ(MetricsDaemon::kUnknownPowerState,
daemon_.LookupPowerState("somestate"));
}
TEST_F(MetricsDaemonTest, LookupSessionState) {
EXPECT_EQ(MetricsDaemon::kSessionStateStarted,
daemon_.LookupSessionState("started"));
EXPECT_EQ(MetricsDaemon::kSessionStateStopped,
daemon_.LookupSessionState("stopped"));
EXPECT_EQ(MetricsDaemon::kUnknownSessionState,
daemon_.LookupSessionState("somestate"));
}
TEST_F(MetricsDaemonTest, MessageFilter) {
DBusMessage* msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
DBusHandlerResult res =
MetricsDaemon::MessageFilter(/* connection */ NULL, msg, &daemon_);
EXPECT_EQ(DBUS_HANDLER_RESULT_NOT_YET_HANDLED, res);
DeleteDBusMessage(msg);
IgnoreActiveUseUpdate();
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricAnyCrashesDailyName),
Update(1))
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricAnyCrashesWeeklyName),
Update(1))
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricUserCrashesDailyName),
Update(1))
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricUserCrashesWeeklyName),
Update(1))
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*user_crash_interval_, Flush())
.Times(1)
.RetiresOnSaturation();
vector<string> signal_args;
msg = NewDBusSignalString("/",
"org.chromium.CrashReporter",
"UserCrash",
signal_args);
res = MetricsDaemon::MessageFilter(/* connection */ NULL, msg, &daemon_);
EXPECT_EQ(DBUS_HANDLER_RESULT_HANDLED, res);
DeleteDBusMessage(msg);
signal_args.clear();
signal_args.push_back("on");
msg = NewDBusSignalString("/",
"org.chromium.PowerManager",
"PowerStateChanged",
signal_args);
EXPECT_EQ(MetricsDaemon::kUnknownPowerState, daemon_.power_state_);
res = MetricsDaemon::MessageFilter(/* connection */ NULL, msg, &daemon_);
EXPECT_EQ(MetricsDaemon::kPowerStateOn, daemon_.power_state_);
EXPECT_EQ(DBUS_HANDLER_RESULT_HANDLED, res);
DeleteDBusMessage(msg);
signal_args.clear();
IgnoreActiveUseUpdate();
msg = NewDBusSignalString("/",
"org.chromium.PowerManager",
"ScreenIsUnlocked",
signal_args);
EXPECT_FALSE(daemon_.user_active_);
res = MetricsDaemon::MessageFilter(/* connection */ NULL, msg, &daemon_);
EXPECT_TRUE(daemon_.user_active_);
EXPECT_EQ(DBUS_HANDLER_RESULT_HANDLED, res);
DeleteDBusMessage(msg);
IgnoreActiveUseUpdate();
signal_args.clear();
signal_args.push_back("started");
signal_args.push_back("bob"); // arbitrary username
msg = NewDBusSignalString("/org/chromium/SessionManager",
"org.chromium.SessionManagerInterface",
"SessionStateChanged",
signal_args);
EXPECT_EQ(MetricsDaemon::kUnknownSessionState, daemon_.session_state_);
res = MetricsDaemon::MessageFilter(/* connection */ NULL, msg, &daemon_);
EXPECT_EQ(MetricsDaemon::kSessionStateStarted, daemon_.session_state_);
EXPECT_EQ(DBUS_HANDLER_RESULT_HANDLED, res);
DeleteDBusMessage(msg);
signal_args.clear();
signal_args.push_back("randomstate");
signal_args.push_back("bob"); // arbitrary username
msg = NewDBusSignalString("/",
"org.chromium.UnknownService.Manager",
"StateChanged",
signal_args);
res = MetricsDaemon::MessageFilter(/* connection */ NULL, msg, &daemon_);
EXPECT_EQ(DBUS_HANDLER_RESULT_NOT_YET_HANDLED, res);
DeleteDBusMessage(msg);
}
TEST_F(MetricsDaemonTest, PowerStateChanged) {
ExpectActiveUseUpdate(7, 0);
daemon_.SetUserActiveState(/* active */ true,
TestTime(7 * kSecondsPerDay + 15));
EXPECT_TRUE(daemon_.user_active_);
EXPECT_EQ(TestTime(7 * kSecondsPerDay + 15), daemon_.user_active_last_);
ExpectActiveUseUpdate(7, 30);
daemon_.PowerStateChanged("mem", TestTime(7 * kSecondsPerDay + 45));
EXPECT_EQ(MetricsDaemon::kPowerStateMem, daemon_.power_state_);
EXPECT_FALSE(daemon_.user_active_);
EXPECT_EQ(TestTime(7 * kSecondsPerDay + 45), daemon_.user_active_last_);
daemon_.PowerStateChanged("on", TestTime(7 * kSecondsPerDay + 85));
EXPECT_EQ(MetricsDaemon::kPowerStateOn, daemon_.power_state_);
EXPECT_FALSE(daemon_.user_active_);
EXPECT_EQ(TestTime(7 * kSecondsPerDay + 45), daemon_.user_active_last_);
ExpectActiveUseUpdate(7, 0);
daemon_.PowerStateChanged("otherstate", TestTime(7 * kSecondsPerDay + 185));
EXPECT_EQ(MetricsDaemon::kUnknownPowerState, daemon_.power_state_);
EXPECT_FALSE(daemon_.user_active_);
EXPECT_EQ(TestTime(7 * kSecondsPerDay + 185), daemon_.user_active_last_);
}
TEST_F(MetricsDaemonTest, ProcessKernelCrash) {
IgnoreActiveUseUpdate();
EXPECT_CALL(*kernel_crash_interval_, Flush())
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricAnyCrashesDailyName),
Update(1));
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricAnyCrashesWeeklyName),
Update(1));
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricKernelCrashesDailyName),
Update(1));
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricKernelCrashesWeeklyName),
Update(1));
daemon_.ProcessKernelCrash();
}
TEST_F(MetricsDaemonTest, ProcessUncleanShutdown) {
IgnoreActiveUseUpdate();
EXPECT_CALL(*unclean_shutdown_interval_, Flush())
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricAnyCrashesDailyName),
Update(1));
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricAnyCrashesWeeklyName),
Update(1));
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricUncleanShutdownsDailyName),
Update(1));
EXPECT_CALL(
GetFrequencyMock(MetricsDaemon::kMetricUncleanShutdownsWeeklyName),
Update(1));
daemon_.ProcessUncleanShutdown();
}
TEST_F(MetricsDaemonTest, ProcessUserCrash) {
IgnoreActiveUseUpdate();
EXPECT_CALL(*user_crash_interval_, Flush())
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricAnyCrashesDailyName),
Update(1));
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricAnyCrashesWeeklyName),
Update(1));
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricUserCrashesDailyName),
Update(1));
EXPECT_CALL(GetFrequencyMock(MetricsDaemon::kMetricUserCrashesWeeklyName),
Update(1));
daemon_.ProcessUserCrash();
}
TEST_F(MetricsDaemonTest, SendMetric) {
ExpectMetric("Dummy.Metric", 3, 1, 100, 50);
daemon_.SendMetric("Dummy.Metric", /* sample */ 3,
/* min */ 1, /* max */ 100, /* buckets */ 50);
}
TEST_F(MetricsDaemonTest, SessionStateChanged) {
ExpectActiveUseUpdate(15, 0);
daemon_.SessionStateChanged("started", TestTime(15 * kSecondsPerDay + 20));
EXPECT_EQ(MetricsDaemon::kSessionStateStarted, daemon_.session_state_);
EXPECT_TRUE(daemon_.user_active_);
EXPECT_EQ(TestTime(15 * kSecondsPerDay + 20), daemon_.user_active_last_);
ExpectActiveUseUpdate(15, 130);
daemon_.SessionStateChanged("stopped", TestTime(15 * kSecondsPerDay + 150));
EXPECT_EQ(MetricsDaemon::kSessionStateStopped, daemon_.session_state_);
EXPECT_FALSE(daemon_.user_active_);
EXPECT_EQ(TestTime(15 * kSecondsPerDay + 150), daemon_.user_active_last_);
ExpectActiveUseUpdate(15, 0);
daemon_.SessionStateChanged("otherstate",
TestTime(15 * kSecondsPerDay + 300));
EXPECT_EQ(MetricsDaemon::kUnknownSessionState, daemon_.session_state_);
EXPECT_FALSE(daemon_.user_active_);
EXPECT_EQ(TestTime(15 * kSecondsPerDay + 300), daemon_.user_active_last_);
}
TEST_F(MetricsDaemonTest, SetUserActiveState) {
ExpectActiveUseUpdate(5, 0);
daemon_.SetUserActiveState(/* active */ false,
TestTime(5 * kSecondsPerDay + 10));
EXPECT_FALSE(daemon_.user_active_);
EXPECT_EQ(TestTime(5 * kSecondsPerDay + 10), daemon_.user_active_last_);
ExpectActiveUseUpdate(6, 0);
daemon_.SetUserActiveState(/* active */ true,
TestTime(6 * kSecondsPerDay + 20));
EXPECT_TRUE(daemon_.user_active_);
EXPECT_EQ(TestTime(6 * kSecondsPerDay + 20), daemon_.user_active_last_);
ExpectActiveUseUpdate(6, 100);
daemon_.SetUserActiveState(/* active */ true,
TestTime(6 * kSecondsPerDay + 120));
EXPECT_TRUE(daemon_.user_active_);
EXPECT_EQ(TestTime(6 * kSecondsPerDay + 120), daemon_.user_active_last_);
ExpectActiveUseUpdate(6, 110);
daemon_.SetUserActiveState(/* active */ false,
TestTime(6 * kSecondsPerDay + 230));
EXPECT_FALSE(daemon_.user_active_);
EXPECT_EQ(TestTime(6 * kSecondsPerDay + 230), daemon_.user_active_last_);
ExpectActiveUseUpdate(6, 0);
daemon_.SetUserActiveState(/* active */ false,
TestTime(6 * kSecondsPerDay + 260));
EXPECT_FALSE(daemon_.user_active_);
EXPECT_EQ(TestTime(6 * kSecondsPerDay + 260), daemon_.user_active_last_);
}
TEST_F(MetricsDaemonTest, SetUserActiveStateTimeJump) {
ExpectActiveUseUpdate(10, 0);
daemon_.SetUserActiveState(/* active */ true,
TestTime(10 * kSecondsPerDay + 500));
EXPECT_TRUE(daemon_.user_active_);
EXPECT_EQ(TestTime(10 * kSecondsPerDay + 500), daemon_.user_active_last_);
ExpectActiveUseUpdate(10, 0);
daemon_.SetUserActiveState(/* active */ true,
TestTime(10 * kSecondsPerDay + 300));
EXPECT_TRUE(daemon_.user_active_);
EXPECT_EQ(TestTime(10 * kSecondsPerDay + 300), daemon_.user_active_last_);
ExpectActiveUseUpdate(10, 0);
daemon_.SetUserActiveState(/* active */ true,
TestTime(10 * kSecondsPerDay + 1000));
EXPECT_TRUE(daemon_.user_active_);
EXPECT_EQ(TestTime(10 * kSecondsPerDay + 1000), daemon_.user_active_last_);
}
TEST_F(MetricsDaemonTest, GetHistogramPath) {
EXPECT_EQ("/var/log/metrics/Logging.AnyCrashesDaily",
daemon_.GetHistogramPath(
MetricsDaemon::kMetricAnyCrashesDailyName).value());
}
TEST_F(MetricsDaemonTest, ReportDiskStats) {
long int read_sectors_now, write_sectors_now;
CreateFakeDiskStatsFile(kFakeDiskStats[1].c_str());
daemon_.DiskStatsReadStats(&read_sectors_now, &write_sectors_now);
EXPECT_EQ(read_sectors_now, kFakeReadSectors[1]);
EXPECT_EQ(write_sectors_now, kFakeWriteSectors[1]);
MetricsDaemon::DiskStatsState ds_state = daemon_.diskstats_state_;
EXPECT_CALL(metrics_lib_,
SendToUMA(_, (kFakeReadSectors[1] - kFakeReadSectors[0]) / 30,
_, _, _));
EXPECT_CALL(metrics_lib_,
SendToUMA(_, (kFakeWriteSectors[1] - kFakeWriteSectors[0]) / 30,
_, _, _));
daemon_.DiskStatsCallback();
EXPECT_TRUE(ds_state != daemon_.diskstats_state_);
}
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}