Source release v3.5.0

This commit is contained in:
Gene Morgan
2017-11-28 17:42:16 -08:00
parent 501c22890d
commit 31381a1311
155 changed files with 16680 additions and 3816 deletions

View File

@@ -0,0 +1,177 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Unit tests for CounterMetric
#include "counter_metric.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "metric_serialization.h"
#include "scoped_ptr.h"
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));
};
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_;
}
scoped_ptr<MockCounterMetricSerializer> mock_serializer_;
};
TEST_F(CounterMetricTest, NoFieldsSuccessNullCallback) {
wvcdm::metrics::CounterMetric<> metric("no/fields/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);
}
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");
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}"]);
}
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);
std::map<std::string, int64_t> value_map = GetValueMap(metric);
ASSERT_EQ(4u, GetValueMap(metric).size());
// 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}"]);
// Verify that a non-existent distribution returns default 0
EXPECT_EQ(0, value_map["error_code:1,size:1"]);
}
TEST_F(CounterMetricTest, TwoFieldsSuccessWithCallback) {
wvcdm::metrics::CounterMetric<int, std::string> metric("two/fields/metric",
"error_code",
"stringval");
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());
}
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);
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);
}
} // namespace metrics
} // namespace wvcdm

View File

@@ -0,0 +1,47 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Unit tests for Distribution.
#include <float.h>
#include "distribution.h"
#include "gtest/gtest.h"
namespace wvcdm {
namespace metrics {
TEST(DistributionTest, NoValuesRecorded) {
Distribution distribution;
EXPECT_EQ(DBL_MAX, distribution.Min());
EXPECT_EQ(-DBL_MAX, distribution.Max());
EXPECT_EQ(0, distribution.Mean());
EXPECT_EQ(0, distribution.Count());
EXPECT_EQ(0, distribution.Variance());
}
TEST(DistributionTest, OneValueRecorded) {
Distribution distribution;
distribution.Record(5.0);
EXPECT_EQ(5, distribution.Min());
EXPECT_EQ(5, distribution.Max());
EXPECT_EQ(5, distribution.Mean());
EXPECT_EQ(1, distribution.Count());
EXPECT_EQ(0, distribution.Variance());
}
TEST(DistributionTest, MultipleValuesRecorded) {
Distribution distribution;
distribution.Record(5.0);
distribution.Record(10.0);
distribution.Record(15.0);
EXPECT_EQ(5, distribution.Min());
EXPECT_EQ(15, distribution.Max());
EXPECT_EQ(10, distribution.Mean());
EXPECT_EQ(3, distribution.Count());
EXPECT_NEAR(16.6667, distribution.Variance(), 0.0001);
}
} // namespace metrics
} // namespace wvcdm

View File

