// Copyright (c) 2012 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/metrics_collector.h"

#include <stdint.h>

#include <cmath>
#include <set>
#include <string>
#include <vector>

#include <base/format_macros.h>
#include <base/logging.h>
#include <base/timer/timer.h>
#include <chromeos/dbus/service_constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <metrics/metrics_library_mock.h>

#include "power_manager/common/fake_prefs.h"
#include "power_manager/common/metrics_constants.h"
#include "power_manager/common/metrics_sender.h"
#include "power_manager/common/power_constants.h"
#include "power_manager/powerd/policy/backlight_controller_stub.h"
#include "power_manager/powerd/system/power_supply.h"

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Mock;
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::Test;

namespace power_manager {

class MetricsCollectorTest : public Test {
 public:
  MetricsCollectorTest()
      : metrics_lib_(new StrictMock<MetricsLibraryMock>),
        metrics_sender_(
            scoped_ptr<MetricsLibraryInterface>(metrics_lib_)) {
    collector_.clock_.set_current_time_for_testing(
        base::TimeTicks::FromInternalValue(1000));
    collector_.clock_.set_current_wall_time_for_testing(
        base::Time::FromInternalValue(2000));

    power_status_.battery_percentage = 100.0;
    power_status_.battery_is_present = true;
  }

 protected:
  // Initializes |collector_|.
  void Init() {
    collector_.Init(&prefs_, &display_backlight_controller_,
                    &keyboard_backlight_controller_, power_status_);
  }

  // Advances both the monotonically-increasing time and wall time by
  // |interval|.
  void AdvanceTime(base::TimeDelta interval) {
    collector_.clock_.set_current_time_for_testing(
        collector_.clock_.GetCurrentTime() + interval);
    collector_.clock_.set_current_wall_time_for_testing(
        collector_.clock_.GetCurrentWallTime() + interval);
  }

  // Adds expectations to ignore all metrics sent by HandleSessionStateChange()
  // (except ones listed in |metrics_to_test_|).
  void IgnoreHandleSessionStateChangeMetrics() {
    IgnoreEnumMetric(MetricsCollector::AppendPowerSourceToEnumName(
        kMetricBatteryRemainingAtStartOfSessionName, POWER_AC));
    IgnoreEnumMetric(MetricsCollector::AppendPowerSourceToEnumName(
        kMetricBatteryRemainingAtStartOfSessionName, POWER_BATTERY));
    IgnoreEnumMetric(MetricsCollector::AppendPowerSourceToEnumName(
        kMetricBatteryRemainingAtEndOfSessionName, POWER_AC));
    IgnoreEnumMetric(MetricsCollector::AppendPowerSourceToEnumName(
        kMetricBatteryRemainingAtEndOfSessionName, POWER_BATTERY));
    IgnoreMetric(kMetricLengthOfSessionName);
    IgnoreMetric(kMetricNumberOfAlsAdjustmentsPerSessionName);
    IgnoreMetric(MetricsCollector::AppendPowerSourceToEnumName(
        kMetricUserBrightnessAdjustmentsPerSessionName, POWER_AC));
    IgnoreMetric(MetricsCollector::AppendPowerSourceToEnumName(
        kMetricUserBrightnessAdjustmentsPerSessionName, POWER_BATTERY));
  }

  // Adds expectations to ignore all metrics sent by HandlePowerStatusUpdate()
  // (except ones listed in |metrics_to_test_|).
  void IgnoreHandlePowerStatusUpdateMetrics() {
    IgnoreMetric(kMetricNumOfSessionsPerChargeName);
    IgnoreEnumMetric(kMetricBatteryRemainingWhenChargeStartsName);
    IgnoreEnumMetric(kMetricBatteryChargeHealthName);
    IgnoreMetric(kMetricBatteryDischargeRateName);
    IgnoreMetric(kMetricBatteryDischargeRateWhileSuspendedName);
    IgnoreEnumMetric(kMetricBatteryInfoSampleName);
  }

  // Updates |power_status_|'s |line_power_on| member and passes it to
  // HandlePowerStatusUpdate().
  void UpdatePowerStatusLinePower(bool line_power_on) {
    power_status_.line_power_on = line_power_on;
    collector_.HandlePowerStatusUpdate(power_status_);
  }

