// Copyright 2017 Google Inc. All Rights Reserved. // // This file contains unit tests for the WvContentDecryptionModule class // that pertain to collecting and reporting metrics. #include "gmock/gmock.h" #include "log.h" #include "metrics.pb.h" #include "test_base.h" #include "test_printers.h" #include "wv_cdm_types.h" #include "wv_content_decryption_module.h" using ::testing::Eq; using ::testing::StrEq; using ::testing::Gt; using ::testing::Test; using wvcdm::CdmResponseType; namespace wvcdm { // This class is used to test the metrics-related feaures of the // WvContentDecryptionModule class. class WvContentDecryptionModuleMetricsTest : public ::testing::Test { protected: wvcdm::WvContentDecryptionModule decryptor_; }; TEST_F(WvContentDecryptionModuleMetricsTest, NoMetrics) { // Get metrics before any operations are performed. std::string serialized_metrics; decryptor_.GetSerializedMetrics(&serialized_metrics); EXPECT_TRUE(serialized_metrics.empty()); } TEST_F(WvContentDecryptionModuleMetricsTest, EngineOnlyMetrics) { std::string request; std::string provisioning_server_url; CdmCertificateType cert_type = kCertificateWidevine; std::string cert_authority, cert, wrapped_key; // This call will create a CdmEngine instance with an EngineMetrics instance. EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest(cert_type, cert_authority, kDefaultCdmIdentifier, &request, &provisioning_server_url)); std::string serialized_metrics; decryptor_.GetSerializedMetrics(&serialized_metrics); // Spot check some metric values. drm_metrics::MetricsGroup metrics; ASSERT_TRUE(metrics.ParseFromString(serialized_metrics)); EXPECT_THAT(metrics.metric_size(), Eq(0)); ASSERT_THAT(metrics.metric_sub_group_size(), Eq(1)); ASSERT_THAT(metrics.metric_sub_group(0).metric_size(), Gt(0)); EXPECT_THAT(metrics.metric_sub_group(0).metric_sub_group_size(), Eq(0)); EXPECT_THAT( metrics.metric_sub_group(0).metric(0).name(), StrEq("/drm/widevine/cdm_engine/" "get_provisioning_request/time/count{error:0}")); EXPECT_THAT(metrics.metric_sub_group(0).metric(0).value().int_value(), Eq(1)); } TEST_F(WvContentDecryptionModuleMetricsTest, EngineAndSessionMetrics) { CdmSessionId session_id; wvcdm::CdmKeySystem key_system("com.widevine"); // Openning the session will fail with NEEDS_PROVISIONING error. But it will // still create some session-level stats. EXPECT_EQ(CdmResponseType::NEED_PROVISIONING, decryptor_.OpenSession(key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id)); // The metrics will have a single engine and single session stats. std::string serialized_metrics; decryptor_.GetSerializedMetrics(&serialized_metrics); // Spot check some metric values. drm_metrics::MetricsGroup metrics; ASSERT_TRUE(metrics.ParseFromString(serialized_metrics)); // The outer container will never have metrics. EXPECT_THAT(metrics.metric_size(), Eq(0)); ASSERT_THAT(metrics.metric_sub_group_size(), Eq(1)); ASSERT_THAT(metrics.metric_sub_group(0).metric_size(), Gt(0)); // Validate an engine-level metric. EXPECT_THAT( metrics.metric_sub_group(0).metric(0).name(), StrEq("/drm/widevine/cdm_engine/open_session/time/count{error:7}")); EXPECT_THAT(metrics.metric_sub_group(0).metric(0).value().int_value(), Eq(1)); // Validate a session-level metric. EXPECT_THAT(metrics.metric_sub_group(0).metric_sub_group_size(), Eq(1)); EXPECT_THAT( metrics.metric_sub_group(0).metric_sub_group(0).metric(0).name(), StrEq("/drm/widevine/cdm_session/session_id")); } TEST_F(WvContentDecryptionModuleMetricsTest, MultipleEngineMetric) { CdmSessionId session_id; wvcdm::CdmKeySystem key_system("com.widevine"); CdmIdentifier identifier = { "foo", "bar" }; // Openning the session will fail with NEEDS_PROVISIONING error. But it will // still create some session-level stats. EXPECT_EQ(CdmResponseType::NEED_PROVISIONING, decryptor_.OpenSession(key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id)); // Open a second engine with a custom identifier. EXPECT_EQ(CdmResponseType::NEED_PROVISIONING, decryptor_.OpenSession(key_system, NULL, identifier, NULL, &session_id)); // The metrics will now have two engines with single session stats each. std::string serialized_metrics; decryptor_.GetSerializedMetrics(&serialized_metrics); // Spot check some metric values. drm_metrics::MetricsGroup metrics; ASSERT_TRUE(metrics.ParseFromString(serialized_metrics)); // The outer container will never have metrics. EXPECT_THAT(metrics.metric_size(), Eq(0)); // Two engine-level metrics are expected. ASSERT_THAT(metrics.metric_sub_group_size(), Eq(2)); for (int i = 0; i < metrics.metric_sub_group_size(); i++) { // Validate the engine-level metric. ASSERT_THAT(metrics.metric_sub_group(i).metric_size(), Gt(0)); EXPECT_THAT( metrics.metric_sub_group(i).metric(0).name(), StrEq("/drm/widevine/cdm_engine/open_session/time/count{error:7}")); EXPECT_THAT(metrics.metric_sub_group(i).metric(0).value().int_value(), Eq(1)); // Validate a session-level metric. EXPECT_THAT(metrics.metric_sub_group(i).metric_sub_group_size(), Eq(1)); EXPECT_THAT( metrics.metric_sub_group(i).metric_sub_group(0).metric(0).name(), StrEq("/drm/widevine/cdm_session/session_id")); } } }