// 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();
}
