Files
android/libwvdrmengine/cdm/test/wv_cdm_metrics_test.cpp
Srujan Gaddam 4c5c4caf66 Add detail about L3 initialization
Bug: b/70299597
Merge of http://go/wvgerrit/67304
Test: Android, CE CDM, and Linux tests

There's a few different things that can go wrong in the L3
initialization, with seeding and device key failures among others. They
should be recorded in metrics to track. Along the same lines, since
multiple errors can happen in conjunction, metrics needs to change to
add more fields for errors. This CL also adds the
hidl_metrics_adapter_unittest to the Android test scripts.

Change-Id: Ie5bcf81bbe294a1136c58410f90087a13b3d911d
2018-12-14 11:32:19 -08:00

183 lines
6.7 KiB
C++

// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
//
// 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 "string_conversions.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::Ge;
using ::testing::Gt;
using ::testing::Lt;
using ::testing::Test;
using wvcdm::CdmResponseType;
namespace {
const std::string kEmptyServiceCertificate;
} // unnamed namespace
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, IdentifierNotFound) {
drm_metrics::WvCdmMetrics metrics;
ASSERT_EQ(wvcdm::UNKNOWN_ERROR,
decryptor_.GetMetrics(kDefaultCdmIdentifier, &metrics));
}
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,
kEmptyServiceCertificate, &request,
&provisioning_server_url));
drm_metrics::WvCdmMetrics metrics;
ASSERT_EQ(wvcdm::NO_ERROR,
decryptor_.GetMetrics(kDefaultCdmIdentifier, &metrics));
// 100 is an arbitrary high value that shouldn't ever occur.
EXPECT_THAT(
metrics.engine_metrics().level3_oemcrypto_initialization_error()
.int_value(), Lt(100));
EXPECT_THAT(
metrics.engine_metrics().level3_oemcrypto_initialization_error()
.int_value(), Ge(0));
EXPECT_THAT(
metrics.engine_metrics().oemcrypto_initialization_mode().int_value(),
Lt(100));
EXPECT_THAT(
metrics.engine_metrics().oemcrypto_initialization_mode().int_value(),
Ge(0));
EXPECT_THAT(
metrics.engine_metrics().previous_oemcrypto_initialization_failure()
.int_value(), Lt(100));
EXPECT_THAT(
metrics.engine_metrics().previous_oemcrypto_initialization_failure()
.int_value(), Ge(0));
ASSERT_THAT(metrics.engine_metrics()
.cdm_engine_get_provisioning_request_time_us().size(), Eq(1));
EXPECT_THAT(metrics.engine_metrics()
.cdm_engine_get_provisioning_request_time_us(0)
.operation_count(),
Eq(1u));
}
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));
drm_metrics::WvCdmMetrics metrics;
ASSERT_EQ(wvcdm::NO_ERROR,
decryptor_.GetMetrics(kDefaultCdmIdentifier, &metrics));
std::string serialized_metrics;
ASSERT_TRUE(metrics.SerializeToString(&serialized_metrics));
// Spot check some metric values.
// Validate engine-level metrics.
EXPECT_TRUE(metrics.engine_metrics()
.has_level3_oemcrypto_initialization_error());
EXPECT_TRUE(metrics.engine_metrics().has_oemcrypto_initialization_mode());
EXPECT_TRUE(metrics.engine_metrics()
.has_previous_oemcrypto_initialization_failure());
ASSERT_THAT(metrics.engine_metrics().cdm_engine_open_session().size(), Eq(1));
EXPECT_THAT(metrics.engine_metrics().cdm_engine_open_session(0).count(),
Eq(1));
EXPECT_THAT(metrics.engine_metrics()
.cdm_engine_open_session(0).attributes().error_code(),
Eq(CdmResponseType::NEED_PROVISIONING));
// Validate a session-level metric.
ASSERT_THAT(metrics.session_metrics().size(), Eq(1));
EXPECT_THAT(
metrics.session_metrics(0).cdm_session_life_span_ms().double_value(),
Gt(0.0))
<< "Unexpected failure with session_metrics: "
<< wvcdm::b2a_hex(serialized_metrics);
}
TEST_F(WvContentDecryptionModuleMetricsTest,
DifferentCdmIdentifiersHaveDifferentMetrics) {
CdmSessionId session_id;
wvcdm::CdmKeySystem key_system("com.widevine");
CdmIdentifier identifiers[] = { kDefaultCdmIdentifier,
{ "foo", "bar", "baz", 7 },
// Note that this has all the same parameters
// as the one above except for the unique_id.
{ "foo", "bar", "baz", 8 }};
const int cdm_engine_count = 3;
for (int i = 0; i < cdm_engine_count; i++) {
// To make sure we can detect different engine metrics,
// make the open session call a different number of times for
// each identifier.
for (int j = 0; j <= i; j ++) {
EXPECT_EQ(CdmResponseType::NEED_PROVISIONING,
decryptor_.OpenSession(key_system, NULL,
identifiers[i], NULL, &session_id));
}
}
for (int i = 0; i < cdm_engine_count; i++) {
drm_metrics::WvCdmMetrics metrics;
metrics.Clear();
ASSERT_EQ(wvcdm::NO_ERROR,
decryptor_.GetMetrics(identifiers[i], &metrics));
std::string serialized_metrics;
ASSERT_TRUE(metrics.SerializeToString(&serialized_metrics));
ASSERT_THAT(metrics.engine_metrics().cdm_engine_open_session().size(),
Eq(1));
// The number of times open session was called should match the index
// of the identifier
EXPECT_THAT(metrics.engine_metrics().cdm_engine_open_session(0).count(),
Eq(i + 1));
EXPECT_THAT(
metrics.engine_metrics()
.cdm_engine_open_session(0).attributes().error_code(),
Eq(CdmResponseType::NEED_PROVISIONING));
// Spot check a session-level metric.
ASSERT_THAT(metrics.session_metrics().size(), Eq(i + 1))
<< "Unexpected failure with session_metrics: "
<< wvcdm::b2a_hex(serialized_metrics);
EXPECT_THAT(metrics.session_metrics(0)
.cdm_session_life_span_ms().double_value(), Gt(0.0))
<< "Unexpected failure with session_metrics: "
<< wvcdm::b2a_hex(serialized_metrics);
}
}
} // wvcdm namespace