This change is the complete Widevine metrics system. It will measure and record runtime information about what is happening in the CDM - such as errors and throughput. Bug: 33745339 Bug: 26027857 Change-Id: Ic9a82074f1e2b72c72d751b235f8ae361232787d
227 lines
7.2 KiB
C++
227 lines
7.2 KiB
C++
// Copyright 2017 Google Inc. All Rights Reserved.
|
|
//
|
|
// Unit tests for EventMetric
|
|
|
|
#include "event_metric.h"
|
|
#include "metric_publisher.h"
|
|
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
#include "scoped_ptr.h"
|
|
|
|
using testing::IsNull;
|
|
using testing::NotNull;
|
|
|
|
namespace wvcdm {
|
|
namespace metrics {
|
|
|
|
class MockEventMetricNotification : public MetricNotification {
|
|
public:
|
|
MOCK_METHOD2(UpdateString, void(const std::string& metric_id,
|
|
const std::string& value));
|
|
MOCK_METHOD2(UpdateInt32, void(const std::string& metric_id,
|
|
int32_t value));
|
|
MOCK_METHOD2(UpdateInt64, void(const std::string& metric_id,
|
|
int64_t value));
|
|
MOCK_METHOD2(UpdateDouble, void(const std::string& metric_id,
|
|
double value));
|
|
};
|
|
|
|
class EventMetricTest : public ::testing::Test {
|
|
public:
|
|
void SetUp() {
|
|
mock_notification_.reset(new MockEventMetricNotification());
|
|
}
|
|
protected:
|
|
template<typename F1,
|
|
typename F2,
|
|
typename F3,
|
|
typename F4>
|
|
const std::map<std::string, Distribution*>
|
|
GetValueMap(
|
|
const wvcdm::metrics::EventMetric<F1, F2, F3, F4>&
|
|
metric) {
|
|
return metric.value_map_;
|
|
}
|
|
|
|
scoped_ptr<MockEventMetricNotification> mock_notification_;
|
|
};
|
|
|
|
TEST_F(EventMetricTest, NoFieldsSuccessNullCallback) {
|
|
wvcdm::metrics::EventMetric<> metric("no/fields/metric");
|
|
metric.Record(10LL);
|
|
metric.Record(10LL);
|
|
|
|
std::map<std::string, Distribution*> value_map = GetValueMap(metric);
|
|
ASSERT_EQ(1, GetValueMap(metric).size());
|
|
EXPECT_EQ(2, value_map.begin()->second->Count());
|
|
EXPECT_EQ("", value_map.begin()->first);
|
|
}
|
|
|
|
TEST_F(EventMetricTest, NoFieldsSuccessWithCallback) {
|
|
wvcdm::metrics::EventMetric<> metric("no/fields/metric");
|
|
EXPECT_CALL(*mock_notification_,
|
|
UpdateInt64("no/fields/metric/count", 1.0));
|
|
EXPECT_CALL(*mock_notification_,
|
|
UpdateDouble("no/fields/metric/mean", 10.0));
|
|
EXPECT_CALL(*mock_notification_,
|
|
UpdateDouble("no/fields/metric/variance", 0.0));
|
|
EXPECT_CALL(*mock_notification_,
|
|
UpdateDouble("no/fields/metric/min", 10.0));
|
|
EXPECT_CALL(*mock_notification_,
|
|
UpdateDouble("no/fields/metric/max", 10.0));
|
|
|
|
metric.Record(10);
|
|
metric.Publish(mock_notification_.get());
|
|
|
|
std::map<std::string, Distribution*> value_map = GetValueMap(metric);
|
|
ASSERT_EQ(1, GetValueMap(metric).size());
|
|
EXPECT_EQ(1, value_map.begin()->second->Count());
|
|
EXPECT_EQ("", value_map.begin()->first);
|
|
}
|
|
|
|
TEST_F(EventMetricTest, OneFieldSuccessNoCallback) {
|
|
wvcdm::metrics::EventMetric<int> metric(
|
|
"single/fields/metric",
|
|
"error_code");
|
|
metric.Record(10LL, 7);
|
|
metric.Record(11LL, 13);
|
|
metric.Record(12LL, 13);
|
|
std::map<std::string, Distribution*> value_map = GetValueMap(metric);
|
|
ASSERT_EQ(2, GetValueMap(metric).size());
|
|
|
|
// Verify both instances.
|
|
// TODO(blueeyes): Export MakeFieldNameString so it can be used here.
|
|
Distribution* distribution_error_7 = value_map["{error_code:7}"];
|
|
Distribution* distribution_error_13 = value_map["{error_code:13}"];
|
|
ASSERT_THAT(distribution_error_7, NotNull());
|
|
ASSERT_THAT(distribution_error_13, NotNull());
|
|
|
|
EXPECT_EQ(1, distribution_error_7->Count());
|
|
EXPECT_EQ(2, distribution_error_13->Count());
|
|
}
|
|
|
|
TEST_F(EventMetricTest, TwoFieldsSuccess) {
|
|
wvcdm::metrics::EventMetric<int, int> metric(
|
|
"two/fields/metric",
|
|
"error_code",
|
|
"size");
|
|
metric.Record(1, 7, 23);
|
|
metric.Record(2, 7, 29);
|
|
metric.Record(3, 11, 23);
|
|
metric.Record(4, 11, 29);
|
|
metric.Record(5, 7, 23);
|
|
|
|
std::map<std::string, Distribution*> value_map = GetValueMap(metric);
|
|
ASSERT_EQ(4, GetValueMap(metric).size());
|
|
|
|
// Verify all instances.
|
|
Distribution* distribution_7_23 = value_map["{error_code:7&size:23}"];
|
|
Distribution* distribution_7_29 = value_map["{error_code:7&size:29}"];
|
|
Distribution* distribution_11_23 = value_map["{error_code:11&size:23}"];
|
|
Distribution* distribution_11_29 = value_map["{error_code:11&size:29}"];
|
|
ASSERT_THAT(distribution_7_23, NotNull());
|
|
ASSERT_THAT(distribution_7_29, NotNull());
|
|
ASSERT_THAT(distribution_11_23, NotNull());
|
|
ASSERT_THAT(distribution_11_29, NotNull());
|
|
|
|
EXPECT_EQ(2, distribution_7_23->Count());
|
|
EXPECT_EQ(1, distribution_7_29->Count());
|
|
EXPECT_EQ(1, distribution_11_23->Count());
|
|
EXPECT_EQ(1, distribution_11_29->Count());
|
|
|
|
// Verify that a non-existent distribution returns nullptr.
|
|
Distribution* null_distribution = value_map["error_code:1,size:1"];
|
|
ASSERT_THAT(null_distribution, IsNull());
|
|
}
|
|
|
|
TEST_F(EventMetricTest, TwoFieldsSuccessWithCallback) {
|
|
wvcdm::metrics::EventMetric<int, Pow2Bucket> metric("two/fields/metric",
|
|
"error_code",
|
|
"pow2_size");
|
|
|
|
// Callbacks from second record operation.
|
|
EXPECT_CALL(
|
|
*mock_notification_,
|
|
UpdateInt64("two/fields/metric/count{error_code:11&pow2_size:16}", 2.0));
|
|
EXPECT_CALL(
|
|
*mock_notification_,
|
|
UpdateDouble("two/fields/metric/mean{error_code:11&pow2_size:16}", 3.5));
|
|
EXPECT_CALL(
|
|
*mock_notification_,
|
|
UpdateDouble("two/fields/metric/variance{error_code:11&pow2_size:16}",
|
|
0.25));
|
|
EXPECT_CALL(
|
|
*mock_notification_,
|
|
UpdateDouble("two/fields/metric/min{error_code:11&pow2_size:16}", 3.0));
|
|
EXPECT_CALL(
|
|
*mock_notification_,
|
|
UpdateDouble("two/fields/metric/max{error_code:11&pow2_size:16}", 4.0));
|
|
metric.Record(3, 11, Pow2Bucket(29));
|
|
metric.Record(4, 11, Pow2Bucket(29));
|
|
metric.Publish(mock_notification_.get());
|
|
}
|
|
|
|
TEST_F(EventMetricTest, ThreeFieldsSuccess) {
|
|
wvcdm::metrics::EventMetric<int, int, bool> metric(
|
|
"three/fields/metric",
|
|
"error_code",
|
|
"size",
|
|
"woke up happy");
|
|
metric.Record(10LL, 7, 13, false);
|
|
|
|
|
|
std::map<std::string, Distribution*> value_map = GetValueMap(metric);
|
|
ASSERT_EQ(1, GetValueMap(metric).size());
|
|
EXPECT_EQ("{error_code:7&size:13&woke up happy:0}",
|
|
value_map.begin()->first);
|
|
EXPECT_EQ(1, value_map.begin()->second->Count());
|
|
}
|
|
|
|
TEST_F(EventMetricTest, FourFieldsSuccess) {
|
|
wvcdm::metrics::EventMetric<int, int, bool, std::string> metric(
|
|
"Four/fields/metric",
|
|
"error_code",
|
|
"size",
|
|
"woke up happy",
|
|
"horoscope");
|
|
metric.Record(10LL, 7, 13, true, "find your true love");
|
|
|
|
std::map<std::string, Distribution*> value_map = GetValueMap(metric);
|
|
ASSERT_EQ(1, GetValueMap(metric).size());
|
|
EXPECT_EQ(
|
|
"{error_code:7&size:13&woke up happy:1&horoscope:find your true love}",
|
|
value_map.begin()->first);
|
|
EXPECT_EQ(1, value_map.begin()->second->Count());
|
|
}
|
|
|
|
TEST_F(EventMetricTest, Pow2BucketTest) {
|
|
std::stringstream value;
|
|
value << Pow2Bucket(1);
|
|
EXPECT_EQ("1", value.str());
|
|
|
|
value.str("");
|
|
value << Pow2Bucket(0);
|
|
EXPECT_EQ("0", value.str());
|
|
|
|
value.str("");
|
|
value << Pow2Bucket(2);
|
|
EXPECT_EQ("2", value.str());
|
|
|
|
value.str("");
|
|
value << Pow2Bucket(0xFFFFFFFF);
|
|
EXPECT_EQ("2147483648", value.str());
|
|
|
|
value.str("");
|
|
value << Pow2Bucket(0x80000000);
|
|
EXPECT_EQ("2147483648", value.str());
|
|
|
|
value.str("");
|
|
value << Pow2Bucket(0x7FFFFFFF);
|
|
EXPECT_EQ("1073741824", value.str());
|
|
}
|
|
|
|
} // namespace metrics
|
|
} // namespace wvcdm
|
|
|