@@ -0,0 +1,242 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Unit tests for EventMetric
#include "event_metric.h"
#include "metric_serialization.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "scoped_ptr.h"
using testing::IsNull;
using testing::NotNull;
namespace wvcdm {
namespace metrics {
class MockEventMetricSerializer : 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));
};
class EventMetricTest : public ::testing::Test {
public:
void SetUp() {
mock_serializer_.reset(new MockEventMetricSerializer());
}
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<MockEventMetricSerializer> mock_serializer_;
};
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(1u, 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_serializer_,
SetInt64("no/fields/metric/count", 2));
EXPECT_CALL(*mock_serializer_,
SetDouble("no/fields/metric/mean", 10.0));
EXPECT_CALL(*mock_serializer_,
SetDouble("no/fields/metric/variance", 0.0));
EXPECT_CALL(*mock_serializer_,
SetDouble("no/fields/metric/min", 10.0));
EXPECT_CALL(*mock_serializer_,
SetDouble("no/fields/metric/max", 10.0));
metric.Record(10);
metric.Record(10);
metric.Serialize(mock_serializer_.get());
std::map<std::string, Distribution*> value_map = GetValueMap(metric);
ASSERT_EQ(1u, GetValueMap(metric).size());
EXPECT_EQ(2, value_map.begin()->second->Count());
EXPECT_EQ("", value_map.begin()->first);
}
TEST_F(EventMetricTest, NoFieldsSuccessSingleRecordWithCallback) {
wvcdm::metrics::EventMetric<> metric("no/fields/metric");
EXPECT_CALL(*mock_serializer_,
SetInt64("no/fields/metric/count", 1.0));
EXPECT_CALL(*mock_serializer_,
SetDouble("no/fields/metric/mean", 10.0));
metric.Record(10);
metric.Serialize(mock_serializer_.get());
std::map<std::string, Distribution*> value_map = GetValueMap(metric);
ASSERT_EQ(1u, 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(2u, 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(4u, 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_serializer_,
SetInt64("two/fields/metric/count{error_code:11&pow2_size:16}", 2.0));
EXPECT_CALL(
*mock_serializer_,
SetDouble("two/fields/metric/mean{error_code:11&pow2_size:16}", 3.5));
EXPECT_CALL(
*mock_serializer_,
SetDouble("two/fields/metric/variance{error_code:11&pow2_size:16}",
0.25));
EXPECT_CALL(
*mock_serializer_,
SetDouble("two/fields/metric/min{error_code:11&pow2_size:16}", 3.0));
EXPECT_CALL(
*mock_serializer_,
SetDouble("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.Serialize(mock_serializer_.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(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->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(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(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(0xFFFFFFFFu);
EXPECT_EQ("2147483648", value.str());
value.str("");
value << Pow2Bucket(0x80000000u);
EXPECT_EQ("2147483648", value.str());
value.str("");
value << Pow2Bucket(0x7FFFFFFF);
EXPECT_EQ("1073741824", value.str());
}
} // namespace metrics
} // namespace wvcdm

View File

@@ -0,0 +1,445 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Unit tests for the metrics collections,
// EngineMetrics, SessionMetrics and CrytpoMetrics.
#include "metrics_collections.h"
#include <sstream>
#include "gmock/gmock.h"
#include "google/protobuf/text_format.h"
#include "gtest/gtest.h"
#include "log.h"
#include "metrics.pb.h"
#include "wv_cdm_types.h"
using drm_metrics::MetricsGroup;
using google::protobuf::TextFormat;
namespace wvcdm {
namespace metrics {
// TODO(blueeyes): Improve this implementation by supporting full message
// API In CDM. That allows us to use MessageDifferencer.
class EngineMetricsTest : public ::testing::Test {
};
TEST_F(EngineMetricsTest, AllEngineMetrics) {
EngineMetrics engine_metrics;
// Set some values in all of the engine metrics.
engine_metrics.cdm_engine_add_key_.Record(1.0, KEY_ADDED);
engine_metrics.cdm_engine_close_session_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_decrypt_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_find_session_for_key_.Record(1.0, false);
engine_metrics.cdm_engine_generate_key_request_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_get_provisioning_request_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_get_usage_info_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_handle_provisioning_response_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_life_span_.Record(1.0);
engine_metrics.cdm_engine_open_key_set_session_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_open_session_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_query_key_status_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_release_all_usage_info_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_release_usage_info_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_remove_keys_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_restore_key_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_unprovision_.Record(1.0, NO_ERROR, kSecurityLevelL1);
drm_metrics::MetricsGroup actual_metrics;
engine_metrics.Serialize(&actual_metrics, true, false);
// For each EventMetric, 2 metrics get serialized since only one sample was
// taken. So, the total number of serialized metrics are 2*17.
ASSERT_EQ(2 * 17, actual_metrics.metric_size());
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
// Spot check some metrics.
EXPECT_EQ("/drm/widevine/cdm_engine/add_key/time/count{error:2}",
actual_metrics.metric(0).name());
EXPECT_EQ("/drm/widevine/cdm_engine/close_session/time/mean{error:0}",
actual_metrics.metric(3).name());
EXPECT_EQ("/drm/widevine/cdm_engine/decrypt/time/mean{error:0}",
actual_metrics.metric(5).name());
EXPECT_EQ(1.0, actual_metrics.metric(5).value().double_value());
}
TEST_F(EngineMetricsTest, EngineAndCryptoMetrics) {
EngineMetrics engine_metrics;
// Set some values in some of the engine metrics and some crypto metrics.
engine_metrics.cdm_engine_add_key_.Record(1.0, KEY_ADDED);
engine_metrics.cdm_engine_close_session_.Record(1.0, NO_ERROR);
CryptoMetrics* crypto_metrics = engine_metrics.GetCryptoMetrics();
crypto_metrics->crypto_session_generic_decrypt_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
crypto_metrics->crypto_session_get_device_unique_id_
.Record(4.0, false);
drm_metrics::MetricsGroup actual_metrics;
engine_metrics.Serialize(&actual_metrics, true, false);
// For each EventMetric, 2 metrics get serialized since only one sample was
// taken. So, the total number of serialized metrics are 2*4 since we
// touched 4 metrics.
ASSERT_EQ(2 * 4, actual_metrics.metric_size());
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
// Spot check some metrics.
EXPECT_EQ("/drm/widevine/cdm_engine/add_key/time/count{error:2}",
actual_metrics.metric(0).name());
EXPECT_EQ(
"/drm/widevine/crypto_session/generic_decrypt/time/count"
"{error:0&length:1024&encryption_algorithm:1}",
actual_metrics.metric(4).name());
EXPECT_EQ(
"/drm/widevine/crypto_session/get_device_unique_id/time/mean{success:0}",
actual_metrics.metric(7).name());
EXPECT_EQ(4.0, actual_metrics.metric(7).value().double_value());
}
TEST_F(EngineMetricsTest, EmptyEngineMetrics) {
EngineMetrics engine_metrics;
drm_metrics::MetricsGroup actual_metrics;
engine_metrics.Serialize(&actual_metrics, true, false);
EXPECT_EQ(0, actual_metrics.metric_size());
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
}
TEST_F(EngineMetricsTest, EngineMetricsWithCompletedSessions) {
EngineMetrics engine_metrics;
// Set a values in an engine metric and in a crypto metric.
engine_metrics.cdm_engine_add_key_.Record(1.0, KEY_ADDED);
engine_metrics.GetCryptoMetrics()
->crypto_session_load_certificate_private_key_.Record(2.0, true);
// Create two sessions and record some metrics.
SessionMetrics* session_metrics_1 = engine_metrics.AddSession();
session_metrics_1->SetSessionId("session_id_1");
SessionMetrics* session_metrics_2 = engine_metrics.AddSession();
session_metrics_2->SetSessionId("session_id_2");
// Record a CryptoMetrics metric in the session.
session_metrics_2->GetCryptoMetrics()->crypto_session_generic_decrypt_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
session_metrics_2->SetSessionId("session_id_2");
// Mark only session 2 as completed.
session_metrics_2->SetCompleted();
drm_metrics::MetricsGroup actual_metrics;
engine_metrics.Serialize(&actual_metrics, true, false);
// Validate metric counts.
// For each EventMetric, 2 metrics get serialized since only one sample was
// taken. So, the total number of serialized metrics are 2*2 since we
// touched 2 metrics.
ASSERT_EQ(2 * 2, actual_metrics.metric_size());
ASSERT_EQ(1, actual_metrics.metric_sub_group_size());
ASSERT_EQ(3, actual_metrics.metric_sub_group(0).metric_size());
// Spot check some metrics.
EXPECT_EQ("/drm/widevine/cdm_engine/add_key/time/count{error:2}",
actual_metrics.metric(0).name());
EXPECT_EQ("/drm/widevine/crypto_session/load_certificate_private_key"
"/time/count{success:1}",
actual_metrics.metric(2).name());
EXPECT_EQ("/drm/widevine/cdm_session/session_id",
actual_metrics.metric_sub_group(0).metric(0).name());
EXPECT_EQ(
"session_id_2",
actual_metrics.metric_sub_group(0).metric(0).value().string_value());
EXPECT_EQ(
"/drm/widevine/crypto_session/generic_decrypt/time/count"
"{error:0&length:1024&encryption_algorithm:1}",
actual_metrics.metric_sub_group(0).metric(1).name());
}
TEST_F(EngineMetricsTest, EngineMetricsSerializeAllSessions) {
EngineMetrics engine_metrics;
// Create two sessions and record some metrics.
SessionMetrics* session_metrics_1 = engine_metrics.AddSession();
session_metrics_1->SetSessionId("session_id_1");
SessionMetrics* session_metrics_2 = engine_metrics.AddSession();
session_metrics_2->SetSessionId("session_id_2");
// Mark only session 2 as completed.
session_metrics_2->SetCompleted();
drm_metrics::MetricsGroup actual_metrics;
engine_metrics.Serialize(&actual_metrics, false, false);
// Validate metric counts.
// No Engine-level metrics were recorded.
ASSERT_EQ(0, actual_metrics.metric_size());
// Two sub groups, 1 per session.
ASSERT_EQ(2, actual_metrics.metric_sub_group_size());
ASSERT_EQ(1, actual_metrics.metric_sub_group(0).metric_size());
// Spot check some metrics.
EXPECT_EQ("/drm/widevine/cdm_session/session_id",
actual_metrics.metric_sub_group(0).metric(0).name());
EXPECT_EQ(
"session_id_1",
actual_metrics.metric_sub_group(0).metric(0).value().string_value());
EXPECT_EQ("/drm/widevine/cdm_session/session_id",
actual_metrics.metric_sub_group(1).metric(0).name());
EXPECT_EQ(
"session_id_2",
actual_metrics.metric_sub_group(1).metric(0).value().string_value());
}
TEST_F(EngineMetricsTest, EngineMetricsRemoveSessions) {
EngineMetrics engine_metrics;
// Create two sessions and record some metrics.
SessionMetrics* session_metrics_1 = engine_metrics.AddSession();
session_metrics_1->SetSessionId("session_id_1");
SessionMetrics* session_metrics_2 = engine_metrics.AddSession();
session_metrics_2->SetSessionId("session_id_2");
// Mark only session 2 as completed.
session_metrics_2->SetCompleted();
// Serialize all metrics, don't remove any.
drm_metrics::MetricsGroup actual_metrics;
engine_metrics.Serialize(&actual_metrics, false, false);
// Validate metric counts.
// Two sub groups, 1 per session.
ASSERT_EQ(2, actual_metrics.metric_sub_group_size());
// Serialize completed metrics, remove them.
actual_metrics.Clear();
engine_metrics.Serialize(&actual_metrics, true, true);
// Validate metric counts.
// Only one, completed session should exist.
ASSERT_EQ(1, actual_metrics.metric_sub_group_size());
ASSERT_EQ(1, actual_metrics.metric_sub_group(0).metric_size());
EXPECT_EQ(
"session_id_2",
actual_metrics.metric_sub_group(0).metric(0).value().string_value());
// Serialize all metrics, remove them.
actual_metrics.Clear();
engine_metrics.Serialize(&actual_metrics, false, true);
// Validate metric counts.
// Only one, non-complete session should exist.
ASSERT_EQ(1, actual_metrics.metric_sub_group_size());
ASSERT_EQ(1, actual_metrics.metric_sub_group(0).metric_size());
EXPECT_EQ(
"session_id_1",
actual_metrics.metric_sub_group(0).metric(0).value().string_value());
// Serialize all metrics, don't remove any.
actual_metrics.Clear();
engine_metrics.Serialize(&actual_metrics, false, false);
// Validate metric counts.
// There should be no more metric subgroups left.
ASSERT_EQ(0, actual_metrics.metric_sub_group_size());
}
class SessionMetricsTest : public ::testing::Test {
};
TEST_F(SessionMetricsTest, AllSessionMetrics) {
SessionMetrics session_metrics;
session_metrics.SetSessionId("session_id 1");
session_metrics.cdm_session_life_span_.Record(1.0);
session_metrics.cdm_session_renew_key_.Record(1.0, NO_ERROR);
session_metrics.cdm_session_restore_offline_session_.Record(1.0, NO_ERROR);
session_metrics.cdm_session_restore_usage_session_.Record(1.0, NO_ERROR);
// Record a CryptoMetrics metric in the session.
session_metrics.GetCryptoMetrics()->crypto_session_generic_decrypt_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
MetricsGroup actual_metrics;
session_metrics.Serialize(&actual_metrics);
ASSERT_EQ(11, actual_metrics.metric_size());
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
// Spot check some metrics.
EXPECT_EQ("/drm/widevine/cdm_session/session_id",
actual_metrics.metric(0).name());
EXPECT_EQ("/drm/widevine/cdm_session/life_span/time/count",
actual_metrics.metric(1).name());
EXPECT_EQ("/drm/widevine/cdm_session/renew_key/time/mean{error:0}",
actual_metrics.metric(4).name());
EXPECT_EQ(1.0, actual_metrics.metric(4).value().double_value());
EXPECT_EQ("/drm/widevine/crypto_session/generic_decrypt/time/count"
"{error:0&length:1024&encryption_algorithm:1}",
actual_metrics.metric(9).name());
}
TEST_F(SessionMetricsTest, EmptySessionMetrics) {
SessionMetrics session_metrics;
MetricsGroup actual_metrics;
session_metrics.Serialize(&actual_metrics);
// Session metric always has a session id.
ASSERT_EQ(1, actual_metrics.metric_size());
EXPECT_EQ("/drm/widevine/cdm_session/session_id",
actual_metrics.metric(0).name());
EXPECT_EQ("", actual_metrics.metric(0).value().string_value());
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
}
class CryptoMetricsTest : public ::testing::Test {
};
TEST_F(CryptoMetricsTest, AllCryptoMetrics) {
CryptoMetrics crypto_metrics;
// Crypto session metrics.
crypto_metrics.crypto_session_delete_all_usage_reports_
.Record(1.0, NO_ERROR);
crypto_metrics.crypto_session_delete_multiple_usage_information_
.Record(1.0, NO_ERROR);
crypto_metrics.crypto_session_generic_decrypt_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
crypto_metrics.crypto_session_generic_encrypt_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
crypto_metrics.crypto_session_generic_sign_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256);
crypto_metrics.crypto_session_generic_verify_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256);
crypto_metrics.crypto_session_get_device_unique_id_.Record(1.0, true);
crypto_metrics.crypto_session_get_security_level_
.Record(1.0, kSecurityLevelL1);
crypto_metrics.crypto_session_get_system_id_.Record(1.0, true, 1234);
crypto_metrics.crypto_session_get_token_.Record(1.0, true);
crypto_metrics.crypto_session_life_span_.Record(1.0);
crypto_metrics.crypto_session_load_certificate_private_key_
.Record(1.0, true);
crypto_metrics.crypto_session_open_.Record(1.0, NO_ERROR, kLevelDefault);
crypto_metrics.crypto_session_update_usage_information_
.Record(1.0, NO_ERROR);
crypto_metrics.crypto_session_usage_information_support_.Record(1.0, true);
// Oem crypto metrics.
crypto_metrics.oemcrypto_api_version_.Record(1.0, 123, kLevelDefault);
crypto_metrics.oemcrypto_close_session_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_copy_buffer_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED,
kLevelDefault, Pow2Bucket(1025));
crypto_metrics.oemcrypto_deactivate_usage_entry_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_decrypt_cenc_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_delete_usage_entry_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_delete_usage_table_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_derive_keys_from_session_key_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_force_delete_usage_entry_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_generate_derived_keys_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_generate_nonce_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_generate_rsa_signature_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_generate_signature_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_generic_decrypt_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_generic_encrypt_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_generic_sign_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_generic_verify_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_get_device_id_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_get_hdcp_capability_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_get_key_data_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED,
Pow2Bucket(1025), kLevelDefault);
crypto_metrics.oemcrypto_get_max_number_of_sessions_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_get_number_of_open_sessions_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_get_oem_public_certificate_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_get_provisioning_method_
.Record(1.0, OEMCrypto_Keybox, kLevelDefault);
crypto_metrics.oemcrypto_get_random_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_initialize_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_install_keybox_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_is_anti_rollback_hw_present_
.Record(1.0, true, kLevelDefault);
crypto_metrics.oemcrypto_is_keybox_valid_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_load_device_rsa_key_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_load_keys_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_load_test_keybox_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_load_test_rsa_key_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_open_session_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_refresh_keys_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_report_usage_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_rewrap_device_rsa_key_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_rewrap_device_rsa_key_30_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_security_level_
.Record(1.0, kSecurityLevelL2, kLevelDefault);
crypto_metrics.oemcrypto_security_patch_level_
.Record(1.0, 123, kLevelDefault);
crypto_metrics.oemcrypto_select_key_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_supports_usage_table_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_update_usage_table_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_wrap_keybox_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
// Internal OEMCrypto Metrics
crypto_metrics.oemcrypto_initialization_mode_
.Record(1.0, OEMCrypto_INITIALIZED_FORCING_L3);
crypto_metrics.oemcrypto_l1_api_version_.Record(1.0, 12, 123);
MetricsGroup actual_metrics;
crypto_metrics.Serialize(&actual_metrics);
// 61 EventMetric instances, 2 values each.
ASSERT_EQ(122, actual_metrics.metric_size());
// Spot check some metrics.
EXPECT_EQ(
"/drm/widevine/crypto_session/delete_all_usage_reports/time/count"
"{error:0}",
actual_metrics.metric(0).name());
EXPECT_EQ(1, actual_metrics.metric(0).value().int_value());
EXPECT_EQ(
"/drm/widevine/oemcrypto/l1_api_version/mean{version:12&min_version:123}",
actual_metrics.metric(121).name());
EXPECT_EQ(1.0, actual_metrics.metric(121).value().double_value());
// No subgroups should exist.
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
}
} // namespace metrics
} // namespace wvcdm