  // Adds a metrics library mock expectation that the specified metric
  // will be generated.
  void ExpectMetric(const std::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 enum
  // metric will be generated.
  void ExpectEnumMetric(const std::string& name, int sample, int max) {
    EXPECT_CALL(*metrics_lib_, SendEnumToUMA(name, sample, max))
        .Times(1)
        .WillOnce(Return(true))
        .RetiresOnSaturation();
  }

  // Ignores an arbitrary number of reports of |name|.
  void IgnoreMetric(const std::string& name) {
    if (metrics_to_test_.count(name))
      return;
    EXPECT_CALL(*metrics_lib_, SendToUMA(name, _, _, _, _))
        .Times(AnyNumber())
        .WillRepeatedly(Return(true));
  }

  // Ignores an arbitrary number of reports of |name|.
  void IgnoreEnumMetric(const std::string& name) {
    if (metrics_to_test_.count(name))
      return;
    EXPECT_CALL(*metrics_lib_, SendEnumToUMA(name, _, _))
        .Times(AnyNumber())
        .WillRepeatedly(Return(true));
  }

  void ExpectBatteryDischargeRateMetric(int sample) {
    ExpectMetric(kMetricBatteryDischargeRateName, sample,
                 kMetricBatteryDischargeRateMin,
                 kMetricBatteryDischargeRateMax,
                 kMetricDefaultBuckets);
  }

  void ExpectNumOfSessionsPerChargeMetric(int sample) {
    ExpectMetric(kMetricNumOfSessionsPerChargeName, sample,
                 kMetricNumOfSessionsPerChargeMin,
                 kMetricNumOfSessionsPerChargeMax,
                 kMetricDefaultBuckets);
  }

  FakePrefs prefs_;
  policy::BacklightControllerStub display_backlight_controller_;
  policy::BacklightControllerStub keyboard_backlight_controller_;
  system::PowerStatus power_status_;

  // StrictMock turns all unexpected calls into hard failures.
  StrictMock<MetricsLibraryMock>* metrics_lib_;  // Weak pointer.
  MetricsSender metrics_sender_;

  MetricsCollector collector_;

  // Names of metrics that will not be ignored by calls to Ignore*(). Tests
  // should insert the metrics that they're testing into this set and then call
  // Ignore*Metrics() (and call it again whenever expectations are cleared).
  std::set<std::string> metrics_to_test_;
};

TEST_F(MetricsCollectorTest, BacklightLevel) {
  power_status_.line_power_on = false;
  Init();
  ASSERT_TRUE(collector_.generate_backlight_metrics_timer_.IsRunning());
  collector_.HandleScreenDimmedChange(true, base::TimeTicks::Now());
  collector_.GenerateBacklightLevelMetrics();
  Mock::VerifyAndClearExpectations(metrics_lib_);

  const int64_t kCurrentDisplayPercent = 57;
  display_backlight_controller_.set_percent(kCurrentDisplayPercent);
  const int64_t kCurrentKeyboardPercent = 43;
  keyboard_backlight_controller_.set_percent(kCurrentKeyboardPercent);

  collector_.HandleScreenDimmedChange(false, base::TimeTicks::Now());
  ExpectEnumMetric(MetricsCollector::AppendPowerSourceToEnumName(
                       kMetricBacklightLevelName, POWER_BATTERY),
                   kCurrentDisplayPercent, kMetricMaxPercent);
  ExpectEnumMetric(kMetricKeyboardBacklightLevelName, kCurrentKeyboardPercent,
                   kMetricMaxPercent);
  collector_.GenerateBacklightLevelMetrics();

  power_status_.line_power_on = true;
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  ExpectEnumMetric(MetricsCollector::AppendPowerSourceToEnumName(
                       kMetricBacklightLevelName, POWER_AC),
                   kCurrentDisplayPercent, kMetricMaxPercent);
  ExpectEnumMetric(kMetricKeyboardBacklightLevelName, kCurrentKeyboardPercent,
                   kMetricMaxPercent);
  collector_.GenerateBacklightLevelMetrics();
}

TEST_F(MetricsCollectorTest, BatteryDischargeRate) {
  power_status_.line_power_on = false;
  Init();

  metrics_to_test_.insert(kMetricBatteryDischargeRateName);
  IgnoreHandlePowerStatusUpdateMetrics();

  // This much time must elapse before the discharge rate will be reported
  // again.
  const base::TimeDelta interval = base::TimeDelta::FromSeconds(
      kMetricBatteryDischargeRateInterval);

  power_status_.battery_energy_rate = 5.0;
  ExpectBatteryDischargeRateMetric(5000);
  collector_.HandlePowerStatusUpdate(power_status_);

  power_status_.battery_energy_rate = 4.5;
  ExpectBatteryDischargeRateMetric(4500);
  AdvanceTime(interval);
  collector_.HandlePowerStatusUpdate(power_status_);

  power_status_.battery_energy_rate = 6.4;
  ExpectBatteryDischargeRateMetric(6400);
  AdvanceTime(interval);
  collector_.HandlePowerStatusUpdate(power_status_);

  Mock::VerifyAndClearExpectations(metrics_lib_);
  IgnoreHandlePowerStatusUpdateMetrics();

  // Another update before the full interval has elapsed shouldn't result in
  // another report.
  AdvanceTime(interval / 2);
  collector_.HandlePowerStatusUpdate(power_status_);

  // Neither should a call while the energy rate is negative.
  AdvanceTime(interval);
  power_status_.battery_energy_rate = -4.0;
  collector_.HandlePowerStatusUpdate(power_status_);

  // Ditto for a call while the system is on AC power.
  power_status_.line_power_on = true;
  power_status_.battery_energy_rate = 4.0;
  collector_.HandlePowerStatusUpdate(power_status_);
}

TEST_F(MetricsCollectorTest, BatteryInfoWhenChargeStarts) {
  const double kBatteryPercentages[] = { 10.1, 10.7, 82.4, 82.5, 100.0 };

  power_status_.line_power_on = false;
  power_status_.battery_charge_full_design = 100.0;
  Init();

  metrics_to_test_.insert(kMetricBatteryRemainingWhenChargeStartsName);
  metrics_to_test_.insert(kMetricBatteryChargeHealthName);

  for (size_t i = 0; i < arraysize(kBatteryPercentages); ++i) {
    IgnoreHandlePowerStatusUpdateMetrics();

    power_status_.line_power_on = false;
    power_status_.battery_charge_full = kBatteryPercentages[i];
    power_status_.battery_percentage = kBatteryPercentages[i];
    collector_.HandlePowerStatusUpdate(power_status_);

    power_status_.line_power_on = true;
    ExpectEnumMetric(kMetricBatteryRemainingWhenChargeStartsName,
                     round(power_status_.battery_percentage),
                     kMetricMaxPercent);
    ExpectEnumMetric(kMetricBatteryChargeHealthName,
                     round(100.0 * power_status_.battery_charge_full /
                           power_status_.battery_charge_full_design),
                     kMetricBatteryChargeHealthMax);
    collector_.HandlePowerStatusUpdate(power_status_);

    Mock::VerifyAndClearExpectations(metrics_lib_);
  }
}

TEST_F(MetricsCollectorTest, SessionStartOrStop) {
  const uint kAlsAdjustments[] = { 0, 100 };
  const uint kUserAdjustments[] = { 0, 200 };
  const double kBatteryPercentages[] = { 10.5, 23.0 };
  const int kSessionSecs[] = { 900, kMetricLengthOfSessionMax + 10 };
  ASSERT_EQ(arraysize(kAlsAdjustments), arraysize(kUserAdjustments));
  ASSERT_EQ(arraysize(kAlsAdjustments), arraysize(kBatteryPercentages));
  ASSERT_EQ(arraysize(kAlsAdjustments), arraysize(kSessionSecs));

  power_status_.line_power_on = false;
  Init();

  for (size_t i = 0; i < arraysize(kAlsAdjustments); ++i) {
    IgnoreHandlePowerStatusUpdateMetrics();
    power_status_.battery_percentage = kBatteryPercentages[i];
    ExpectEnumMetric(
        MetricsCollector::AppendPowerSourceToEnumName(
            kMetricBatteryRemainingAtStartOfSessionName, POWER_BATTERY),
        round(kBatteryPercentages[i]), kMetricMaxPercent);
    collector_.HandlePowerStatusUpdate(power_status_);
    collector_.HandleSessionStateChange(SESSION_STARTED);
    Mock::VerifyAndClearExpectations(metrics_lib_);

    ExpectEnumMetric(
        MetricsCollector::AppendPowerSourceToEnumName(
            kMetricBatteryRemainingAtEndOfSessionName, POWER_BATTERY),
        round(kBatteryPercentages[i]), kMetricMaxPercent);

    display_backlight_controller_.set_num_als_adjustments(kAlsAdjustments[i]);
    display_backlight_controller_.set_num_user_adjustments(kUserAdjustments[i]);
    ExpectMetric(kMetricNumberOfAlsAdjustmentsPerSessionName,
                 kAlsAdjustments[i],
                 kMetricNumberOfAlsAdjustmentsPerSessionMin,
                 kMetricNumberOfAlsAdjustmentsPerSessionMax,
                 kMetricDefaultBuckets);
    ExpectMetric(
        MetricsCollector::AppendPowerSourceToEnumName(
            kMetricUserBrightnessAdjustmentsPerSessionName, POWER_BATTERY),
        kUserAdjustments[i],
        kMetricUserBrightnessAdjustmentsPerSessionMin,
        kMetricUserBrightnessAdjustmentsPerSessionMax,
        kMetricDefaultBuckets);

    AdvanceTime(base::TimeDelta::FromSeconds(kSessionSecs[i]));
    ExpectMetric(kMetricLengthOfSessionName,
                 kSessionSecs[i],
                 kMetricLengthOfSessionMin,
                 kMetricLengthOfSessionMax,
                 kMetricDefaultBuckets);

    collector_.HandleSessionStateChange(SESSION_STOPPED);
    Mock::VerifyAndClearExpectations(metrics_lib_);
  }
}

TEST_F(MetricsCollectorTest, GenerateNumOfSessionsPerChargeMetric) {
  metrics_to_test_.insert(kMetricNumOfSessionsPerChargeName);
  power_status_.line_power_on = false;
  Init();

  IgnoreHandlePowerStatusUpdateMetrics();
  UpdatePowerStatusLinePower(true);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // If the session is already started when going off line power, it should be
  // counted. Additional power status updates that don't describe a power source
  // change shouldn't increment the count.
  IgnoreHandleSessionStateChangeMetrics();
  collector_.HandleSessionStateChange(SESSION_STARTED);
  IgnoreHandlePowerStatusUpdateMetrics();
  UpdatePowerStatusLinePower(false);
  UpdatePowerStatusLinePower(false);
  UpdatePowerStatusLinePower(false);
  ExpectNumOfSessionsPerChargeMetric(1);
  UpdatePowerStatusLinePower(true);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // Sessions that start while on battery power should also be counted.
  IgnoreHandleSessionStateChangeMetrics();
  collector_.HandleSessionStateChange(SESSION_STOPPED);
  IgnoreHandlePowerStatusUpdateMetrics();
  UpdatePowerStatusLinePower(false);
  collector_.HandleSessionStateChange(SESSION_STARTED);
  collector_.HandleSessionStateChange(SESSION_STOPPED);
  collector_.HandleSessionStateChange(SESSION_STARTED);
  collector_.HandleSessionStateChange(SESSION_STOPPED);
  collector_.HandleSessionStateChange(SESSION_STARTED);
  ExpectNumOfSessionsPerChargeMetric(3);
  UpdatePowerStatusLinePower(true);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // Check that the pref is used, so the count will persist across reboots.
  IgnoreHandlePowerStatusUpdateMetrics();
  UpdatePowerStatusLinePower(false);
  prefs_.SetInt64(kNumSessionsOnCurrentChargePref, 5);
  ExpectNumOfSessionsPerChargeMetric(5);
  UpdatePowerStatusLinePower(true);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // Negative values in the pref should be ignored.
  prefs_.SetInt64(kNumSessionsOnCurrentChargePref, -2);
  IgnoreHandlePowerStatusUpdateMetrics();
  UpdatePowerStatusLinePower(false);
  ExpectNumOfSessionsPerChargeMetric(1);
  UpdatePowerStatusLinePower(true);
  Mock::VerifyAndClearExpectations(metrics_lib_);
}

TEST_F(MetricsCollectorTest, SendEnumMetric) {
  Init();
  ExpectEnumMetric("Dummy.EnumMetric", 50, 200);
  EXPECT_TRUE(SendEnumMetric("Dummy.EnumMetric", 50, 200));

  // Out-of-bounds values should be capped.
  ExpectEnumMetric("Dummy.EnumMetric2", 20, 20);
  EXPECT_TRUE(SendEnumMetric("Dummy.EnumMetric2", 21, 20));
}

TEST_F(MetricsCollectorTest, SendMetric) {
  Init();
  ExpectMetric("Dummy.Metric", 3, 1, 100, 50);
  EXPECT_TRUE(SendMetric("Dummy.Metric", 3, 1, 100, 50));

  // Out-of-bounds values should not be capped (so they can instead land in the
  // underflow or overflow bucket).
  ExpectMetric("Dummy.Metric2", -1, 0, 20, 4);
  EXPECT_TRUE(SendMetric("Dummy.Metric2", -1, 0, 20, 4));
  ExpectMetric("Dummy.Metric3", 30, 5, 25, 6);
  EXPECT_TRUE(SendMetric("Dummy.Metric3", 30, 5, 25, 6));
}

TEST_F(MetricsCollectorTest, SendMetricWithPowerSource) {
  power_status_.line_power_on = false;
  Init();
  ExpectMetric("Dummy.MetricOnBattery", 3, 1, 100, 50);
  EXPECT_TRUE(collector_.SendMetricWithPowerSource(
      "Dummy.Metric", 3, 1, 100, 50));

  IgnoreHandlePowerStatusUpdateMetrics();
  power_status_.line_power_on = true;
  collector_.HandlePowerStatusUpdate(power_status_);
  ExpectMetric("Dummy.MetricOnAC", 6, 2, 200, 80);
  EXPECT_TRUE(collector_.SendMetricWithPowerSource(
      "Dummy.Metric", 6, 2, 200, 80));
}

TEST_F(MetricsCollectorTest, PowerButtonDownMetric) {
  Init();

  // We should ignore a button release that wasn't preceded by a press.
  collector_.HandlePowerButtonEvent(BUTTON_UP);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // Presses that are followed by additional presses should also be ignored.
  collector_.HandlePowerButtonEvent(BUTTON_DOWN);
  collector_.HandlePowerButtonEvent(BUTTON_DOWN);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // Send a regular sequence of events and check that the duration is reported.
  collector_.HandlePowerButtonEvent(BUTTON_DOWN);
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(243);
  AdvanceTime(kDuration);
  ExpectMetric(kMetricPowerButtonDownTimeName,
               kDuration.InMilliseconds(),
               kMetricPowerButtonDownTimeMin,
               kMetricPowerButtonDownTimeMax,
               kMetricDefaultBuckets);
  collector_.HandlePowerButtonEvent(BUTTON_UP);
}

TEST_F(MetricsCollectorTest, GatherDarkResumeMetrics) {
  Init();

  std::vector<base::TimeDelta> wake_durations;
  base::TimeDelta suspend_duration;

  // First test the basic case.
  wake_durations.push_back(base::TimeDelta::FromSeconds(2));
  wake_durations.push_back(base::TimeDelta::FromSeconds(6));
  wake_durations.push_back(base::TimeDelta::FromMilliseconds(573));
  wake_durations.push_back(base::TimeDelta::FromSeconds(7));

  suspend_duration = base::TimeDelta::FromHours(2);

  ExpectMetric(kMetricDarkResumeWakeupsPerHourName,
               wake_durations.size() / suspend_duration.InHours(),
               kMetricDarkResumeWakeupsPerHourMin,
               kMetricDarkResumeWakeupsPerHourMax,
               kMetricDefaultBuckets);
  for (const base::TimeDelta& duration : wake_durations) {
    ExpectMetric(kMetricDarkResumeWakeDurationMsName,
                 duration.InMilliseconds(),
                 kMetricDarkResumeWakeDurationMsMin,
                 kMetricDarkResumeWakeDurationMsMax,
                 kMetricDefaultBuckets);
  }

  collector_.GenerateDarkResumeMetrics(wake_durations, suspend_duration);

  // If the suspend lasts for less than an hour, the wakeups per hour should be
  // scaled up.
  Mock::VerifyAndClearExpectations(metrics_lib_);
  wake_durations.clear();

  wake_durations.push_back(base::TimeDelta::FromMilliseconds(359));
  suspend_duration = base::TimeDelta::FromMinutes(13);

  IgnoreMetric(kMetricDarkResumeWakeDurationMsName);
  ExpectMetric(kMetricDarkResumeWakeupsPerHourName, 4,
               kMetricDarkResumeWakeupsPerHourMin,
               kMetricDarkResumeWakeupsPerHourMax,
               kMetricDefaultBuckets);

  collector_.GenerateDarkResumeMetrics(wake_durations, suspend_duration);
}

TEST_F(MetricsCollectorTest, BatteryDischargeRateWhileSuspended) {
  const double kEnergyBeforeSuspend = 60;
  const double kEnergyAfterResume = 50;
  const base::TimeDelta kSuspendDuration = base::TimeDelta::FromHours(1);

  metrics_to_test_.insert(kMetricBatteryDischargeRateWhileSuspendedName);
  power_status_.line_power_on = false;
  power_status_.battery_energy = kEnergyAfterResume;
  Init();

  // We shouldn't send a sample if we haven't suspended.
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // Ditto if the system is on AC before suspending...
  power_status_.line_power_on = true;
  power_status_.battery_energy = kEnergyBeforeSuspend;
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  collector_.PrepareForSuspend();
  AdvanceTime(kSuspendDuration);
  ExpectMetric(kMetricSuspendAttemptsBeforeSuccessName, 1,
               kMetricSuspendAttemptsMin, kMetricSuspendAttemptsMax,
               kMetricSuspendAttemptsBuckets);
  collector_.HandleResume(1);
  power_status_.line_power_on = false;
  power_status_.battery_energy = kEnergyAfterResume;
  collector_.HandlePowerStatusUpdate(power_status_);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // ... or after resuming...
  power_status_.line_power_on = false;
  power_status_.battery_energy = kEnergyBeforeSuspend;
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  collector_.PrepareForSuspend();
  AdvanceTime(kSuspendDuration);
  ExpectMetric(kMetricSuspendAttemptsBeforeSuccessName, 2,
               kMetricSuspendAttemptsMin, kMetricSuspendAttemptsMax,
               kMetricSuspendAttemptsBuckets);
  collector_.HandleResume(2);
  power_status_.line_power_on = true;
  power_status_.battery_energy = kEnergyAfterResume;
  collector_.HandlePowerStatusUpdate(power_status_);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // ... or if the battery's energy increased while the system was
  // suspended (i.e. it was temporarily connected to AC while suspended).
  power_status_.line_power_on = false;
  power_status_.battery_energy = kEnergyBeforeSuspend;
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  collector_.PrepareForSuspend();
  AdvanceTime(kSuspendDuration);
  ExpectMetric(kMetricSuspendAttemptsBeforeSuccessName, 1,
               kMetricSuspendAttemptsMin, kMetricSuspendAttemptsMax,
               kMetricSuspendAttemptsBuckets);
  collector_.HandleResume(1);
  power_status_.battery_energy = kEnergyBeforeSuspend + 5.0;
  collector_.HandlePowerStatusUpdate(power_status_);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // The sample also shouldn't be reported if the system wasn't suspended
  // for very long.
  power_status_.battery_energy = kEnergyBeforeSuspend;
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  collector_.PrepareForSuspend();
  AdvanceTime(base::TimeDelta::FromSeconds(
      kMetricBatteryDischargeRateWhileSuspendedMinSuspendSec - 1));
  ExpectMetric(kMetricSuspendAttemptsBeforeSuccessName, 1,
               kMetricSuspendAttemptsMin, kMetricSuspendAttemptsMax,
               kMetricSuspendAttemptsBuckets);
  collector_.HandleResume(1);
  power_status_.battery_energy = kEnergyAfterResume;
  collector_.HandlePowerStatusUpdate(power_status_);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // The sample should be reported if the energy decreased over a long
  // enough time.
  power_status_.battery_energy = kEnergyBeforeSuspend;
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  collector_.PrepareForSuspend();
  AdvanceTime(kSuspendDuration);
  ExpectMetric(kMetricSuspendAttemptsBeforeSuccessName, 1,
               kMetricSuspendAttemptsMin, kMetricSuspendAttemptsMax,
               kMetricSuspendAttemptsBuckets);
  collector_.HandleResume(1);
  power_status_.battery_energy = kEnergyAfterResume;
  const int rate_mw = static_cast<int>(round(
      1000 * (kEnergyBeforeSuspend - kEnergyAfterResume) /
      (kSuspendDuration.InSecondsF() / 3600)));
  ExpectMetric(kMetricBatteryDischargeRateWhileSuspendedName, rate_mw,
               kMetricBatteryDischargeRateWhileSuspendedMin,
               kMetricBatteryDischargeRateWhileSuspendedMax,
               kMetricDefaultBuckets);
  collector_.HandlePowerStatusUpdate(power_status_);
}

}  // namespace power_manager
