|
|
|
|
@@ -21,12 +21,36 @@
|
|
|
|
|
#include "wv_cdm_constants.h"
|
|
|
|
|
#include "wv_cdm_types.h"
|
|
|
|
|
|
|
|
|
|
// gmock methods
|
|
|
|
|
using ::testing::_;
|
|
|
|
|
using ::testing::AllOf;
|
|
|
|
|
using ::testing::AtMost;
|
|
|
|
|
using ::testing::ContainerEq;
|
|
|
|
|
using ::testing::Contains;
|
|
|
|
|
using ::testing::DoAll;
|
|
|
|
|
using ::testing::ElementsAre;
|
|
|
|
|
using ::testing::ElementsAreArray;
|
|
|
|
|
using ::testing::Ge;
|
|
|
|
|
using ::testing::Invoke;
|
|
|
|
|
using ::testing::InvokeWithoutArgs;
|
|
|
|
|
using ::testing::Lt;
|
|
|
|
|
using ::testing::NotNull;
|
|
|
|
|
using ::testing::Return;
|
|
|
|
|
using ::testing::SaveArg;
|
|
|
|
|
using ::testing::SetArgPointee;
|
|
|
|
|
using ::testing::SizeIs;
|
|
|
|
|
using ::testing::StrEq;
|
|
|
|
|
using ::testing::UnorderedElementsAre;
|
|
|
|
|
using ::testing::UnorderedElementsAreArray;
|
|
|
|
|
|
|
|
|
|
namespace wvcdm {
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
const std::string kEmptyString;
|
|
|
|
|
|
|
|
|
|
constexpr size_t kDefaultTableCapacity = 300;
|
|
|
|
|
|
|
|
|
|
constexpr int64_t kDefaultExpireDuration = 33 * 24 * 60 * 60; // 33 Days
|
|
|
|
|
|
|
|
|
|
const CdmUsageTableHeader kEmptyUsageTableHeader;
|
|
|
|
|
@@ -172,7 +196,7 @@ const std::vector<DeviceFiles::CdmUsageData> kEmptyUsageInfoUsageDataList;
|
|
|
|
|
const std::vector<CdmUsageEntryInfo> kEmptyUsageEntryInfoVector;
|
|
|
|
|
std::vector<CdmUsageEntryInfo> kUsageEntryInfoVector;
|
|
|
|
|
std::vector<CdmUsageEntryInfo> k10UsageEntryInfoVector;
|
|
|
|
|
std::vector<CdmUsageEntryInfo> k201UsageEntryInfoVector;
|
|
|
|
|
std::vector<CdmUsageEntryInfo> kOverFullUsageEntryInfoVector;
|
|
|
|
|
|
|
|
|
|
const DeviceFiles::LicenseState kActiveLicenseState =
|
|
|
|
|
DeviceFiles::kLicenseStateActive;
|
|
|
|
|
@@ -275,23 +299,24 @@ void InitVectorConstants() {
|
|
|
|
|
k10UsageEntryInfoVector.push_back(kUsageEntryInfoOfflineLicense5);
|
|
|
|
|
k10UsageEntryInfoVector.push_back(kUsageEntryInfoSecureStop5);
|
|
|
|
|
|
|
|
|
|
k201UsageEntryInfoVector.clear();
|
|
|
|
|
for (size_t i = 0; i < 201; ++i) {
|
|
|
|
|
kOverFullUsageEntryInfoVector.clear();
|
|
|
|
|
for (size_t i = 0; i < (kDefaultTableCapacity + 1); ++i) {
|
|
|
|
|
switch (i % 4) {
|
|
|
|
|
case 0:
|
|
|
|
|
k201UsageEntryInfoVector.push_back(kUsageEntryInfoOfflineLicense1);
|
|
|
|
|
kOverFullUsageEntryInfoVector.push_back(kUsageEntryInfoOfflineLicense1);
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
k201UsageEntryInfoVector.push_back(kUsageEntryInfoSecureStop1);
|
|
|
|
|
kOverFullUsageEntryInfoVector.push_back(kUsageEntryInfoSecureStop1);
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
k201UsageEntryInfoVector.push_back(kUsageEntryInfoOfflineLicense2);
|
|
|
|
|
kOverFullUsageEntryInfoVector.push_back(kUsageEntryInfoOfflineLicense2);
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
k201UsageEntryInfoVector.push_back(kUsageEntryInfoSecureStop2);
|
|
|
|
|
kOverFullUsageEntryInfoVector.push_back(kUsageEntryInfoSecureStop2);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
k201UsageEntryInfoVector.push_back(kUsageEntryInfoStorageTypeUnknown);
|
|
|
|
|
kOverFullUsageEntryInfoVector.push_back(
|
|
|
|
|
kUsageEntryInfoStorageTypeUnknown);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -436,8 +461,8 @@ class MockCryptoSession : public TestCryptoSession {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
size_t maximum_usage_table_entries_ = 0;
|
|
|
|
|
bool maximum_usage_table_entries_set_ = false;
|
|
|
|
|
size_t maximum_usage_table_entries_ = kDefaultTableCapacity;
|
|
|
|
|
bool maximum_usage_table_entries_set_ = true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Partial mock of the UsageTableHeader. This is to test when dependency
|
|
|
|
|
@@ -447,32 +472,25 @@ class MockUsageTableHeader : public UsageTableHeader {
|
|
|
|
|
MockUsageTableHeader() : UsageTableHeader() {}
|
|
|
|
|
MOCK_METHOD4(InvalidateEntry, CdmResponseType(uint32_t, bool, DeviceFiles*,
|
|
|
|
|
metrics::CryptoMetrics*));
|
|
|
|
|
MOCK_METHOD6(AddEntry,
|
|
|
|
|
CdmResponseType(CryptoSession*, bool, const CdmKeySetId&,
|
|
|
|
|
const std::string&, const CdmKeyResponse&,
|
|
|
|
|
uint32_t*));
|
|
|
|
|
|
|
|
|
|
CdmResponseType SuperAddEntry(CryptoSession* crypto_session,
|
|
|
|
|
bool persistent_license,
|
|
|
|
|
const CdmKeySetId& key_set_id,
|
|
|
|
|
const std::string& usage_info_filename,
|
|
|
|
|
const CdmKeyResponse& license_message,
|
|
|
|
|
uint32_t* usage_entry_number) {
|
|
|
|
|
return UsageTableHeader::AddEntry(crypto_session, persistent_license,
|
|
|
|
|
key_set_id, usage_info_filename,
|
|
|
|
|
license_message, usage_entry_number);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
// gmock methods
|
|
|
|
|
using ::testing::_;
|
|
|
|
|
using ::testing::AllOf;
|
|
|
|
|
using ::testing::AtMost;
|
|
|
|
|
using ::testing::ContainerEq;
|
|
|
|
|
using ::testing::Contains;
|
|
|
|
|
using ::testing::DoAll;
|
|
|
|
|
using ::testing::ElementsAre;
|
|
|
|
|
using ::testing::ElementsAreArray;
|
|
|
|
|
using ::testing::Ge;
|
|
|
|
|
using ::testing::Invoke;
|
|
|
|
|
using ::testing::InvokeWithoutArgs;
|
|
|
|
|
using ::testing::Lt;
|
|
|
|
|
using ::testing::NotNull;
|
|
|
|
|
using ::testing::Return;
|
|
|
|
|
using ::testing::SaveArg;
|
|
|
|
|
using ::testing::SetArgPointee;
|
|
|
|
|
using ::testing::SizeIs;
|
|
|
|
|
using ::testing::StrEq;
|
|
|
|
|
using ::testing::UnorderedElementsAre;
|
|
|
|
|
using ::testing::UnorderedElementsAreArray;
|
|
|
|
|
|
|
|
|
|
class UsageTableHeaderTest : public WvCdmTestBase {
|
|
|
|
|
public:
|
|
|
|
|
static void SetUpTestCase() {
|
|
|
|
|
@@ -523,6 +541,7 @@ class UsageTableHeaderTest : public WvCdmTestBase {
|
|
|
|
|
// Create new mock objects if using MockUsageTableHeader
|
|
|
|
|
device_files_ = new MockDeviceFiles();
|
|
|
|
|
crypto_session_ = new MockCryptoSession(&crypto_metrics_);
|
|
|
|
|
|
|
|
|
|
MockUsageTableHeader* mock_usage_table_header = new MockUsageTableHeader();
|
|
|
|
|
|
|
|
|
|
// mock_usage_table_header_ object takes ownership of these objects
|
|
|
|
|
@@ -652,16 +671,16 @@ TEST_P(UsageTableHeaderInitializationTest, UsageTableHeaderExists) {
|
|
|
|
|
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_P(UsageTableHeaderInitializationTest, 200UsageEntries) {
|
|
|
|
|
std::vector<CdmUsageEntryInfo> usage_entries_200 = k201UsageEntryInfoVector;
|
|
|
|
|
usage_entries_200.resize(200);
|
|
|
|
|
TEST_P(UsageTableHeaderInitializationTest, UsageEntriesAtCapacity) {
|
|
|
|
|
std::vector<CdmUsageEntryInfo> usage_entries = kOverFullUsageEntryInfoVector;
|
|
|
|
|
usage_entries.resize(kDefaultTableCapacity);
|
|
|
|
|
const SecurityLevel security_level =
|
|
|
|
|
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
|
|
|
|
SetArgPointee<1>(usage_entries_200),
|
|
|
|
|
SetArgPointee<2>(false), Return(true)));
|
|
|
|
|
SetArgPointee<1>(usage_entries), SetArgPointee<2>(false),
|
|
|
|
|
Return(true)));
|
|
|
|
|
EXPECT_CALL(*crypto_session_,
|
|
|
|
|
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
|
|
|
|
.WillOnce(Return(NO_ERROR));
|
|
|
|
|
@@ -670,11 +689,76 @@ TEST_P(UsageTableHeaderInitializationTest, 200UsageEntries) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_P(UsageTableHeaderInitializationTest,
|
|
|
|
|
201UsageEntries_AddEntryFails_UsageTableHeaderRecreated) {
|
|
|
|
|
UsageEntries_NoCapacity_UnderMinimum) {
|
|
|
|
|
crypto_session_->SetMaximumUsageTableEntries(0); // Unlimited.
|
|
|
|
|
std::vector<CdmUsageEntryInfo> usage_entries = kOverFullUsageEntryInfoVector;
|
|
|
|
|
constexpr size_t kHalfMinCapacity = kDefaultTableCapacity / 2;
|
|
|
|
|
usage_entries.resize(kHalfMinCapacity);
|
|
|
|
|
const SecurityLevel security_level =
|
|
|
|
|
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
|
|
|
|
SetArgPointee<1>(k201UsageEntryInfoVector),
|
|
|
|
|
SetArgPointee<1>(usage_entries), SetArgPointee<2>(false),
|
|
|
|
|
Return(true)));
|
|
|
|
|
EXPECT_CALL(*crypto_session_,
|
|
|
|
|
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
|
|
|
|
.WillOnce(Return(NO_ERROR));
|
|
|
|
|
// No expectations of creating or deleting entries if the number of entries
|
|
|
|
|
// is less than minimally required capacity.
|
|
|
|
|
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_P(UsageTableHeaderInitializationTest, UsageEntries_NoCapacity) {
|
|
|
|
|
crypto_session_->SetMaximumUsageTableEntries(0); // Unlimited.
|
|
|
|
|
std::vector<CdmUsageEntryInfo> usage_entries = kOverFullUsageEntryInfoVector;
|
|
|
|
|
usage_entries.resize(kDefaultTableCapacity);
|
|
|
|
|
const SecurityLevel security_level =
|
|
|
|
|
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
|
|
|
|
SetArgPointee<1>(usage_entries), SetArgPointee<2>(false),
|
|
|
|
|
Return(true)));
|
|
|
|
|
EXPECT_CALL(*crypto_session_,
|
|
|
|
|
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
|
|
|
|
.WillOnce(Return(NO_ERROR));
|
|
|
|
|
|
|
|
|
|
// Expect an attempt to create a new entry.
|
|
|
|
|
EXPECT_CALL(*crypto_session_, Open(security_level))
|
|
|
|
|
.WillOnce(Return(NO_ERROR));
|
|
|
|
|
const uint32_t expect_usage_entry_number = kDefaultTableCapacity;
|
|
|
|
|
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<0>(expect_usage_entry_number), Return(NO_ERROR)));
|
|
|
|
|
EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
StoreUsageTableInfo(kAnotherUsageTableHeader,
|
|
|
|
|
SizeIs(kDefaultTableCapacity + 1)))
|
|
|
|
|
.WillOnce(Return(true));
|
|
|
|
|
|
|
|
|
|
// Delete the entry after.
|
|
|
|
|
EXPECT_CALL(
|
|
|
|
|
*crypto_session_,
|
|
|
|
|
ShrinkUsageTableHeader(security_level, kDefaultTableCapacity, NotNull()))
|
|
|
|
|
.WillOnce(DoAll(SetArgPointee<2>(kYetAnotherUsageTableHeader),
|
|
|
|
|
Return(NO_ERROR)));
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
StoreUsageTableInfo(kYetAnotherUsageTableHeader,
|
|
|
|
|
SizeIs(kDefaultTableCapacity)))
|
|
|
|
|
.WillOnce(Return(true));
|
|
|
|
|
|
|
|
|
|
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_P(UsageTableHeaderInitializationTest,
|
|
|
|
|
UsageEntriesOverCapacity_AddEntryFails_UsageTableHeaderRecreated) {
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
|
|
|
|
SetArgPointee<1>(kOverFullUsageEntryInfoVector),
|
|
|
|
|
SetArgPointee<2>(false), Return(true)));
|
|
|
|
|
|
|
|
|
|
const SecurityLevel security_level =
|
|
|
|
|
@@ -696,7 +780,8 @@ TEST_P(UsageTableHeaderInitializationTest,
|
|
|
|
|
.WillOnce(Return(true));
|
|
|
|
|
|
|
|
|
|
// Expectations for AddEntry
|
|
|
|
|
const uint32_t expect_usage_entry_number = k201UsageEntryInfoVector.size();
|
|
|
|
|
const uint32_t expect_usage_entry_number =
|
|
|
|
|
kOverFullUsageEntryInfoVector.size();
|
|
|
|
|
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
|
|
|
|
.WillOnce(DoAll(SetArgPointee<0>(expect_usage_entry_number),
|
|
|
|
|
Return(CREATE_USAGE_ENTRY_UNKNOWN_ERROR)));
|
|
|
|
|
@@ -705,9 +790,46 @@ TEST_P(UsageTableHeaderInitializationTest,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_P(UsageTableHeaderInitializationTest,
|
|
|
|
|
201UsageEntries_AddInvalidateEntrySucceeds) {
|
|
|
|
|
std::vector<CdmUsageEntryInfo> usage_entries_202 = k201UsageEntryInfoVector;
|
|
|
|
|
usage_entries_202.push_back(kDummyUsageEntryInfo);
|
|
|
|
|
UsageEntries_NoCapacity_AddEntryFails_UsageTableHeaderRecreated) {
|
|
|
|
|
crypto_session_->SetMaximumUsageTableEntries(0); // Unlimited.
|
|
|
|
|
std::vector<CdmUsageEntryInfo> usage_entries = kOverFullUsageEntryInfoVector;
|
|
|
|
|
usage_entries.resize(kDefaultTableCapacity);
|
|
|
|
|
const SecurityLevel security_level =
|
|
|
|
|
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
|
|
|
|
SetArgPointee<1>(usage_entries), SetArgPointee<2>(false),
|
|
|
|
|
Return(true)));
|
|
|
|
|
EXPECT_CALL(*crypto_session_,
|
|
|
|
|
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
|
|
|
|
.WillOnce(Return(NO_ERROR));
|
|
|
|
|
// Try to create a new entry, and fail.
|
|
|
|
|
EXPECT_CALL(*crypto_session_, Open(security_level))
|
|
|
|
|
.WillOnce(Return(NO_ERROR));
|
|
|
|
|
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
|
|
|
|
.WillOnce(Return(CREATE_USAGE_ENTRY_UNKNOWN_ERROR));
|
|
|
|
|
// Expect clean up.
|
|
|
|
|
EXPECT_CALL(*device_files_, DeleteAllLicenses()).WillOnce(Return(true));
|
|
|
|
|
EXPECT_CALL(*device_files_, DeleteAllUsageInfo()).WillOnce(Return(true));
|
|
|
|
|
EXPECT_CALL(*device_files_, DeleteUsageTableInfo()).WillOnce(Return(true));
|
|
|
|
|
// Expect recreation of usage table.
|
|
|
|
|
EXPECT_CALL(*crypto_session_,
|
|
|
|
|
CreateUsageTableHeader(security_level, NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<1>(kEmptyUsageTableHeader), Return(NO_ERROR)));
|
|
|
|
|
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader,
|
|
|
|
|
kEmptyUsageEntryInfoVector))
|
|
|
|
|
.WillOnce(Return(true));
|
|
|
|
|
|
|
|
|
|
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_P(UsageTableHeaderInitializationTest,
|
|
|
|
|
UsageEntriesOverCapacity_AddInvalidateEntrySucceeds) {
|
|
|
|
|
// Capacity +2.
|
|
|
|
|
std::vector<CdmUsageEntryInfo> usage_entries = kOverFullUsageEntryInfoVector;
|
|
|
|
|
usage_entries.push_back(kDummyUsageEntryInfo);
|
|
|
|
|
|
|
|
|
|
const SecurityLevel security_level =
|
|
|
|
|
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
|
|
|
|
@@ -715,33 +837,36 @@ TEST_P(UsageTableHeaderInitializationTest,
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
|
|
|
|
SetArgPointee<1>(k201UsageEntryInfoVector),
|
|
|
|
|
SetArgPointee<1>(kOverFullUsageEntryInfoVector),
|
|
|
|
|
SetArgPointee<2>(false), Return(true)));
|
|
|
|
|
EXPECT_CALL(*crypto_session_,
|
|
|
|
|
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
|
|
|
|
.WillOnce(Return(NO_ERROR));
|
|
|
|
|
|
|
|
|
|
// Expectations for AddEntry
|
|
|
|
|
const uint32_t expect_usage_entry_number = k201UsageEntryInfoVector.size();
|
|
|
|
|
const uint32_t expect_usage_entry_number =
|
|
|
|
|
kOverFullUsageEntryInfoVector.size();
|
|
|
|
|
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
|
|
|
|
.WillOnce(DoAll(SetArgPointee<0>(expect_usage_entry_number),
|
|
|
|
|
Return(NO_ERROR)));
|
|
|
|
|
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kUsageTableHeader,
|
|
|
|
|
usage_entries_202))
|
|
|
|
|
EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
StoreUsageTableInfo(kAnotherUsageTableHeader, usage_entries))
|
|
|
|
|
.WillOnce(Return(true));
|
|
|
|
|
|
|
|
|
|
// Expectations for InvalidateEntry, assumes no entry other entry is invalid.
|
|
|
|
|
EXPECT_CALL(*crypto_session_, Open(security_level))
|
|
|
|
|
.WillOnce(Return(NO_ERROR));
|
|
|
|
|
EXPECT_CALL(*crypto_session_,
|
|
|
|
|
ShrinkUsageTableHeader(security_level,
|
|
|
|
|
usage_entries_202.size() - 1, NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
|
|
|
|
ShrinkUsageTableHeader(security_level, usage_entries.size() - 1,
|
|
|
|
|
NotNull()))
|
|
|
|
|
.WillOnce(DoAll(SetArgPointee<2>(kYetAnotherUsageTableHeader),
|
|
|
|
|
Return(NO_ERROR)));
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
StoreUsageTableInfo(
|
|
|
|
|
kAnotherUsageTableHeader,
|
|
|
|
|
SizeIs(k201UsageEntryInfoVector.size())))
|
|
|
|
|
StoreUsageTableInfo(kYetAnotherUsageTableHeader,
|
|
|
|
|
SizeIs(kOverFullUsageEntryInfoVector.size())))
|
|
|
|
|
.WillOnce(Return(true));
|
|
|
|
|
|
|
|
|
|
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
|
|
|
|
@@ -800,10 +925,12 @@ TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveOfflineUsageEntry) {
|
|
|
|
|
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<0>(expect_usage_entry_number), Return(NO_ERROR)));
|
|
|
|
|
|
|
|
|
|
EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
StoreUsageTableInfo(
|
|
|
|
|
kUsageTableHeader,
|
|
|
|
|
kAnotherUsageTableHeader,
|
|
|
|
|
UnorderedElementsAreArray(expect_usage_entry_info_vector)))
|
|
|
|
|
.WillOnce(Return(true));
|
|
|
|
|
|
|
|
|
|
@@ -831,10 +958,12 @@ TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveSecureStopUsageEntry) {
|
|
|
|
|
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<0>(expect_usage_entry_number), Return(NO_ERROR)));
|
|
|
|
|
|
|
|
|
|
EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
StoreUsageTableInfo(
|
|
|
|
|
kUsageTableHeader,
|
|
|
|
|
kAnotherUsageTableHeader,
|
|
|
|
|
UnorderedElementsAreArray(expect_usage_entry_info_vector)))
|
|
|
|
|
.WillOnce(Return(true));
|
|
|
|
|
|
|
|
|
|
@@ -859,11 +988,13 @@ TEST_F(UsageTableHeaderTest, AddEntry_SkipUsageEntries) {
|
|
|
|
|
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<0>(expect_usage_entry_number), Return(NO_ERROR)));
|
|
|
|
|
|
|
|
|
|
EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
|
|
|
|
EXPECT_CALL(
|
|
|
|
|
*device_files_,
|
|
|
|
|
StoreUsageTableInfo(
|
|
|
|
|
kUsageTableHeader,
|
|
|
|
|
kAnotherUsageTableHeader,
|
|
|
|
|
UnorderedElementsAre(
|
|
|
|
|
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1,
|
|
|
|
|
kUsageEntryInfoStorageTypeUnknown,
|
|
|
|
|
@@ -905,17 +1036,19 @@ TEST_F(UsageTableHeaderTest,
|
|
|
|
|
|
|
|
|
|
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
|
|
|
|
.WillOnce(Return(INSUFFICIENT_CRYPTO_RESOURCES_3))
|
|
|
|
|
.WillOnce(DoAll(SetArgPointee<0>(expected_usage_entry_number),
|
|
|
|
|
Return(NO_ERROR)));
|
|
|
|
|
EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<0>(expected_usage_entry_number),
|
|
|
|
|
Return(NO_ERROR)));
|
|
|
|
|
DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
|
|
|
|
|
|
|
|
|
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kUsageTableHeader, _))
|
|
|
|
|
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, _))
|
|
|
|
|
.WillOnce(DoAll(SaveArg<1>(&final_usage_entries), Return(true)));
|
|
|
|
|
|
|
|
|
|
// Now invoke the method under test
|
|
|
|
|
uint32_t usage_entry_number;
|
|
|
|
|
EXPECT_EQ(NO_ERROR,
|
|
|
|
|
mock_usage_table_header->AddEntry(
|
|
|
|
|
mock_usage_table_header->SuperAddEntry(
|
|
|
|
|
crypto_session_,
|
|
|
|
|
kUsageEntryInfoOfflineLicense6.storage_type == kStorageLicense,
|
|
|
|
|
kUsageEntryInfoOfflineLicense6.key_set_id,
|
|
|
|
|
@@ -959,7 +1092,7 @@ TEST_F(UsageTableHeaderTest, AddEntry_CreateUsageEntryFailsEveryTime) {
|
|
|
|
|
// Now invoke the method under test
|
|
|
|
|
uint32_t usage_entry_number;
|
|
|
|
|
EXPECT_EQ(INSUFFICIENT_CRYPTO_RESOURCES_3,
|
|
|
|
|
mock_usage_table_header->AddEntry(
|
|
|
|
|
mock_usage_table_header->SuperAddEntry(
|
|
|
|
|
crypto_session_, true /* persistent */,
|
|
|
|
|
kUsageEntryInfoOfflineLicense6.key_set_id,
|
|
|
|
|
kUsageEntryInfoOfflineLicense6.usage_info_file_name,
|
|
|
|
|
@@ -3390,8 +3523,10 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateLicenseEntry) {
|
|
|
|
|
MockClock mock_clock;
|
|
|
|
|
usage_table_header_->SetClock(&mock_clock);
|
|
|
|
|
EXPECT_CALL(mock_clock, GetCurrentTime()).WillOnce(Return(kLruBaseTime));
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
StoreUsageTableInfo(kUpgradedUsageTableHeader, _));
|
|
|
|
|
EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
|
|
|
|
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, _));
|
|
|
|
|
|
|
|
|
|
// The Call.
|
|
|
|
|
uint32_t usage_entry_number = 0;
|
|
|
|
|
@@ -3436,8 +3571,10 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateUsageInfoEntry) {
|
|
|
|
|
MockClock mock_clock;
|
|
|
|
|
usage_table_header_->SetClock(&mock_clock);
|
|
|
|
|
EXPECT_CALL(mock_clock, GetCurrentTime()).WillOnce(Return(kLruBaseTime));
|
|
|
|
|
EXPECT_CALL(*device_files_,
|
|
|
|
|
StoreUsageTableInfo(kUpgradedUsageTableHeader, _));
|
|
|
|
|
EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull()))
|
|
|
|
|
.WillOnce(
|
|
|
|
|
DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
|
|
|
|
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, _));
|
|
|
|
|
|
|
|
|
|
// The Call.
|
|
|
|
|
uint32_t usage_entry_number = 0;
|
|
|
|
|
@@ -3970,15 +4107,7 @@ TEST_F(UsageTableHeaderTest, PotentialTableCapacity_Unavailable) {
|
|
|
|
|
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
|
|
|
|
EXPECT_EQ(usage_table_header_->potential_table_capacity(),
|
|
|
|
|
kMinimumUsageTableEntriesSupported);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(UsageTableHeaderTest, PotentialTableCapacity_Zero) {
|
|
|
|
|
// This will issue a warning about the reported capacity is unexpected,
|
|
|
|
|
// and will default to the version's required minimum.
|
|
|
|
|
crypto_session_->SetMaximumUsageTableEntries(0u);
|
|
|
|
|
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
|
|
|
|
EXPECT_EQ(usage_table_header_->potential_table_capacity(),
|
|
|
|
|
kMinimumUsageTableEntriesSupported);
|
|
|
|
|
EXPECT_FALSE(usage_table_header_->HasUnlimitedTableCapacity());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(UsageTableHeaderTest, PotentialTableCapacity_TooSmall) {
|
|
|
|
|
@@ -3989,6 +4118,18 @@ TEST_F(UsageTableHeaderTest, PotentialTableCapacity_TooSmall) {
|
|
|
|
|
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
|
|
|
|
EXPECT_EQ(usage_table_header_->potential_table_capacity(),
|
|
|
|
|
kMinimumUsageTableEntriesSupported);
|
|
|
|
|
EXPECT_FALSE(usage_table_header_->HasUnlimitedTableCapacity());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(UsageTableHeaderTest, PotentialTableCapacity_Unlimited) {
|
|
|
|
|
MockUsageTableHeader* mock_usage_table_header = SetUpMock();
|
|
|
|
|
// Zero indicates that the table size is unlimited.
|
|
|
|
|
crypto_session_->SetMaximumUsageTableEntries(0u);
|
|
|
|
|
|
|
|
|
|
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
|
|
|
|
constexpr size_t kZero = 0u;
|
|
|
|
|
EXPECT_EQ(mock_usage_table_header->potential_table_capacity(), kZero);
|
|
|
|
|
EXPECT_TRUE(mock_usage_table_header->HasUnlimitedTableCapacity());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(UsageTableHeaderTest, PotentialTableCapacity_Available) {
|
|
|
|
|
@@ -3996,6 +4137,7 @@ TEST_F(UsageTableHeaderTest, PotentialTableCapacity_Available) {
|
|
|
|
|
crypto_session_->SetMaximumUsageTableEntries(kTableCapacity);
|
|
|
|
|
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
|
|
|
|
EXPECT_EQ(usage_table_header_->potential_table_capacity(), kTableCapacity);
|
|
|
|
|
EXPECT_FALSE(usage_table_header_->HasUnlimitedTableCapacity());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace wvcdm
|
|
|
|
|
|