View File

@@ -0,0 +1,445 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Unit tests for the metrics collections,
// EngineMetrics, SessionMetrics and CryptoMetrics.
#include "metrics_collections.h"
#include <sstream>
#include "gmock/gmock.h"
#include "google/protobuf/text_format.h"
#include "gtest/gtest.h"
#include "log.h"
#include "metrics.pb.h"
#include "wv_cdm_types.h"
using drm_metrics::MetricsGroup;
using google::protobuf::TextFormat;
namespace wvcdm {
namespace metrics {
// TODO(blueeyes): Improve this implementation by supporting full message
// API In CDM. That allows us to use MessageDifferencer.
class EngineMetricsTest : public ::testing::Test {
};
TEST_F(EngineMetricsTest, AllEngineMetrics) {
EngineMetrics engine_metrics;
// Set some values in all of the engine metrics.
engine_metrics.cdm_engine_add_key_.Record(1.0, KEY_ADDED);
engine_metrics.cdm_engine_close_session_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_decrypt_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_find_session_for_key_.Record(1.0, false);
engine_metrics.cdm_engine_generate_key_request_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_get_provisioning_request_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_get_usage_info_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_handle_provisioning_response_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_life_span_.Record(1.0);
engine_metrics.cdm_engine_open_key_set_session_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_open_session_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_query_key_status_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_release_all_usage_info_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_release_usage_info_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_remove_keys_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_restore_key_.Record(1.0, NO_ERROR);
engine_metrics.cdm_engine_unprovision_.Record(1.0, NO_ERROR, kSecurityLevelL1);
drm_metrics::MetricsGroup actual_metrics;
engine_metrics.Serialize(&actual_metrics, true, false);
// For each EventMetric, 2 metrics get serialized since only one sample was
// taken. So, the total number of serialized metrics are 2*17.
ASSERT_EQ(2 * 17, actual_metrics.metric_size());
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
// Spot check some metrics.
EXPECT_EQ("/drm/widevine/cdm_engine/add_key/time/count{error:2}",
actual_metrics.metric(0).name());
EXPECT_EQ("/drm/widevine/cdm_engine/close_session/count{error:0}",
actual_metrics.metric(3).name());
EXPECT_EQ("/drm/widevine/cdm_engine/decrypt/time/mean{error:0}",
actual_metrics.metric(5).name());
EXPECT_EQ(1.0, actual_metrics.metric(5).value().double_value());
}
TEST_F(EngineMetricsTest, EngineAndCryptoMetrics) {
EngineMetrics engine_metrics;
// Set some values in some of the engine metrics and some crypto metrics.
engine_metrics.cdm_engine_add_key_.Record(1.0, KEY_ADDED);
engine_metrics.cdm_engine_close_session_.Record(1.0, NO_ERROR);
CryptoMetrics* crypto_metrics = engine_metrics.GetCryptoMetrics();
crypto_metrics->crypto_session_generic_decrypt_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
crypto_metrics->crypto_session_get_device_unique_id_
.Record(4.0, false);
drm_metrics::MetricsGroup actual_metrics;
engine_metrics.Serialize(&actual_metrics, true, false);
// For each EventMetric, 2 metrics get serialized since only one sample was
// taken. So, the total number of serialized metrics are 2*4 since we
// touched 4 metrics.
ASSERT_EQ(2 * 4, actual_metrics.metric_size());
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
// Spot check some metrics.
EXPECT_EQ("/drm/widevine/cdm_engine/add_key/time/count{error:2}",
actual_metrics.metric(0).name());
EXPECT_EQ(
"/drm/widevine/crypto_session/generic_decrypt/time/count"
"{error:0&length:1024&encryption_algorithm:1}",
actual_metrics.metric(4).name());
EXPECT_EQ(
"/drm/widevine/crypto_session/get_device_unique_id/count{success:0}",
actual_metrics.metric(7).name());
EXPECT_EQ(4.0, actual_metrics.metric(7).value().double_value());
}
TEST_F(EngineMetricsTest, EmptyEngineMetrics) {
EngineMetrics engine_metrics;
drm_metrics::MetricsGroup actual_metrics;
engine_metrics.Serialize(&actual_metrics, true, false);
EXPECT_EQ(0, actual_metrics.metric_size());
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
}
TEST_F(EngineMetricsTest, EngineMetricsWithCompletedSessions) {
EngineMetrics engine_metrics;
// Set a values in an engine metric and in a crypto metric.
engine_metrics.cdm_engine_add_key_.Record(1.0, KEY_ADDED);
engine_metrics.GetCryptoMetrics()
->crypto_session_load_certificate_private_key_.Record(2.0, true);
// Create two sessions and record some metrics.
SessionMetrics* session_metrics_1 = engine_metrics.AddSession();
session_metrics_1->SetSessionId("session_id_1");
SessionMetrics* session_metrics_2 = engine_metrics.AddSession();
session_metrics_2->SetSessionId("session_id_2");
// Record a CryptoMetrics metric in the session.
session_metrics_2->GetCryptoMetrics()->crypto_session_generic_decrypt_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
session_metrics_2->SetSessionId("session_id_2");
// Mark only session 2 as completed.
session_metrics_2->SetCompleted();
drm_metrics::MetricsGroup actual_metrics;
engine_metrics.Serialize(&actual_metrics, true, false);
// Validate metric counts.
// For each EventMetric, 2 metrics get serialized since only one sample was
// taken. So, the total number of serialized metrics are 2*2 since we
// touched 2 metrics.
ASSERT_EQ(2 * 2, actual_metrics.metric_size());
ASSERT_EQ(1, actual_metrics.metric_sub_group_size());
ASSERT_EQ(3, actual_metrics.metric_sub_group(0).metric_size());
// Spot check some metrics.
EXPECT_EQ("/drm/widevine/cdm_engine/add_key/time/count{error:2}",
actual_metrics.metric(0).name());
EXPECT_EQ("/drm/widevine/crypto_session/load_certificate_private_key"
"/time/count{success:1}",
actual_metrics.metric(2).name());
EXPECT_EQ("/drm/widevine/cdm_session/session_id",
actual_metrics.metric_sub_group(0).metric(0).name());
EXPECT_EQ(
"session_id_2",
actual_metrics.metric_sub_group(0).metric(0).value().string_value());
EXPECT_EQ(
"/drm/widevine/crypto_session/generic_decrypt/time/count"
"{error:0&length:1024&encryption_algorithm:1}",
actual_metrics.metric_sub_group(0).metric(1).name());
}
TEST_F(EngineMetricsTest, EngineMetricsSerializeAllSessions) {
EngineMetrics engine_metrics;
// Create two sessions and record some metrics.
SessionMetrics* session_metrics_1 = engine_metrics.AddSession();
session_metrics_1->SetSessionId("session_id_1");
SessionMetrics* session_metrics_2 = engine_metrics.AddSession();
session_metrics_2->SetSessionId("session_id_2");
// Mark only session 2 as completed.
session_metrics_2->SetCompleted();
drm_metrics::MetricsGroup actual_metrics;
engine_metrics.Serialize(&actual_metrics, false, false);
// Validate metric counts.
// No Engine-level metrics were recorded.
ASSERT_EQ(0, actual_metrics.metric_size());
// Two sub groups, 1 per session.
ASSERT_EQ(2, actual_metrics.metric_sub_group_size());
ASSERT_EQ(1, actual_metrics.metric_sub_group(0).metric_size());
// Spot check some metrics.
EXPECT_EQ("/drm/widevine/cdm_session/session_id",
actual_metrics.metric_sub_group(0).metric(0).name());
EXPECT_EQ(
"session_id_1",
actual_metrics.metric_sub_group(0).metric(0).value().string_value());
EXPECT_EQ("/drm/widevine/cdm_session/session_id",
actual_metrics.metric_sub_group(1).metric(0).name());
EXPECT_EQ(
"session_id_2",
actual_metrics.metric_sub_group(1).metric(0).value().string_value());
}
TEST_F(EngineMetricsTest, EngineMetricsRemoveSessions) {
EngineMetrics engine_metrics;
// Create two sessions and record some metrics.
SessionMetrics* session_metrics_1 = engine_metrics.AddSession();
session_metrics_1->SetSessionId("session_id_1");
SessionMetrics* session_metrics_2 = engine_metrics.AddSession();
session_metrics_2->SetSessionId("session_id_2");
// Mark only session 2 as completed.
session_metrics_2->SetCompleted();
// Serialize all metrics, don't remove any.
drm_metrics::MetricsGroup actual_metrics;
engine_metrics.Serialize(&actual_metrics, false, false);
// Validate metric counts.
// Two sub groups, 1 per session.
ASSERT_EQ(2, actual_metrics.metric_sub_group_size());
// Serialize completed metrics, remove them.
actual_metrics.Clear();
engine_metrics.Serialize(&actual_metrics, true, true);
// Validate metric counts.
// Only one, completed session should exist.
ASSERT_EQ(1, actual_metrics.metric_sub_group_size());
ASSERT_EQ(1, actual_metrics.metric_sub_group(0).metric_size());
EXPECT_EQ(
"session_id_2",
actual_metrics.metric_sub_group(0).metric(0).value().string_value());
// Serialize all metrics, remove them.
actual_metrics.Clear();
engine_metrics.Serialize(&actual_metrics, false, true);
// Validate metric counts.
// Only one, non-complete session should exist.
ASSERT_EQ(1, actual_metrics.metric_sub_group_size());
ASSERT_EQ(1, actual_metrics.metric_sub_group(0).metric_size());
EXPECT_EQ(
"session_id_1",
actual_metrics.metric_sub_group(0).metric(0).value().string_value());
// Serialize all metrics, don't remove any.
actual_metrics.Clear();
engine_metrics.Serialize(&actual_metrics, false, false);
// Validate metric counts.
// There should be no more metric subgroups left.
ASSERT_EQ(0, actual_metrics.metric_sub_group_size());
}
class SessionMetricsTest : public ::testing::Test {
};
TEST_F(SessionMetricsTest, AllSessionMetrics) {
SessionMetrics session_metrics;
session_metrics.SetSessionId("session_id 1");
session_metrics.cdm_session_life_span_.Record(1.0);
session_metrics.cdm_session_renew_key_.Record(1.0, NO_ERROR);
session_metrics.cdm_session_restore_offline_session_.Record(1.0, NO_ERROR);
session_metrics.cdm_session_restore_usage_session_.Record(1.0, NO_ERROR);
// Record a CryptoMetrics metric in the session.
session_metrics.GetCryptoMetrics()->crypto_session_generic_decrypt_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
MetricsGroup actual_metrics;
session_metrics.Serialize(&actual_metrics);
ASSERT_EQ(11, actual_metrics.metric_size());
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
// Spot check some metrics.
EXPECT_EQ("/drm/widevine/cdm_session/session_id",
actual_metrics.metric(0).name());
EXPECT_EQ("/drm/widevine/cdm_session/life_span",
actual_metrics.metric(1).name());
EXPECT_EQ("/drm/widevine/cdm_session/renew_key/time/mean{error:0}",
actual_metrics.metric(4).name());
EXPECT_EQ(1.0, actual_metrics.metric(4).value().double_value());
EXPECT_EQ("/drm/widevine/crypto_session/generic_decrypt/time/count"
"{error:0&length:1024&encryption_algorithm:1}",
actual_metrics.metric(9).name());
}
TEST_F(SessionMetricsTest, EmptySessionMetrics) {
SessionMetrics session_metrics;
MetricsGroup actual_metrics;
session_metrics.Serialize(&actual_metrics);
// Session metric always has a session id.
ASSERT_EQ(1, actual_metrics.metric_size());
EXPECT_EQ("/drm/widevine/cdm_session/session_id",
actual_metrics.metric(0).name());
EXPECT_EQ("", actual_metrics.metric(0).value().string_value());
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
}
class CryptoMetricsTest : public ::testing::Test {
};
TEST_F(CryptoMetricsTest, AllCryptoMetrics) {
CryptoMetrics crypto_metrics;
// Crypto session metrics.
crypto_metrics.crypto_session_delete_all_usage_reports_
.Record(1.0, NO_ERROR);
crypto_metrics.crypto_session_delete_multiple_usage_information_
.Record(1.0, NO_ERROR);
crypto_metrics.crypto_session_generic_decrypt_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
crypto_metrics.crypto_session_generic_encrypt_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128);
crypto_metrics.crypto_session_generic_sign_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256);
crypto_metrics.crypto_session_generic_verify_
.Record(2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256);
crypto_metrics.crypto_session_get_device_unique_id_.Record(1.0, true);
crypto_metrics.crypto_session_get_security_level_
.Record(1.0, kSecurityLevelL1);
crypto_metrics.crypto_session_get_system_id_.Record(1.0, true, 1234);
crypto_metrics.crypto_session_get_token_.Record(1.0, true);
crypto_metrics.crypto_session_life_span_.Record(1.0);
crypto_metrics.crypto_session_load_certificate_private_key_
.Record(1.0, true);
crypto_metrics.crypto_session_open_.Record(1.0, NO_ERROR, kLevelDefault);
crypto_metrics.crypto_session_update_usage_information_
.Record(1.0, NO_ERROR);
crypto_metrics.crypto_session_usage_information_support_.Record(1.0, true);
// Oem crypto metrics.
crypto_metrics.oemcrypto_api_version_.Record(1.0, 123, kLevelDefault);
crypto_metrics.oemcrypto_close_session_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_copy_buffer_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED,
kLevelDefault, Pow2Bucket(1025));
crypto_metrics.oemcrypto_deactivate_usage_entry_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_decrypt_cenc_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_delete_usage_entry_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_delete_usage_table_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_derive_keys_from_session_key_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_force_delete_usage_entry_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_generate_derived_keys_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_generate_nonce_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_generate_rsa_signature_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_generate_signature_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_generic_decrypt_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_generic_encrypt_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_generic_sign_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_generic_verify_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_get_device_id_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_get_hdcp_capability_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_get_key_data_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED,
Pow2Bucket(1025), kLevelDefault);
crypto_metrics.oemcrypto_get_max_number_of_sessions_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_get_number_of_open_sessions_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_get_oem_public_certificate_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_get_provisioning_method_
.Record(1.0, OEMCrypto_Keybox, kLevelDefault);
crypto_metrics.oemcrypto_get_random_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, Pow2Bucket(1025));
crypto_metrics.oemcrypto_initialize_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_install_keybox_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_is_anti_rollback_hw_present_
.Record(1.0, true, kLevelDefault);
crypto_metrics.oemcrypto_is_keybox_valid_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_load_device_rsa_key_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_load_keys_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_load_test_keybox_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_load_test_rsa_key_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_open_session_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_refresh_keys_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_report_usage_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_rewrap_device_rsa_key_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_rewrap_device_rsa_key_30_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_security_level_
.Record(1.0, kSecurityLevelL2, kLevelDefault);
crypto_metrics.oemcrypto_security_patch_level_
.Record(1.0, 123, kLevelDefault);
crypto_metrics.oemcrypto_select_key_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_supports_usage_table_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault);
crypto_metrics.oemcrypto_update_usage_table_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
crypto_metrics.oemcrypto_wrap_keybox_
.Record(1.0, OEMCrypto_ERROR_INIT_FAILED);
// Internal OEMCrypto Metrics
crypto_metrics.oemcrypto_initialization_mode_
.Record(1.0, OEMCrypto_INITIALIZED_FORCING_L3);
crypto_metrics.oemcrypto_l1_api_version_.Record(1.0, 12, 123);
MetricsGroup actual_metrics;
crypto_metrics.Serialize(&actual_metrics);
// 61 EventMetric instances, 2 values each.
ASSERT_EQ(122, actual_metrics.metric_size());
// Spot check some metrics.
EXPECT_EQ(
"/drm/widevine/crypto_session/delete_all_usage_reports/count"
"{error:0}",
actual_metrics.metric(0).name());
EXPECT_EQ(1, actual_metrics.metric(0).value().int_value());
EXPECT_EQ(
"/drm/widevine/oemcrypto/l1_api_version/mean{version:12&min_version:123}",
actual_metrics.metric(121).name());
EXPECT_EQ(1.0, actual_metrics.metric(121).value().double_value());
// No subgroups should exist.
EXPECT_EQ(0, actual_metrics.metric_sub_group_size());
}
} // namespace metrics
} // namespace wvcdm

