Unittests will retry provisioning if failed.
[ Merge of http://go/wvgerrit/84490 ] The unit tests will now make at most 10 attempts to provision themselves before declaring failure. This change is made to help with flaky provisioning requests that have been experienced on the Jenkins build server. Bug: 139298083 Test: Linux unit test, Jenkins build and Android unit tests Change-Id: I6415a5ef9fdf10ceb893867d5fc73131338e9f76
This commit is contained in:
@@ -11,7 +11,9 @@
|
||||
#include <openssl/cmac.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "cdm_engine.h"
|
||||
@@ -253,7 +255,7 @@ void WvCdmTestBase::InstallTestRootOfTrust() {
|
||||
}
|
||||
}
|
||||
|
||||
void WvCdmTestBase::Provision() {
|
||||
void WvCdmTestBase::Provision(size_t max_attempts) {
|
||||
CdmProvisioningRequest prov_request;
|
||||
CdmProvisioningRequest binary_prov_request;
|
||||
std::string provisioning_server_url;
|
||||
@@ -264,6 +266,8 @@ void WvCdmTestBase::Provision() {
|
||||
CdmSessionId session_id;
|
||||
FileSystem file_system;
|
||||
|
||||
ASSERT_GE(max_attempts, 1lu) << "|max_attempts| must be at least 1";
|
||||
|
||||
// TODO(fredgc): provision for different SPOIDs.
|
||||
CdmEngine cdm_engine(&file_system,
|
||||
std::shared_ptr<EngineMetrics>(new EngineMetrics));
|
||||
@@ -284,41 +288,85 @@ void WvCdmTestBase::Provision() {
|
||||
// Ignore URL provided by CdmEngine. Use ours, as configured
|
||||
// for test vs. production server.
|
||||
provisioning_server_url.assign(config_.provisioning_server());
|
||||
UrlRequest url_request(provisioning_server_url);
|
||||
EXPECT_TRUE(url_request.is_connected());
|
||||
url_request.PostCertRequestInQueryString(prov_request);
|
||||
|
||||
// Attempt to provision using the same requests a maximum of |max_attempts|
|
||||
// times.
|
||||
// TODO(b/139361531): Remove loop once provisioning service is stable.
|
||||
std::string http_message;
|
||||
bool ok = url_request.GetResponse(&http_message);
|
||||
EXPECT_TRUE(ok) << http_message;
|
||||
size_t attempt_num = 0;
|
||||
bool provision_success = false;
|
||||
do {
|
||||
if (attempt_num > 0) {
|
||||
// Sleep between attempts.
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
++attempt_num;
|
||||
|
||||
LOGV("WvCdmTestBase::Provision: http_message: \n%s\n", http_message.c_str());
|
||||
// Make request.
|
||||
UrlRequest url_request(provisioning_server_url);
|
||||
if (!url_request.is_connected()) {
|
||||
LOGE("Failed to connect to provisioning server: url = %s",
|
||||
provisioning_server_url.c_str());
|
||||
continue;
|
||||
}
|
||||
url_request.PostCertRequestInQueryString(prov_request);
|
||||
|
||||
if (binary_provisioning_) {
|
||||
// extract provisioning response from received message
|
||||
// Extracts signed response from JSON string, result is serialized protobuf.
|
||||
const std::string kMessageStart = "\"signedResponse\": \"";
|
||||
const std::string kMessageEnd = "\"";
|
||||
std::string protobuf_response;
|
||||
EXPECT_TRUE(ExtractSignedMessage(http_message, kMessageStart, kMessageEnd,
|
||||
&protobuf_response))
|
||||
<< "Failed to extract signed serialized response from JSON response";
|
||||
// Receive and parse response.
|
||||
if (!url_request.GetResponse(&http_message)) {
|
||||
LOGE("Failed to get provisioning response");
|
||||
continue;
|
||||
}
|
||||
|
||||
LOGV("WvCdmEnginePreProvTest::Provision: extracted response message: \n"
|
||||
"%s\n", protobuf_response.c_str());
|
||||
LOGV("http_message: \n%s\n", http_message.c_str());
|
||||
|
||||
// base64 decode response to yield binary protobuf
|
||||
std::vector<uint8_t> response_vec(Base64SafeDecode(
|
||||
std::string(protobuf_response.begin(), protobuf_response.end())));
|
||||
std::string binary_protobuf_response(response_vec.begin(),
|
||||
response_vec.end());
|
||||
ASSERT_EQ(NO_ERROR, cdm_engine.HandleProvisioningResponse(
|
||||
binary_protobuf_response, &cert, &wrapped_key))
|
||||
<< "message = " << http_message;
|
||||
} else {
|
||||
ASSERT_EQ(NO_ERROR, cdm_engine.HandleProvisioningResponse(
|
||||
http_message, &cert, &wrapped_key))
|
||||
<< "message = " << http_message;
|
||||
if (binary_provisioning_) {
|
||||
// extract provisioning response from received message
|
||||
// Extracts signed response from JSON string, result is serialized
|
||||
// protobuf.
|
||||
static const std::string kMessageStart = "\"signedResponse\": \"";
|
||||
static const std::string kMessageEnd = "\"";
|
||||
std::string protobuf_response;
|
||||
if (!ExtractSignedMessage(http_message, kMessageStart, kMessageEnd,
|
||||
&protobuf_response)) {
|
||||
LOGE("Failed to extract signed serialized response from JSON response");
|
||||
continue;
|
||||
}
|
||||
|
||||
LOGV("Extracted response message: \n%s\n", protobuf_response.c_str());
|
||||
|
||||
// base64 decode response to yield binary protobuf
|
||||
std::vector<uint8_t> response_vec(Base64SafeDecode(protobuf_response));
|
||||
if (response_vec.empty() && !protobuf_response.empty()) {
|
||||
LOGE("Failed to decode base64 of response: response = %s",
|
||||
protobuf_response.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string binary_protobuf_response(response_vec.begin(),
|
||||
response_vec.end());
|
||||
|
||||
if (cdm_engine.HandleProvisioningResponse(binary_protobuf_response, &cert,
|
||||
&wrapped_key) != NO_ERROR) {
|
||||
LOGE("Failed to handle provisioning response");
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (cdm_engine.HandleProvisioningResponse(http_message, &cert,
|
||||
&wrapped_key) != NO_ERROR) {
|
||||
LOGE("Failed to handle binary provisioning response");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
provision_success = true;
|
||||
} while (attempt_num <= max_attempts && !provision_success);
|
||||
|
||||
if (attempt_num > 1) {
|
||||
LOGW("Provisioning request failed at least once: attempts = %zu",
|
||||
attempt_num);
|
||||
}
|
||||
|
||||
ASSERT_TRUE(provision_success)
|
||||
<< "Failed to provision: message = " << http_message;
|
||||
}
|
||||
|
||||
// TODO(fredgc): Replace this with a pre-defined DRM certificate. We could do
|
||||
|
||||
@@ -19,6 +19,9 @@ namespace wvcdm {
|
||||
// to configure OEMCrypto to use a test keybox.
|
||||
class WvCdmTestBase : public ::testing::Test {
|
||||
public:
|
||||
// Default number of provisioning try attempts.
|
||||
constexpr static size_t kDefaultMaxProvisioningAttempts = 10;
|
||||
|
||||
WvCdmTestBase() : config_(default_config_), binary_provisioning_(false) {}
|
||||
~WvCdmTestBase() override {}
|
||||
void SetUp() override;
|
||||
@@ -32,7 +35,7 @@ class WvCdmTestBase : public ::testing::Test {
|
||||
static void InstallTestRootOfTrust();
|
||||
|
||||
// Send provisioning request to the server and handle response.
|
||||
virtual void Provision();
|
||||
virtual void Provision(size_t max_attempts = kDefaultMaxProvisioningAttempts);
|
||||
// Calls Provision() if not already provisioned.
|
||||
virtual void EnsureProvisioned();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user