Fixes widevine metrics proto serialization

Changes to a much more efficient and more reusable protobuf format for
metrics.

Test: Widevine tests, Google Play and MediaDrm CTS test.
Bug: 73724218

Change-Id: I3299051d7a16bcd7758c8f272415ca40e10c1313
This commit is contained in:
Adam Stone
2018-02-20 19:12:02 -08:00
parent efc008c5a1
commit b19f0d106f
25 changed files with 1587 additions and 1867 deletions

View File

@@ -6,171 +6,123 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "metric_serialization.h"
#include "scoped_ptr.h"
#include "string_conversions.h"
using drm_metrics::TestMetrics;
using testing::IsNull;
using testing::NotNull;
namespace wvcdm {
namespace metrics {
class MockCounterMetricSerializer : public MetricSerializer {
public:
MOCK_METHOD2(SetString, void(const std::string& metric_id,
const std::string& value));
MOCK_METHOD2(SetInt32, void(const std::string& metric_id,
int32_t value));
MOCK_METHOD2(SetInt64, void(const std::string& metric_id,
int64_t value));
MOCK_METHOD2(SetDouble, void(const std::string& metric_id,
double value));
};
TEST(CounterMetricTest, NoFieldsEmpty) {
wvcdm::metrics::CounterMetric<> metric;
class CounterMetricTest : public ::testing::Test {
public:
void SetUp() {
mock_serializer_.reset(new MockCounterMetricSerializer());
}
protected:
template<typename F1,
typename F2,
typename F3,
typename F4>
const std::map<std::string, int64_t>
GetValueMap(
const wvcdm::metrics::CounterMetric<F1, F2, F3, F4>&
metric) {
return metric.value_map_;
}
TestMetrics metric_proto;
metric.ToProto(metric_proto.mutable_test_counters());
ASSERT_EQ(0, metric_proto.test_counters().size());
}
scoped_ptr<MockCounterMetricSerializer> mock_serializer_;
};
TEST_F(CounterMetricTest, NoFieldsSuccessNullCallback) {
wvcdm::metrics::CounterMetric<> metric("no/fields/metric");
TEST(CounterMetricTest, NoFieldsSuccess) {
wvcdm::metrics::CounterMetric<> metric;
metric.Increment();
metric.Increment(10);
std::map<std::string, int64_t> value_map = GetValueMap(metric);
ASSERT_EQ(1u, GetValueMap(metric).size());
EXPECT_EQ(11, value_map.begin()->second);
EXPECT_EQ("", value_map.begin()->first);
TestMetrics metric_proto;
std::string serialized_metrics;
metric.ToProto(metric_proto.mutable_test_counters());
ASSERT_EQ(1, metric_proto.test_counters().size());
ASSERT_TRUE(metric_proto.SerializeToString(&serialized_metrics));
EXPECT_EQ(11, metric_proto.test_counters(0).count());
EXPECT_FALSE(metric_proto.test_counters(0).has_attributes())
<< std::string("Unexpected attributes value. Serialized metrics: ")
<< wvcdm::b2a_hex(serialized_metrics);
}
TEST_F(CounterMetricTest, NoFieldsSuccessWithCallback) {
wvcdm::metrics::CounterMetric<> metric("no/fields/metric");
EXPECT_CALL(*mock_serializer_,
SetInt64("no/fields/metric/count", 11));
metric.Increment();
metric.Increment(10);
metric.Serialize(mock_serializer_.get());
std::map<std::string, int64_t> value_map = GetValueMap(metric);
ASSERT_EQ(1u, GetValueMap(metric).size());
EXPECT_EQ(11, value_map.begin()->second);
EXPECT_EQ("", value_map.begin()->first);
}
TEST_F(CounterMetricTest, NoFieldsSuccessSingleIncrementWithCallback) {
wvcdm::metrics::CounterMetric<> metric("no/fields/metric");
EXPECT_CALL(*mock_serializer_,
SetInt64("no/fields/metric/count", 1));
metric.Increment();
metric.Serialize(mock_serializer_.get());
std::map<std::string, int64_t> value_map = GetValueMap(metric);
ASSERT_EQ(1u, GetValueMap(metric).size());
EXPECT_EQ(1, value_map.begin()->second);
EXPECT_EQ("", value_map.begin()->first);
}
TEST_F(CounterMetricTest, OneFieldSuccessNoCallback) {
wvcdm::metrics::CounterMetric<int> metric(
"single/fields/metric",
"error_code");
TEST(CounterMetricTest, OneFieldSuccess) {
wvcdm::metrics::CounterMetric<drm_metrics::Attributes::kErrorCodeFieldNumber,
int> metric;
metric.Increment(7);
metric.Increment(10, 7);
metric.Increment(13);
metric.Increment(20, 13);
std::map<std::string, int64_t> value_map = GetValueMap(metric);
ASSERT_EQ(2u, GetValueMap(metric).size());
// Verify both instances.
EXPECT_EQ(11, value_map["{error_code:7}"]);
EXPECT_EQ(21, value_map["{error_code:13}"]);
TestMetrics metric_proto;
metric.ToProto(metric_proto.mutable_test_counters());
ASSERT_EQ(2, metric_proto.test_counters().size());
EXPECT_EQ(11u, metric_proto.test_counters(0).count());
EXPECT_EQ(7, metric_proto.test_counters(0).attributes().error_code());
EXPECT_EQ(21, metric_proto.test_counters(1).count());
EXPECT_EQ(13, metric_proto.test_counters(1).attributes().error_code());
}
TEST_F(CounterMetricTest, TwoFieldsSuccess) {
wvcdm::metrics::CounterMetric<int, int> metric(
"two/fields/metric",
"error_code",
"size");
metric.Increment(7, 23);
metric.Increment(2, 7, 29);
metric.Increment(3, 11, 23);
metric.Increment(4, 11, 29);
metric.Increment(5, 7, 23);
metric.Increment(-5, 7, 29);
TEST(CounterMetricTest, TwoFieldsSuccess) {
CounterMetric<drm_metrics::Attributes::kErrorCodeFieldNumber, int,
drm_metrics::Attributes::kLengthFieldNumber, Pow2Bucket> metric;
std::map<std::string, int64_t> value_map = GetValueMap(metric);
ASSERT_EQ(4u, GetValueMap(metric).size());
metric.Increment(7, Pow2Bucket(23)); // Increment by one.
metric.Increment(2, 7, Pow2Bucket(33));
metric.Increment(3, 11, Pow2Bucket(23));
metric.Increment(4, 11, Pow2Bucket(33));
metric.Increment(5, 7, Pow2Bucket(23));
metric.Increment(-5, 7, Pow2Bucket(33));
// Verify all instances.
EXPECT_EQ(6, value_map["{error_code:7&size:23}"]);
EXPECT_EQ(-3, value_map["{error_code:7&size:29}"]);
EXPECT_EQ(3, value_map["{error_code:11&size:23}"]);
EXPECT_EQ(4, value_map["{error_code:11&size:29}"]);
TestMetrics metric_proto;
metric.ToProto(metric_proto.mutable_test_counters());
ASSERT_EQ(4, metric_proto.test_counters().size());
// Verify that a non-existent distribution returns default 0
EXPECT_EQ(0, value_map["error_code:1,size:1"]);
EXPECT_EQ(6, metric_proto.test_counters(0).count());
EXPECT_EQ(7, metric_proto.test_counters(0).attributes().error_code());
EXPECT_EQ(16u, metric_proto.test_counters(0).attributes().length());
EXPECT_EQ(-3, metric_proto.test_counters(1).count());
EXPECT_EQ(7, metric_proto.test_counters(1).attributes().error_code());
EXPECT_EQ(32u, metric_proto.test_counters(1).attributes().length());
EXPECT_EQ(3, metric_proto.test_counters(2).count());
EXPECT_EQ(11, metric_proto.test_counters(2).attributes().error_code());
EXPECT_EQ(16u, metric_proto.test_counters(2).attributes().length());
EXPECT_EQ(4, metric_proto.test_counters(3).count());
EXPECT_EQ(11, metric_proto.test_counters(3).attributes().error_code());
EXPECT_EQ(32u, metric_proto.test_counters(3).attributes().length());
}
TEST_F(CounterMetricTest, TwoFieldsSuccessWithCallback) {
wvcdm::metrics::CounterMetric<int, std::string> metric("two/fields/metric",
"error_code",
"stringval");
TEST(CounterMetricTest, ThreeFieldsSuccess) {
CounterMetric<drm_metrics::Attributes::kErrorCodeFieldNumber, int,
drm_metrics::Attributes::kLengthFieldNumber, Pow2Bucket,
drm_metrics::Attributes::kErrorCodeBoolFieldNumber, bool>
metric;
metric.Increment(7, Pow2Bucket(13), true);
EXPECT_CALL(
*mock_serializer_,
SetInt64("two/fields/metric/count{error_code:11&stringval:foo}", 5));
metric.Increment(11, "foo");
metric.Increment(4, 11, "foo");
metric.Serialize(mock_serializer_.get());
TestMetrics metric_proto;
metric.ToProto(metric_proto.mutable_test_counters());
ASSERT_EQ(1, metric_proto.test_counters().size());
EXPECT_EQ(1, metric_proto.test_counters(0).count());
EXPECT_EQ(7, metric_proto.test_counters(0).attributes().error_code());
EXPECT_EQ(8u, metric_proto.test_counters(0).attributes().length());
EXPECT_TRUE(metric_proto.test_counters(0).attributes().error_code_bool());
}
TEST_F(CounterMetricTest, ThreeFieldsSuccess) {
wvcdm::metrics::CounterMetric<int, int, bool> metric(
"three/fields/metric",
"error_code",
"size",
"woke up happy");
metric.Increment(7, 13, false);
TEST(CounterMetricTest, FourFieldsSuccess) {
CounterMetric<drm_metrics::Attributes::kErrorCodeFieldNumber, int,
drm_metrics::Attributes::kLengthFieldNumber, Pow2Bucket,
drm_metrics::Attributes::kErrorCodeBoolFieldNumber, bool,
drm_metrics::Attributes::kSecurityLevelFieldNumber,
SecurityLevel> metric;
metric.Increment(10LL, 7, Pow2Bucket(13), true, kLevel3);
std::map<std::string, int64_t> value_map = GetValueMap(metric);
ASSERT_EQ(1u, 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);
}
TEST_F(CounterMetricTest, FourFieldsSuccess) {
wvcdm::metrics::CounterMetric<int, int, bool, std::string> metric(
"Four/fields/metric",
"error_code",
"size",
"woke up happy",
"horoscope");
metric.Increment(10LL, 7, 13, true, "find your true love");
std::map<std::string, int64_t> value_map = GetValueMap(metric);
ASSERT_EQ(1u, 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(10, value_map.begin()->second);
TestMetrics metric_proto;
metric.ToProto(metric_proto.mutable_test_counters());
ASSERT_EQ(1, metric_proto.test_counters().size());
EXPECT_EQ(10, metric_proto.test_counters(0).count());
EXPECT_EQ(7, metric_proto.test_counters(0).attributes().error_code());
EXPECT_EQ(8u, metric_proto.test_counters(0).attributes().length());
EXPECT_TRUE(metric_proto.test_counters(0).attributes().error_code_bool());
EXPECT_EQ(kLevel3,
metric_proto.test_counters(0).attributes().security_level());
}
} // namespace metrics