View File

@@ -0,0 +1,77 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Unit tests for ValueMetric.
#include <string>
#include "value_metric.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "metric_serialization.h"
#include "scoped_ptr.h"
namespace wvcdm {
namespace metrics {
class MockMetricSerializer : 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));
};
class ValueMetricTest : public ::testing::Test {
public:
void SetUp() {
mock_serializer_.reset(new MockMetricSerializer());
}
protected:
scoped_ptr<MockMetricSerializer> mock_serializer_;
};
TEST_F(ValueMetricTest, StringValue) {
ValueMetric<std::string> value_metric("string/metric");
value_metric.Record("foo");
EXPECT_CALL(*mock_serializer_,
SetString("string/metric", "foo"));
value_metric.Serialize(mock_serializer_.get());
}
TEST_F(ValueMetricTest, DoubleValue) {
ValueMetric<double> value_metric("double/metric");
value_metric.Record(42.0);
EXPECT_CALL(*mock_serializer_,
SetDouble("double/metric", 42.0));
value_metric.Serialize(mock_serializer_.get());
}
TEST_F(ValueMetricTest, Int32Value) {
ValueMetric<int32_t> value_metric("int32/metric");
value_metric.Record(42);
EXPECT_CALL(*mock_serializer_,
SetInt32("int32/metric", 42));
value_metric.Serialize(mock_serializer_.get());
}
TEST_F(ValueMetricTest, Int64Value) {
ValueMetric<int64_t> value_metric("int64/metric");
value_metric.Record(42);
EXPECT_CALL(*mock_serializer_,
SetInt64("int64/metric", 42));
value_metric.Serialize(mock_serializer_.get());
}
} // namespace metrics
} // namespace wvcdm