1. "Change CdmResponseType from enum into a struct" Merged from http://go/wvgerrit/163199 Bug: 253271674 2. "Log request information when server returns 401" Bug: 260760387 Bug: 186031735 Merged from http://go/wvgerrit/162798 3. "Specify server version on the command line" Bug: 251599048 Merged from http://go/wvgerrit/158897 Test: build android.hardware.drm-service.widevine Test: Netflix and Play Movies & TV Test: build_and_run_all_unit_tests.sh Bug: 253271674 Change-Id: I70c950acce070609ee0343920ec68e66b058bc23
189 lines
6.8 KiB
C++
189 lines
6.8 KiB
C++
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine License
|
|
// Agreement.
|
|
//
|
|
// This file contains unit tests for the WvContentDecryptionModule class
|
|
// that pertain to collecting and reporting metrics.
|
|
|
|
#include "cdm_identifier.h"
|
|
#include "gmock/gmock.h"
|
|
#include "log.h"
|
|
#include "string_conversions.h"
|
|
#include "test_base.h"
|
|
#include "test_printers.h"
|
|
#include "wv_cdm_types.h"
|
|
#include "wv_content_decryption_module.h"
|
|
#include "wv_metrics.pb.h"
|
|
|
|
using ::testing::Eq;
|
|
using ::testing::Ge;
|
|
using ::testing::Gt;
|
|
using ::testing::Lt;
|
|
using ::testing::StrEq;
|
|
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 WvCdmTestBase {
|
|
protected:
|
|
void Unprovision(CdmIdentifier identifier) {
|
|
EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL1, identifier));
|
|
EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL3, identifier));
|
|
}
|
|
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(NO_ERROR, decryptor_.GetProvisioningRequest(
|
|
cert_type, cert_authority, kDefaultCdmIdentifier,
|
|
kEmptyServiceCertificate, kLevelDefault, &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");
|
|
Unprovision(kDefaultCdmIdentifier);
|
|
|
|
// Opening the session will fail with NEEDS_PROVISIONING error. But it will
|
|
// still create some session-level stats.
|
|
EXPECT_EQ(wvcdm::NEED_PROVISIONING,
|
|
decryptor_.OpenSession(key_system, nullptr, kDefaultCdmIdentifier,
|
|
nullptr, &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());
|
|
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(NEED_PROVISIONING));
|
|
|
|
// Validate a session-level metric.
|
|
ASSERT_THAT(metrics.session_metrics().size(), Eq(1));
|
|
}
|
|
|
|
TEST_F(WvContentDecryptionModuleMetricsTest,
|
|
DifferentCdmIdentifiersHaveDifferentMetrics) {
|
|
CdmSessionId session_id;
|
|
wvcdm::CdmKeySystem key_system("com.widevine");
|
|
CdmIdentifier identifiers[] = {kDefaultCdmIdentifier,
|
|
{"foo", "bar", "baz", 7, 10},
|
|
// Note that this has all the same parameters
|
|
// as the one above except for the unique_id.
|
|
{"foo", "bar", "baz", 8, 11}};
|
|
const int cdm_engine_count = 3;
|
|
|
|
// Force Unprovision.
|
|
for (int i = 0; i < cdm_engine_count; i++) {
|
|
Unprovision(identifiers[i]);
|
|
}
|
|
|
|
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(NEED_PROVISIONING,
|
|
decryptor_.OpenSession(key_system, nullptr, identifiers[i],
|
|
nullptr, &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(NEED_PROVISIONING));
|
|
|
|
// Spot check a session-level metric.
|
|
ASSERT_THAT(metrics.session_metrics().size(), Eq(i + 1))
|
|
<< "Unexpected failure with session_metrics: "
|
|
<< wvutil::b2a_hex(serialized_metrics);
|
|
}
|
|
}
|
|
|
|
} // namespace wvcdm
|