From 2ccef01626f9e97cb577b2968d307a2710b9cabe Mon Sep 17 00:00:00 2001 From: Darin Petkov Date: Wed, 5 May 2010 16:06:37 -0700 Subject: [PATCH] Add some basic tests for metrics_daemon. A separate CL adds a test stanza to the metrics ebuild. More tests (specifically, for the D-Bus MessageFilter) will also come in a separate CL. Review URL: http://codereview.chromium.org/1919005 --- metrics/Makefile | 14 +- metrics/make_tests.sh | 12 + metrics/metrics_daemon.cc | 67 +++-- metrics/metrics_daemon.h | 37 ++- metrics/metrics_daemon_main.cc | 2 +- metrics/metrics_daemon_test.cc | 459 +++++++++++++++++++++++++++++ metrics/metrics_daemon_unittest.cc | 10 - 7 files changed, 559 insertions(+), 42 deletions(-) create mode 100755 metrics/make_tests.sh create mode 100644 metrics/metrics_daemon_test.cc delete mode 100644 metrics/metrics_daemon_unittest.cc diff --git a/metrics/Makefile b/metrics/Makefile index 784ff91e8..cb85fb9ee 100644 --- a/metrics/Makefile +++ b/metrics/Makefile @@ -12,7 +12,7 @@ CXXFLAGS += -Wall -Werror -fPIC -fno-exceptions $(CCONFIG) CLIENT = metrics_client DAEMON = metrics_daemon -TESTDAEMON = test_daemon +DAEMON_TEST = metrics_daemon_test LIB = libmetrics.a SHAREDLIB = libmetrics.so @@ -25,12 +25,14 @@ DAEMON_OBJS = \ metrics_daemon_main.o TESTDAEMON_OBJS = \ metrics_daemon.o \ - metrics_daemon_unittest.o + metrics_daemon_test.o DAEMON_LDFLAGS = $(LDCONFIG) -lrt -lbase -lpthread -lgflags TESTDAEMON_LIBS = -lgtest -all: $(LIB) $(SHAREDLIB) $(CLIENT) $(DAEMON) $(TESTDAEMON) +all: $(LIB) $(SHAREDLIB) $(CLIENT) $(DAEMON) + +tests: $(DAEMON_TEST) $(CLIENT): $(CLIENT_OBJS) $(SHAREDLIB) $(CXX) $(LDFLAGS) $^ -o $@ @@ -38,11 +40,11 @@ $(CLIENT): $(CLIENT_OBJS) $(SHAREDLIB) $(DAEMON): $(DAEMON_OBJS) $(SHAREDLIB) $(CXX) -o $@ $^ $(DAEMON_LDFLAGS) -$(TESTDAEMON): $(TESTDAEMON_OBJS) $(SHAREDLIB) +$(DAEMON_TEST): $(TESTDAEMON_OBJS) $(SHAREDLIB) $(CXX) -o $@ $^ $(DAEMON_LDFLAGS) $(TESTDAEMON_LIBS) $(LIB): $(LIB_OBJS) - ar rcs $@ $^ + $(AR) rcs $@ $^ $(SHAREDLIB): $(LIB_OBJS) $(CXX) $(LDFLAGS) -shared $^ -o $@ @@ -56,7 +58,7 @@ metrics_daemon.o: \ metrics_daemon.h \ network_states.h \ power_states.h -metrics_daemon_unittest.o: \ +metrics_daemon_test.o: \ metrics_daemon.h \ network_states.h \ power_states.h diff --git a/metrics/make_tests.sh b/metrics/make_tests.sh new file mode 100755 index 000000000..9dcc80475 --- /dev/null +++ b/metrics/make_tests.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +# 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. + +# Builds tests. + +set -e +make tests +mkdir -p "${OUT_DIR}" +cp *_test "${OUT_DIR}" diff --git a/metrics/metrics_daemon.cc b/metrics/metrics_daemon.cc index ef973a236..da96dc2c6 100644 --- a/metrics/metrics_daemon.cc +++ b/metrics/metrics_daemon.cc @@ -37,6 +37,20 @@ static const int kSecondsPerDay = kMinutesPerDay * kSecondsPerMinute; static const int kUseMonitorIntervalInit = 1 * kSecondsPerMinute; static const int kUseMonitorIntervalMax = 10 * kSecondsPerMinute; +// static metrics parameters. +const char MetricsDaemon::kMetricDailyUseTimeName[] = + "Logging.DailyUseTime"; +const int MetricsDaemon::kMetricDailyUseTimeMin = 1; +const int MetricsDaemon::kMetricDailyUseTimeMax = kMinutesPerDay; +const int MetricsDaemon::kMetricDailyUseTimeBuckets = 50; + +const char MetricsDaemon::kMetricTimeToNetworkDropName[] = + "Network.TimeToDrop"; +const int MetricsDaemon::kMetricTimeToNetworkDropMin = 1; +const int MetricsDaemon::kMetricTimeToNetworkDropMax = + 8 /* hours */ * kMinutesPerHour * kSecondsPerMinute; +const int MetricsDaemon::kMetricTimeToNetworkDropBuckets = 50; + // static const char* MetricsDaemon::kDBusMatches_[] = { "type='signal'," @@ -86,8 +100,8 @@ const char* MetricsDaemon::kSessionStates_[] = { #include "session_states.h" }; -void MetricsDaemon::Run(bool run_as_daemon, bool testing) { - Init(testing); +void MetricsDaemon::Run(bool run_as_daemon) { + Init(false); if (!run_as_daemon || daemon(0, 0) == 0) { Loop(); } @@ -95,6 +109,11 @@ void MetricsDaemon::Run(bool run_as_daemon, bool testing) { void MetricsDaemon::Init(bool testing) { testing_ = testing; + daily_use_record_file_ = kDailyUseRecordFile; + + // Don't setup D-Bus and GLib in test mode. + if (testing) + return; g_thread_init(NULL); g_type_init(); @@ -192,17 +211,19 @@ void MetricsDaemon::NetStateChanged(const char* state_name, time_t now) { NetworkState state = LookupNetworkState(state_name); // Logs the time in seconds between the network going online to - // going offline in order to measure the mean time to network - // dropping. Going offline as part of suspend-to-RAM is not logged - // as network drop -- the assumption is that the message for - // suspend-to-RAM comes before the network offline message which - // seems to and should be the case. - if (state == kNetworkStateOffline && + // going offline (or, more precisely, going not online) in order to + // measure the mean time to network dropping. Going offline as part + // of suspend-to-RAM is not logged as network drop -- the assumption + // is that the message for suspend-to-RAM comes before the network + // offline message which seems to and should be the case. + if (state != kNetworkStateOnline && network_state_ == kNetworkStateOnline && power_state_ != kPowerStateMem) { int online_time = static_cast(now - network_state_last_); - PublishMetric("Network.TimeToDrop", online_time, - 1, 8 /* hours */ * 60 * 60, 50); + PublishMetric(kMetricTimeToNetworkDropName, online_time, + kMetricTimeToNetworkDropMin, + kMetricTimeToNetworkDropMax, + kMetricTimeToNetworkDropBuckets); } network_state_ = state; @@ -304,11 +325,11 @@ void MetricsDaemon::LogDailyUseRecord(int day, int seconds) { return; DLOG(INFO) << "day: " << day << " usage: " << seconds << " seconds"; - int fd = HANDLE_EINTR(open(kDailyUseRecordFile, + int fd = HANDLE_EINTR(open(daily_use_record_file_, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)); if (fd < 0) { - DLOG(WARNING) << "Unable to open the daily use file."; + PLOG(WARNING) << "Unable to open the daily use file"; return; } @@ -325,12 +346,14 @@ void MetricsDaemon::LogDailyUseRecord(int day, int seconds) { // the usage to the nearest minute and sends it to UMA. int minutes = (record.seconds_ + kSecondsPerMinute / 2) / kSecondsPerMinute; - PublishMetric("Logging.DailyUseTime", - minutes, 1, kMinutesPerDay, 50); + PublishMetric(kMetricDailyUseTimeName, minutes, + kMetricDailyUseTimeMin, + kMetricDailyUseTimeMax, + kMetricDailyUseTimeBuckets); // Truncates the usage file to ensure that no duplicate usage is // sent to UMA. - LOG_IF(WARNING, HANDLE_EINTR(ftruncate(fd, 0)) != 0); + PLOG_IF(WARNING, HANDLE_EINTR(ftruncate(fd, 0)) != 0); } } @@ -344,9 +367,10 @@ void MetricsDaemon::LogDailyUseRecord(int day, int seconds) { // else an already existing record for the same day will be // overwritten with updated usage below. - LOG_IF(WARNING, HANDLE_EINTR(lseek(fd, 0, SEEK_SET)) != 0); - LOG_IF(WARNING, - HANDLE_EINTR(write(fd, &record, sizeof(record))) != sizeof(record)); + PLOG_IF(WARNING, HANDLE_EINTR(lseek(fd, 0, SEEK_SET)) != 0); + PLOG_IF(WARNING, + HANDLE_EINTR(write(fd, &record, sizeof(record))) != + sizeof(record)); } HANDLE_EINTR(close(fd)); @@ -374,6 +398,9 @@ bool MetricsDaemon::UseMonitor() { bool MetricsDaemon::ScheduleUseMonitor(int interval, bool backoff) { + if (testing_) + return false; + // Caps the interval -- the bigger the interval, the more active use // time will be potentially dropped on system shutdown. if (interval > kUseMonitorIntervalMax) @@ -417,8 +444,8 @@ void MetricsDaemon::UnscheduleUseMonitor() { void MetricsDaemon::PublishMetric(const char* name, int sample, int min, int max, int nbuckets) { - DLOG(INFO) << "received metric: " << name << " " << sample << " " - << min << " " << max << " " << nbuckets; + LOG(INFO) << "received metric: " << name << " " << sample << " " + << min << " " << max << " " << nbuckets; if (!testing_) { MetricsLibrary::SendToChrome(name, sample, min, max, nbuckets); } diff --git a/metrics/metrics_daemon.h b/metrics/metrics_daemon.h index 99f76d087..028525a3d 100644 --- a/metrics/metrics_daemon.h +++ b/metrics/metrics_daemon.h @@ -9,11 +9,14 @@ #include #include +#include // for FRIEND_TEST + class MetricsDaemon { public: MetricsDaemon() - : network_state_(kUnknownNetworkState), + : daily_use_record_file_(NULL), + network_state_(kUnknownNetworkState), network_state_last_(0), power_state_(kUnknownPowerState), screensaver_state_(kUnknownScreenSaverState), @@ -26,11 +29,23 @@ class MetricsDaemon { ~MetricsDaemon() {} // Does all the work. If |run_as_daemon| is true, daemonizes by - // forking. If |testing| is true, logs the stats instead of sending - // them to Chrome. - void Run(bool run_as_daemon, bool testing); + // forking. + void Run(bool run_as_daemon); private: + friend class MetricsDaemonTest; + FRIEND_TEST(MetricsDaemonTest, LogDailyUseRecord); + FRIEND_TEST(MetricsDaemonTest, LookupNetworkState); + FRIEND_TEST(MetricsDaemonTest, LookupPowerState); + FRIEND_TEST(MetricsDaemonTest, LookupScreenSaverState); + FRIEND_TEST(MetricsDaemonTest, LookupSessionState); + FRIEND_TEST(MetricsDaemonTest, NetStateChanged); + FRIEND_TEST(MetricsDaemonTest, PowerStateChanged); + FRIEND_TEST(MetricsDaemonTest, PublishMetric); + FRIEND_TEST(MetricsDaemonTest, ScreenSaverStateChanged); + FRIEND_TEST(MetricsDaemonTest, SessionStateChanged); + FRIEND_TEST(MetricsDaemonTest, SetUserActiveState); + // The network states (see network_states.h). enum NetworkState { kUnknownNetworkState = -1, // Initial/unknown network state. @@ -71,6 +86,16 @@ class MetricsDaemon { int seconds_; }; + // Metric parameters. + static const char kMetricDailyUseTimeName[]; + static const int kMetricDailyUseTimeMin; + static const int kMetricDailyUseTimeMax; + static const int kMetricDailyUseTimeBuckets; + static const char kMetricTimeToNetworkDropName[]; + static const int kMetricTimeToNetworkDropMin; + static const int kMetricTimeToNetworkDropMax; + static const int kMetricTimeToNetworkDropBuckets; + // D-Bus message match strings. static const char* kDBusMatches_[]; @@ -161,9 +186,11 @@ class MetricsDaemon { void PublishMetric(const char* name, int sample, int min, int max, int nbuckets); - // Testing mode. + // Test mode. bool testing_; + const char* daily_use_record_file_; + // Current network state. NetworkState network_state_; diff --git a/metrics/metrics_daemon_main.cc b/metrics/metrics_daemon_main.cc index 302bdcb5e..7ace3334d 100644 --- a/metrics/metrics_daemon_main.cc +++ b/metrics/metrics_daemon_main.cc @@ -12,5 +12,5 @@ DEFINE_bool(daemon, true, "run as daemon (use -nodaemon for debugging)"); int main(int argc, char** argv) { MetricsDaemon::MetricsDaemon d; google::ParseCommandLineFlags(&argc, &argv, true); - d.Run(FLAGS_daemon, false); + d.Run(FLAGS_daemon); } diff --git a/metrics/metrics_daemon_test.cc b/metrics/metrics_daemon_test.cc new file mode 100644 index 000000000..043be7249 --- /dev/null +++ b/metrics/metrics_daemon_test.cc @@ -0,0 +1,459 @@ +// 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 "metrics_daemon.h" + +#include + +#include +#include +#include +#include +#include + +static const char kTestDailyUseRecordFile[] = "/tmp/daily-usage-test"; +static const char kDoesNotExistFile[] = "/does/not/exist"; + +static const int kSecondsPerDay = 24 * 60 * 60; + +class MetricsDaemonTest : public testing::Test { + protected: + virtual void SetUp() { + daemon_.Init(true); + daemon_.daily_use_record_file_ = kTestDailyUseRecordFile; + + // The test fixture object will be used by the log message handler. + daemon_test_ = this; + logging::SetLogMessageHandler(LogMessageHandler); + } + + virtual void TearDown() { + logging::SetLogMessageHandler(NULL); + daemon_test_ = NULL; + file_util::Delete(FilePath(kTestDailyUseRecordFile), false); + } + + // Collects log messages in the |daemon_log_| member string so that + // they can be analyzed for errors and expected behavior. + static bool LogMessageHandler(int severity, const std::string& str) { + daemon_test_->daemon_log_.append(str); + daemon_test_->daemon_log_.append("\n"); + + // Returning true would mute the log. + return false; + } + + // Returns true if the daemon log contains |pattern|, false otherwise. + bool LogContains(const std::string& pattern) { + return daemon_log_.find(pattern) != std::string::npos; + } + + // Resets the daemon log history to empty. + void LogReset() { + daemon_log_.clear(); + } + + // Returns true if the specified metric is found in the generated + // log so far, false otherwise. + bool AssertMetricGenerated(const std::string& name, int sample, + int min, int max, int buckets) { + return LogContains(StringPrintf("received metric: %s %d %d %d %d", + name.c_str(), sample, min, max, buckets)); + } + + // Returns true if the specified daily use time metric is found in + // the generated log so far, false otherwise. + bool AssertDailyUseTimeMetric(int sample) { + return AssertMetricGenerated( + MetricsDaemon::kMetricDailyUseTimeName, sample, + MetricsDaemon::kMetricDailyUseTimeMin, + MetricsDaemon::kMetricDailyUseTimeMax, + MetricsDaemon::kMetricDailyUseTimeBuckets); + } + + // Returns true if the specified time to network drop metric is + // found in the generated log so far, false otherwise. + bool AssertTimeToNetworkDropMetric(int sample) { + return AssertMetricGenerated( + MetricsDaemon::kMetricTimeToNetworkDropName, sample, + MetricsDaemon::kMetricTimeToNetworkDropMin, + MetricsDaemon::kMetricTimeToNetworkDropMax, + MetricsDaemon::kMetricTimeToNetworkDropBuckets); + } + + // Returns true if no metric can be found in the generated log so + // far, false otherwise. + bool NoMetricGenerated() { + return !LogContains("received metric"); + } + + // Asserts that the daily use record file contains the specified + // contents. + testing::AssertionResult AssertDailyUseRecord(const char* expr_day, + const char* expr_seconds, + int expected_day, + int expected_seconds) { + int fd = HANDLE_EINTR(open(daemon_.daily_use_record_file_, O_RDONLY)); + if (fd < 0) { + testing::Message msg; + msg << "Unable to open " << daemon_.daily_use_record_file_; + return testing::AssertionFailure(msg); + } + + MetricsDaemon::UseRecord record; + if (!file_util::ReadFromFD(fd, reinterpret_cast(&record), + sizeof(record))) { + testing::Message msg; + msg << "Unable to read " << sizeof(record) << " bytes from " + << daemon_.daily_use_record_file_; + HANDLE_EINTR(close(fd)); + return testing::AssertionFailure(msg); + } + + if (record.day_ != expected_day || record.seconds_ != expected_seconds) { + testing::Message msg; + msg << "actual use record (" << record.day_ << ", " << record.seconds_ + << ") expected (" << expected_day << ", " << expected_seconds << ")"; + HANDLE_EINTR(close(fd)); + return testing::AssertionFailure(msg); + } + + HANDLE_EINTR(close(fd)); + return testing::AssertionSuccess(); + } + + bool NoOrEmptyUseRecordFile() { + FilePath record_file(daemon_.daily_use_record_file_); + int64 record_file_size; + return !file_util::PathExists(record_file) || + (file_util::GetFileSize(record_file, &record_file_size) && + record_file_size == 0); + } + + // Pointer to the current test fixture. + static MetricsDaemonTest* daemon_test_; + + // The MetricsDaemon under test. + MetricsDaemon daemon_; + + // The accumulated metrics daemon log. + std::string daemon_log_; +}; + +// static +MetricsDaemonTest* MetricsDaemonTest::daemon_test_ = NULL; + +TEST_F(MetricsDaemonTest, LogDailyUseRecord) { + EXPECT_EQ(0, daemon_.daily_use_day_last_); + EXPECT_TRUE(NoOrEmptyUseRecordFile()); + + daemon_.LogDailyUseRecord(/* day */ 5, /* seconds */ 120); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 5, /* seconds */ 120); + EXPECT_EQ(5, daemon_.daily_use_day_last_); + + daemon_.LogDailyUseRecord(/* day */ 5, /* seconds */ 0); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 5, /* seconds */ 120); + EXPECT_EQ(5, daemon_.daily_use_day_last_); + + daemon_.LogDailyUseRecord(/* day */ 5, /* seconds */ 240); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 5, /* seconds */ 360); + EXPECT_EQ(5, daemon_.daily_use_day_last_); + + EXPECT_TRUE(NoMetricGenerated()); + + LogReset(); + daemon_.LogDailyUseRecord(/* day */ 6, /* seconds */ 0); + EXPECT_TRUE(NoOrEmptyUseRecordFile()); + EXPECT_TRUE(AssertDailyUseTimeMetric(/* sample */ 6)); + EXPECT_EQ(6, daemon_.daily_use_day_last_); + + // Tests rounding use time to the closest minute. + daemon_.LogDailyUseRecord(/* day */ 6, /* seconds */ 90); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 6, /* seconds */ 90); + EXPECT_EQ(6, daemon_.daily_use_day_last_); + + LogReset(); + daemon_.LogDailyUseRecord(/* day */ 7, /* seconds */ 89); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 7, /* seconds */ 89); + EXPECT_TRUE(AssertDailyUseTimeMetric(/* sample */ 2)); + EXPECT_EQ(7, daemon_.daily_use_day_last_); + + LogReset(); + daemon_.LogDailyUseRecord(/* day */ 6, /* seconds */ 15); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 6, /* seconds */ 15); + EXPECT_TRUE(AssertDailyUseTimeMetric(/* sample */ 1)); + EXPECT_EQ(6, daemon_.daily_use_day_last_); + + // Checks that the daemon doesn't die badly if the file can't be + // created. + LogReset(); + daemon_.daily_use_record_file_ = kDoesNotExistFile; + daemon_.LogDailyUseRecord(10, 20); + EXPECT_TRUE(LogContains("Unable to open the daily use file: " + "No such file or directory")); + EXPECT_EQ(6, daemon_.daily_use_day_last_); + file_util::Delete(FilePath(kDoesNotExistFile), false); +} + +TEST_F(MetricsDaemonTest, LookupNetworkState) { + EXPECT_EQ(MetricsDaemon::kNetworkStateOnline, + daemon_.LookupNetworkState("online")); + EXPECT_EQ(MetricsDaemon::kNetworkStateOffline, + daemon_.LookupNetworkState("offline")); + EXPECT_EQ(MetricsDaemon::kUnknownNetworkState, + daemon_.LookupNetworkState("somestate")); +} + +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, LookupScreenSaverState) { + EXPECT_EQ(MetricsDaemon::kScreenSaverStateLocked, + daemon_.LookupScreenSaverState("locked")); + EXPECT_EQ(MetricsDaemon::kScreenSaverStateUnlocked, + daemon_.LookupScreenSaverState("unlocked")); + EXPECT_EQ(MetricsDaemon::kUnknownScreenSaverState, + daemon_.LookupScreenSaverState("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, NetStateChanged) { + EXPECT_EQ(MetricsDaemon::kUnknownNetworkState, daemon_.network_state_); + EXPECT_EQ(0, daemon_.network_state_last_); + EXPECT_EQ(MetricsDaemon::kUnknownPowerState, daemon_.power_state_); + + daemon_.NetStateChanged("online", /* now */ 10); + EXPECT_EQ(MetricsDaemon::kNetworkStateOnline, daemon_.network_state_); + EXPECT_EQ(10, daemon_.network_state_last_); + + EXPECT_TRUE(NoMetricGenerated()); + + daemon_.NetStateChanged("offline", /* now */ 30); + EXPECT_EQ(MetricsDaemon::kNetworkStateOffline, daemon_.network_state_); + EXPECT_EQ(30, daemon_.network_state_last_); + EXPECT_TRUE(AssertTimeToNetworkDropMetric(/* sample */ 20)); + + LogReset(); + daemon_.NetStateChanged("online", /* now */ 60); + EXPECT_EQ(MetricsDaemon::kNetworkStateOnline, daemon_.network_state_); + EXPECT_EQ(60, daemon_.network_state_last_); + + daemon_.PowerStateChanged("mem", /* now */ 80); + EXPECT_EQ(MetricsDaemon::kPowerStateMem, daemon_.power_state_); + EXPECT_EQ(MetricsDaemon::kNetworkStateOnline, daemon_.network_state_); + EXPECT_EQ(60, daemon_.network_state_last_); + + daemon_.NetStateChanged("offline", /* now */ 85); + EXPECT_EQ(MetricsDaemon::kNetworkStateOffline, daemon_.network_state_); + EXPECT_EQ(85, daemon_.network_state_last_); + + daemon_.NetStateChanged("somestate", /* now */ 90); + EXPECT_EQ(MetricsDaemon::kUnknownNetworkState, daemon_.network_state_); + EXPECT_EQ(90, daemon_.network_state_last_); + + daemon_.NetStateChanged("offline", /* now */ 95); + EXPECT_EQ(MetricsDaemon::kNetworkStateOffline, daemon_.network_state_); + EXPECT_EQ(95, daemon_.network_state_last_); + + daemon_.PowerStateChanged("on", /* now */ 100); + EXPECT_EQ(MetricsDaemon::kPowerStateOn, daemon_.power_state_); + EXPECT_EQ(MetricsDaemon::kNetworkStateOffline, daemon_.network_state_); + EXPECT_EQ(95, daemon_.network_state_last_); + + daemon_.NetStateChanged("online", /* now */ 105); + EXPECT_EQ(MetricsDaemon::kNetworkStateOnline, daemon_.network_state_); + EXPECT_EQ(105, daemon_.network_state_last_); + + EXPECT_TRUE(NoMetricGenerated()); + + daemon_.NetStateChanged("offline", /* now */ 108); + EXPECT_EQ(MetricsDaemon::kNetworkStateOffline, daemon_.network_state_); + EXPECT_EQ(108, daemon_.network_state_last_); + EXPECT_TRUE(AssertTimeToNetworkDropMetric(/* sample */ 3)); +} + +TEST_F(MetricsDaemonTest, PowerStateChanged) { + EXPECT_EQ(MetricsDaemon::kUnknownPowerState, daemon_.power_state_); + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(0, daemon_.user_active_last_); + EXPECT_EQ(0, daemon_.daily_use_day_last_); + EXPECT_TRUE(NoOrEmptyUseRecordFile()); + + daemon_.SetUserActiveState(/* active */ true, 7 * kSecondsPerDay + 15); + EXPECT_TRUE(daemon_.user_active_); + EXPECT_EQ(7 * kSecondsPerDay + 15, daemon_.user_active_last_); + EXPECT_EQ(7, daemon_.daily_use_day_last_); + EXPECT_TRUE(NoOrEmptyUseRecordFile()); + + daemon_.PowerStateChanged("mem", 7 * kSecondsPerDay + 45); + EXPECT_EQ(MetricsDaemon::kPowerStateMem, daemon_.power_state_); + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(7 * kSecondsPerDay + 45, daemon_.user_active_last_); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 7, /* seconds */ 30); + + daemon_.PowerStateChanged("on", 7 * kSecondsPerDay + 85); + EXPECT_EQ(MetricsDaemon::kPowerStateOn, daemon_.power_state_); + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(7 * kSecondsPerDay + 45, daemon_.user_active_last_); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 7, /* seconds */ 30); + + daemon_.PowerStateChanged("otherstate", 7 * kSecondsPerDay + 185); + EXPECT_EQ(MetricsDaemon::kUnknownPowerState, daemon_.power_state_); + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(7 * kSecondsPerDay + 185, daemon_.user_active_last_); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 7, /* seconds */ 30); + + EXPECT_TRUE(NoMetricGenerated()); +} + +TEST_F(MetricsDaemonTest, PublishMetric) { + daemon_.PublishMetric("Dummy.Metric", /* sample */ 3, + /* min */ 1, /* max */ 100, /* buckets */ 50); + EXPECT_TRUE(AssertMetricGenerated("Dummy.Metric", 3, 1, 100, 50)); +} + +TEST_F(MetricsDaemonTest, ScreenSaverStateChanged) { + EXPECT_EQ(MetricsDaemon::kUnknownScreenSaverState, + daemon_.screensaver_state_); + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(0, daemon_.user_active_last_); + EXPECT_EQ(0, daemon_.daily_use_day_last_); + EXPECT_TRUE(NoOrEmptyUseRecordFile()); + + daemon_.ScreenSaverStateChanged("locked", 5 * kSecondsPerDay + 10); + EXPECT_EQ(MetricsDaemon::kScreenSaverStateLocked, + daemon_.screensaver_state_); + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(5 * kSecondsPerDay + 10, daemon_.user_active_last_); + EXPECT_EQ(5, daemon_.daily_use_day_last_); + EXPECT_TRUE(NoOrEmptyUseRecordFile()); + + daemon_.ScreenSaverStateChanged("unlocked", 5 * kSecondsPerDay + 100); + EXPECT_EQ(MetricsDaemon::kScreenSaverStateUnlocked, + daemon_.screensaver_state_); + EXPECT_TRUE(daemon_.user_active_); + EXPECT_EQ(5 * kSecondsPerDay + 100, daemon_.user_active_last_); + EXPECT_TRUE(NoOrEmptyUseRecordFile()); + + daemon_.ScreenSaverStateChanged("otherstate", 5 * kSecondsPerDay + 300); + EXPECT_EQ(MetricsDaemon::kUnknownScreenSaverState, + daemon_.screensaver_state_); + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(5 * kSecondsPerDay + 300, daemon_.user_active_last_); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 5, /* seconds */ 200); + + EXPECT_TRUE(NoMetricGenerated()); +} + +TEST_F(MetricsDaemonTest, SessionStateChanged) { + EXPECT_EQ(MetricsDaemon::kUnknownSessionState, daemon_.session_state_); + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(0, daemon_.user_active_last_); + EXPECT_EQ(0, daemon_.daily_use_day_last_); + EXPECT_TRUE(NoOrEmptyUseRecordFile()); + + daemon_.SessionStateChanged("started", 15 * kSecondsPerDay + 20); + EXPECT_EQ(MetricsDaemon::kSessionStateStarted, daemon_.session_state_); + EXPECT_TRUE(daemon_.user_active_); + EXPECT_EQ(15 * kSecondsPerDay + 20, daemon_.user_active_last_); + EXPECT_EQ(15, daemon_.daily_use_day_last_); + EXPECT_TRUE(NoOrEmptyUseRecordFile()); + + daemon_.SessionStateChanged("stopped", 15 * kSecondsPerDay + 150); + EXPECT_EQ(MetricsDaemon::kSessionStateStopped, daemon_.session_state_); + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(15 * kSecondsPerDay + 150, daemon_.user_active_last_); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 15, /* seconds */ 130); + + daemon_.SessionStateChanged("otherstate", 15 * kSecondsPerDay + 300); + EXPECT_EQ(MetricsDaemon::kUnknownSessionState, daemon_.session_state_); + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(15 * kSecondsPerDay + 300, daemon_.user_active_last_); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 15, /* seconds */ 130); + + EXPECT_TRUE(NoMetricGenerated()); +} + +TEST_F(MetricsDaemonTest, SetUserActiveState) { + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(0, daemon_.user_active_last_); + EXPECT_EQ(0, daemon_.daily_use_day_last_); + EXPECT_TRUE(NoOrEmptyUseRecordFile()); + + daemon_.SetUserActiveState(/* active */ false, 5 * kSecondsPerDay + 10); + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(5 * kSecondsPerDay + 10, daemon_.user_active_last_); + EXPECT_EQ(5, daemon_.daily_use_day_last_); + EXPECT_TRUE(NoOrEmptyUseRecordFile()); + + daemon_.SetUserActiveState(/* active */ true, 6 * kSecondsPerDay + 20); + EXPECT_TRUE(daemon_.user_active_); + EXPECT_EQ(6 * kSecondsPerDay + 20, daemon_.user_active_last_); + EXPECT_EQ(6, daemon_.daily_use_day_last_); + EXPECT_TRUE(NoOrEmptyUseRecordFile()); + + daemon_.SetUserActiveState(/* active */ true, 6 * kSecondsPerDay + 120); + EXPECT_TRUE(daemon_.user_active_); + EXPECT_EQ(6 * kSecondsPerDay + 120, daemon_.user_active_last_); + EXPECT_EQ(6, daemon_.daily_use_day_last_); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 6, /* seconds */ 100); + + daemon_.SetUserActiveState(/* active */ false, 6 * kSecondsPerDay + 220); + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(6 * kSecondsPerDay + 220, daemon_.user_active_last_); + EXPECT_EQ(6, daemon_.daily_use_day_last_); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 6, /* seconds */ 200); + + EXPECT_TRUE(NoMetricGenerated()); + + LogReset(); + daemon_.SetUserActiveState(/* active */ true, 8 * kSecondsPerDay - 300); + EXPECT_TRUE(daemon_.user_active_); + EXPECT_EQ(8 * kSecondsPerDay - 300, daemon_.user_active_last_); + EXPECT_EQ(7, daemon_.daily_use_day_last_); + EXPECT_TRUE(NoOrEmptyUseRecordFile()); + EXPECT_TRUE(AssertDailyUseTimeMetric(/* sample */ 3)); + + LogReset(); + daemon_.SetUserActiveState(/* active */ false, 8 * kSecondsPerDay + 300); + EXPECT_FALSE(daemon_.user_active_); + EXPECT_EQ(8 * kSecondsPerDay + 300, daemon_.user_active_last_); + EXPECT_EQ(8, daemon_.daily_use_day_last_); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 8, /* seconds */ 600); + + daemon_.SetUserActiveState(/* active */ true, 9 * kSecondsPerDay - 400); + EXPECT_TRUE(daemon_.user_active_); + EXPECT_EQ(9 * kSecondsPerDay - 400, daemon_.user_active_last_); + EXPECT_EQ(8, daemon_.daily_use_day_last_); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 8, /* seconds */ 600); + + EXPECT_TRUE(NoMetricGenerated()); + + LogReset(); + daemon_.SetUserActiveState(/* active */ true, 9 * kSecondsPerDay + 400); + EXPECT_TRUE(daemon_.user_active_); + EXPECT_EQ(9 * kSecondsPerDay + 400, daemon_.user_active_last_); + EXPECT_EQ(9, daemon_.daily_use_day_last_); + EXPECT_PRED_FORMAT2(AssertDailyUseRecord, /* day */ 9, /* seconds */ 800); + EXPECT_TRUE(AssertDailyUseTimeMetric(/* sample */ 10)); +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/metrics/metrics_daemon_unittest.cc b/metrics/metrics_daemon_unittest.cc deleted file mode 100644 index 222cefab7..000000000 --- a/metrics/metrics_daemon_unittest.cc +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) 2009 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 "metrics_daemon.h" - -int main(int argc, char** argv) { - MetricsDaemon d; - d.Run(false, true); -}