Files
android/libwvdrmengine/cdm/test/wv_cdm_metrics_test.cpp
Adam Stone 457aceb859 Fixes metrics collection during CdmEngine close.
This fixes a problem where a CdmEngine instance (and its sessions) could
be closed before its metrics could be collected. The change allows the
wv_content_decryption_module to extract metrics from instances about to
be closed. These are held until reported to the caller.

Test: Manually verified that collection is now occurring correctly. Also
added unit test: wv_cdm_metric_test.

This is a merge from wvgerrit/29069

Change-Id: If82bfd5cae3b72b9d14ab4741424a7ae7cc0a3a6
2017-07-12 13:07:15 -07:00

145 lines
5.5 KiB
C++

// 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"));
}
}
}