blob: 8997e77b402b4373978e78d1522dd31e1fc0ba85 [file] [log] [blame]
// Copyright 2015 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 <memory>
#include <string>
#include "base/callback.h"
#include "base/callback_list.h"
#include "base/time/time.h"
#include "base/timer/mock_timer.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "metrics/metrics_library_mock.h"
#include "thermald/key_value_publisher.h"
#include "thermald/metrics_reporter.h"
#include "thermald/mock_temperature_monitor.h"
using std::string;
using std::unique_ptr;
using testing::_;
using testing::AnyNumber;
namespace thermald {
static const char *kTemperatureHistogramPrefix =
"Platform.Thermal.Temperature.";
static const char *kThermalStateHistogramZone0 =
"Platform.Thermal.Zone.Zone 0.States";
static const char *kThermalStateHistogramZone1 =
"Platform.Thermal.Zone.Zone 1.States";
class MetricsReporterTest : public testing::Test {
protected:
MetricsReporterTest();
~MetricsReporterTest();
unique_ptr<MetricsReporter> metrics_reporter_;
KeyValuePublisher output_publisher_;
unique_ptr<MockTemperatureMonitor> temp_monitor_0_;
unique_ptr<MockTemperatureMonitor> temp_monitor_1_;
base::MockRepeatingTimer *metrics_timer_;
static MetricsLibraryMock metrics_lib_;
};
MetricsLibraryMock MetricsReporterTest::metrics_lib_;
MetricsReporterTest::MetricsReporterTest() {
temp_monitor_0_.reset(new MockTemperatureMonitor("temperature 0"));
temp_monitor_1_.reset(new MockTemperatureMonitor("temperature 1"));
metrics_reporter_.reset(new MetricsReporter("Platform",
&output_publisher_,
&metrics_lib_,
base::TimeDelta::FromSeconds(1)));
metrics_timer_ = new base::MockRepeatingTimer();
metrics_reporter_->timer_.reset(metrics_timer_);
}
MetricsReporterTest::~MetricsReporterTest() {
EXPECT_CALL(*temp_monitor_0_.get(), OnSubscriberRemoved()).Times(AnyNumber());
EXPECT_CALL(*temp_monitor_1_.get(), OnSubscriberRemoved()).Times(AnyNumber());
// Make sure the MetricsReporter unsubscribes from the temperature monitors
// before they are deleted.
metrics_reporter_.reset();
}
TEST_F(MetricsReporterTest, StartsMetricsTimerOnStart) {
metrics_reporter_->Start();
ASSERT_TRUE(metrics_timer_->IsRunning());
metrics_reporter_->Stop();
}
TEST_F(MetricsReporterTest, StopsMetricsTimerOnStop) {
metrics_reporter_->Start();
metrics_reporter_->Stop();
ASSERT_FALSE(metrics_timer_->IsRunning());
}
TEST_F(MetricsReporterTest, SubscribesToTemperatureMonitor) {
EXPECT_CALL(*temp_monitor_0_.get(), Subscribe());
metrics_reporter_->AddTemperature(temp_monitor_0_->name(),
temp_monitor_0_.get());
}
TEST_F(MetricsReporterTest, ReportsTemperatures) {
EXPECT_CALL(*temp_monitor_0_.get(), Subscribe());
EXPECT_CALL(*temp_monitor_1_.get(), Subscribe());
metrics_reporter_->AddTemperature(temp_monitor_0_->name(),
temp_monitor_0_.get());
metrics_reporter_->AddTemperature(temp_monitor_1_->name(),
temp_monitor_1_.get());
metrics_reporter_->Start();
EXPECT_CALL(metrics_lib_, SendToUMA(kTemperatureHistogramPrefix +
temp_monitor_0_->name(), 42, _, _, _));
EXPECT_CALL(metrics_lib_, SendToUMA(kTemperatureHistogramPrefix +
temp_monitor_1_->name(), 37, _, _, _));
temp_monitor_0_->NotifySubscribers(42000);
temp_monitor_1_->NotifySubscribers(37000);
metrics_timer_->Fire();
}
TEST_F(MetricsReporterTest, ReportsLatestTemperature) {
EXPECT_CALL(*temp_monitor_0_.get(), Subscribe());
metrics_reporter_->AddTemperature(temp_monitor_0_->name(),
temp_monitor_0_.get());
metrics_reporter_->Start();
EXPECT_CALL(metrics_lib_, SendToUMA(kTemperatureHistogramPrefix +
temp_monitor_0_->name(), 42, _, _, _));
temp_monitor_0_->NotifySubscribers(37000);
temp_monitor_0_->NotifySubscribers(42000);
metrics_timer_->Fire();
}
TEST_F(MetricsReporterTest,
DoesNotReportUnknownTemperatures) {
EXPECT_CALL(*temp_monitor_0_.get(), Subscribe());
EXPECT_CALL(*temp_monitor_1_.get(), Subscribe());
metrics_reporter_->AddTemperature(temp_monitor_0_->name(),
temp_monitor_0_.get());
metrics_reporter_->AddTemperature(temp_monitor_1_->name(),
temp_monitor_1_.get());
metrics_reporter_->Start();
EXPECT_CALL(metrics_lib_, SendToUMA(kTemperatureHistogramPrefix +
temp_monitor_0_->name(),
_, _, _, _)).Times(0);
EXPECT_CALL(metrics_lib_, SendToUMA(kTemperatureHistogramPrefix +
temp_monitor_1_->name(),
37, _, _, _));
temp_monitor_1_->NotifySubscribers(37000);
metrics_timer_->Fire();
}
TEST_F(MetricsReporterTest, ReportsThermalStates) {
metrics_reporter_->Start();
EXPECT_CALL(metrics_lib_, SendToUMA(kThermalStateHistogramZone0, 3, _, _, _));
EXPECT_CALL(metrics_lib_, SendToUMA(kThermalStateHistogramZone1, 7, _, _, _));
output_publisher_.Publish("thermal_zone.Zone 0.state", 3);
output_publisher_.Publish("thermal_zone.Zone 1.state", 7);
metrics_timer_->Fire();
}
TEST_F(MetricsReporterTest, InvalidThermalZoneKeysDoesNotCrash) {
metrics_reporter_->Start();
EXPECT_CALL(metrics_lib_, SendToUMA(_, _, _, _, _)).Times(0);
output_publisher_.Publish("", 1);
output_publisher_.Publish(".", 1);
output_publisher_.Publish("..", 1);
output_publisher_.Publish(".TestZone.", 1);
output_publisher_.Publish("thermal_zone.TestZone.", 1);
output_publisher_.Publish(".TestZone.state", 1);
output_publisher_.Publish("thermal_zone.state", 1);
output_publisher_.Publish("thermal_zone..state", 1);
output_publisher_.Publish("invalid.TestZone.state", 1);
output_publisher_.Publish("thermal_zone.TestZone.invalid", 1);
output_publisher_.Publish("thermal_zone.TestZone.invalid.state", 1);
output_publisher_.Publish("something_completely_different", 1);
metrics_timer_->Fire();
}
TEST_F(MetricsReporterTest, ReportsLatestThermalState) {
metrics_reporter_->Start();
EXPECT_CALL(metrics_lib_, SendToUMA(kThermalStateHistogramZone0, 7, _, _, _));
output_publisher_.Publish("thermal_zone.Zone 0.state", 3);
output_publisher_.Publish("thermal_zone.Zone 0.state", 7);
metrics_timer_->Fire();
}
} // namespace thermald