Merge "Create custom gtest matcher for similar URLs."

This commit is contained in:
Alex Dale
2022-09-21 00:52:32 +00:00
committed by Android (Google) Code Review
2 changed files with 147 additions and 16 deletions

View File

@@ -1548,6 +1548,118 @@ FourSampleDecryptionInfo kCenc30SwitchCipherData[8] = {
}},
};
// Extracts the scheme, hostname and path from the provided URL.
// Example:
// Input: "https://www.widevine.com/service?id=1234&device=pixel&flag"
// Output: "https://www.widevine.com/service"
std::string GetUrlHostAndPath(const std::string& full_url) {
const auto start_of_params = full_url.find('?');
if (start_of_params == std::string::npos) return full_url;
return full_url.substr(0, start_of_params);
}
// Extracts and splits the query parameters from the provided URL.
// Returns an empty list if no parameters are found.
//
// Example:
// Input: "https://www.widevine.com/service?id=1234&device=pixel&flag"
// Output: {"id=1234", "device=pixel", "flag"}
std::vector<std::string> GetUrlQueryParamPairs(const std::string& full_url) {
const auto start_of_params = full_url.find('?');
if (start_of_params == std::string::npos) return {}; // No params.
// Remove host and path.
const std::string all_params = full_url.substr(start_of_params + 1);
if (all_params.empty()) return {};
// Check if there are more than 1 parameters.
auto param_separator = all_params.find('&');
if (param_separator == std::string::npos) {
return {all_params}; // Only 1 parameter.
}
// Split parameters by '&'.
std::vector<std::string> params;
params.push_back(all_params.substr(0, param_separator));
while (param_separator != std::string::npos) {
auto next_param_separator = all_params.find('&', param_separator + 1);
if (next_param_separator == std::string::npos) {
params.push_back(all_params.substr(param_separator + 1));
} else {
params.push_back(all_params.substr(
param_separator + 1, next_param_separator - param_separator - 1));
}
param_separator = next_param_separator;
}
return params;
}
// Extracts and maps the query parameters from the provided URL.
// Creates a map between the parameter keys and values. Parameters
// that are only keys have an empty string value.
//
// Example:
// Input: "https://www.widevine.com/service?id=1234&device=pixel&flag"
// Output: {"id": "1234", "device": "pixel", "flag": ""}
std::map<std::string, std::string> GetUrlQueryParams(
const std::string& full_url) {
const std::vector<std::string> param_pairs = GetUrlQueryParamPairs(full_url);
std::map<std::string, std::string> params;
if (param_pairs.empty()) return params;
for (const auto& pair : param_pairs) {
const auto value_separator = pair.find('=');
if (value_separator == std::string::npos) {
// Just the key.
params.emplace(pair, "");
} else {
params.emplace(pair.substr(0, value_separator),
pair.substr(value_separator + 1));
}
}
return params;
}
// Checks that the |actual_url| is a super set of information compared
// to the |expected_url|. The scheme, hostname and path must be the
// same. The |actual_url| must contain at all the query parameters of
// the |expected_url|. Order of the query parameters do not matter.
//
// Example A:
// Expected: "https://www.widevine.com/service?key=1234"
// Actual: "https://www.widevine.com/service?retry=true&key=1234"
// Result: true
//
// Example B:
// Expected: "https://www.widevine.com/service?key=1234&retry=true"
// Actual: "https://www.widevine.com/service?key=1234"
// Result: false
//
// Example C:
// Expected: "https://www.widevine.com/service?key=1234"
// Actual: "https://www.widevine.org/service?key=1234"
// Result: false
bool IsUrlSimilar(const std::string& expected_url,
const std::string& actual_url) {
// First check the host and path.
const std::string expected_host_and_path = GetUrlHostAndPath(expected_url);
const std::string actual_host_and_path = GetUrlHostAndPath(actual_url);
if (expected_host_and_path != actual_host_and_path) {
return false; // Bad host and/or path.
}
// Compare query parameters.
const std::map<std::string, std::string> expected_params =
GetUrlQueryParams(expected_url);
const std::map<std::string, std::string> actual_params =
GetUrlQueryParams(actual_url);
if (actual_params.size() < expected_params.size()) {
return false; // Missing params.
}
for (const auto& expected_param : expected_params) {
const auto actual_param = actual_params.find(expected_param.first);
if (actual_param == actual_params.end())
return false; // Missing particular param.
if (actual_param->second != expected_param.second)
return false; // Incorrect param value.
}
return true;
}
} // namespace
namespace wvcdm {
@@ -1556,6 +1668,10 @@ using video_widevine::ClientIdentification;
using video_widevine::ClientIdentification_NameValue;
using video_widevine::SignedMessage;
MATCHER_P(IsSimilarUrlTo, expected_url, "") {
return IsUrlSimilar(expected_url, arg);
}
class TestWvCdmClientPropertySet : public CdmClientPropertySet {
public:
TestWvCdmClientPropertySet()
@@ -2058,7 +2174,8 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
&provisioning_server);
EXPECT_EQ(wvcdm::NO_ERROR, status);
if (NO_ERROR != status) return;
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
CdmProvisioningResponse response =
GetCertRequestResponse(config_.provisioning_server());
@@ -2177,7 +2294,8 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningTest) {
cert_type, cert_authority, kDefaultCdmIdentifier,
kEmptyServiceCertificate, kLevelDefault, &key_msg_,
&provisioning_server));
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
std::string response = GetCertRequestResponse(config_.provisioning_server());
EXPECT_NE(0, static_cast<int>(response.size()));
@@ -2202,7 +2320,8 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningTestWithServiceCertificate) {
cert_type, cert_authority, kDefaultCdmIdentifier,
config_.provisioning_service_certificate(), kLevelDefault,
&key_msg_, &provisioning_server));
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
std::string response = GetCertRequestResponse(config_.provisioning_server());
EXPECT_NE(0, static_cast<int>(response.size()));
@@ -2227,7 +2346,8 @@ TEST_F(WvCdmRequestLicenseTest, L3ProvisioningTest) {
decryptor_->GetProvisioningRequest(
cert_type, cert_authority, kDefaultCdmIdentifier,
kEmptyServiceCertificate, kLevel3, &key_msg_, &provisioning_server));
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
std::string response = GetCertRequestResponse(config_.provisioning_server());
EXPECT_NE(0, static_cast<int>(response.size()));
@@ -2330,14 +2450,16 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningInterposedRetryTest) {
cert_type, cert_authority, kDefaultCdmIdentifier,
kEmptyServiceCertificate, kLevelDefault, &key_msg1,
&provisioning_server));
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_->GetProvisioningRequest(
cert_type, cert_authority, kDefaultCdmIdentifier,
kEmptyServiceCertificate, kLevelDefault, &key_msg2,
&provisioning_server));
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
// Second message should succeed.
key_msg_ = key_msg2;
@@ -2375,14 +2497,16 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningInterspersedRetryTest) {
cert_type, cert_authority, kDefaultCdmIdentifier,
kEmptyServiceCertificate, kLevelDefault, &key_msg1,
&provisioning_server));
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_->GetProvisioningRequest(
cert_type, cert_authority, kDefaultCdmIdentifier,
kEmptyServiceCertificate, kLevelDefault, &key_msg2,
&provisioning_server));
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
// First request expected to fail, because only one message may be active.
key_msg_ = key_msg1;
@@ -2421,7 +2545,8 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_X509ProvisioningTest) {
cert_type, cert_authority, kDefaultCdmIdentifier,
kEmptyServiceCertificate, kLevelDefault, &key_msg_,
&provisioning_server));
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
std::string response = GetCertRequestResponse(config_.provisioning_server());
EXPECT_NE(0, static_cast<int>(response.size()));
@@ -2512,7 +2637,8 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningRevocationTest) {
EXPECT_EQ(wvcdm::NO_ERROR, result);
if (NO_ERROR != result) return;
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
if (!wvcdm::Properties::provisioning_messages_are_binary()) {
std::vector<uint8_t> request =
@@ -2550,7 +2676,8 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningRevocationTest) {
EXPECT_EQ(wvcdm::NO_ERROR, result);
if (NO_ERROR != result) return;
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
ProvisioningResponse provisioning_response;
provisioning_response.set_status(status);
@@ -2663,7 +2790,8 @@ TEST_F(WvCdmRequestLicenseTest, PropertySetTest) {
cert_type, cert_authority, kDefaultCdmIdentifier,
kEmptyServiceCertificate, kLevel3, &key_msg_,
&provisioning_server));
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
std::string response =
GetCertRequestResponse(config_.provisioning_server());
EXPECT_NE(0, static_cast<int>(response.size()));
@@ -2740,7 +2868,8 @@ TEST_F(WvCdmRequestLicenseTest, ForceL3Test) {
cert_type, cert_authority, kDefaultCdmIdentifier,
kEmptyServiceCertificate, kLevel3, &key_msg_,
&provisioning_server));
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
std::string response = GetCertRequestResponse(config_.provisioning_server());
EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(NO_ERROR,
@@ -3150,7 +3279,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) {
cert_type, cert_authority, kDefaultCdmIdentifier,
kEmptyServiceCertificate, kLevel3, &key_msg_,
&provisioning_server));
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
std::string response =
GetCertRequestResponse(config_.provisioning_server());
EXPECT_NE(0, static_cast<int>(response.size()));
@@ -3220,7 +3350,8 @@ TEST_F(WvCdmRequestLicenseTest,
cert_type, cert_authority, kDefaultCdmIdentifier,
kEmptyServiceCertificate, kLevel3, &key_msg_,
&provisioning_server_url));
EXPECT_EQ(provisioning_server_url, kDefaultProvisioningServerUrl);
EXPECT_THAT(provisioning_server_url,
IsSimilarUrlTo(kDefaultProvisioningServerUrl));
std::string response =
GetCertRequestResponse(config_.provisioning_server());
EXPECT_NE(0, static_cast<int>(response.size()));

View File

@@ -108,7 +108,7 @@ adb_shell_run event_metric_unittest
adb_shell_run file_store_unittest
adb_shell_run file_utils_unittest
adb_shell_run generic_crypto_unittest
adb_shell_run hidl_metrics_adapter_unittest
adb_shell_run hal_metrics_adapter_unittest
adb_shell_run http_socket_test
adb_shell_run initialization_data_unittest
adb_shell_run libwvdrmdrmplugin_hal_test