Files
ce_cdm/cdm/test/test_host.cpp
2020-10-09 16:08:56 -07:00

143 lines
3.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.
#include "test_host.h"
#include <gtest/gtest.h>
#include <chrono>
#include "device_cert.h"
#include "log.h"
using namespace widevine;
namespace {
constexpr char kCertificateFilename[] = "cert.bin";
} // namespace
TestHost::TestHost() { Reset(); }
TestHost::~TestHost() { wvcdm::TestSleep::set_callback(nullptr); }
void TestHost::Reset() {
auto now = std::chrono::steady_clock().now();
now_ = now.time_since_epoch() / std::chrono::milliseconds(1);
wvcdm::TestSleep::set_callback(this);
save_device_cert_ = false;
// Surprisingly, std::priority_queue has no clear().
while (!timers_.empty()) {
timers_.pop();
}
files_.clear();
files_[kCertificateFilename] =
(device_cert_.size() > 0)
? device_cert_
: std::string((const char*)kDeviceCert, kDeviceCertSize);
}
void TestHost::ElapseTime(int64_t milliseconds) {
// Note that, during the time rollback tests, milliseconds will be negative,
// so we cannot assume goal_time > now_.
int64_t goal_time = now_ + milliseconds;
// Walk forward from now_ to goal_time, stepping at each timer along the way
// to fire its callback.
while (!timers_.empty() && now_ < goal_time) {
Timer t = timers_.top();
ASSERT_GE(t.expiry_time(), now_);
if (t.expiry_time() <= goal_time) {
timers_.pop();
now_ = t.expiry_time();
t.client()->onTimerExpired(t.context());
} else {
// The next timer is further in the future than goal_time, so we are done
// processing the timers.
break;
}
}
// No matter what happened with the timers, update now_ to the goal_time.
now_ = goal_time;
}
int TestHost::NumTimers() const { return timers_.size(); }
bool TestHost::read(const std::string& name, std::string* data) {
StorageMap::iterator it = files_.find(name);
bool ok = it != files_.end();
LOGV("read file: %s: %s", name.c_str(), ok ? "ok" : "fail");
if (!ok) return false;
*data = it->second;
return true;
}
bool TestHost::write(const std::string& name, const std::string& data) {
LOGV("write file: %s", name.c_str());
files_[name] = data;
if (save_device_cert_ && name.compare(kCertificateFilename) == 0) {
device_cert_ = data;
save_device_cert_ = false;
}
return true;
}
bool TestHost::exists(const std::string& name) {
StorageMap::iterator it = files_.find(name);
bool ok = it != files_.end();
LOGV("exists? %s: %s", name.c_str(), ok ? "true" : "false");
return ok;
}
bool TestHost::remove(const std::string& name) {
LOGV("remove: %s", name.c_str());
if (name.empty()) {
// If no name, delete all files (see DeviceFiles::DeleteAllFiles())
files_.clear();
return true;
}
return files_.erase(name) > 0;
}
int32_t TestHost::size(const std::string& name) {
StorageMap::iterator it = files_.find(name);
if (it == files_.end()) return -1;
return it->second.size();
}
bool TestHost::list(std::vector<std::string>* names) {
names->clear();
for (StorageMap::iterator it = files_.begin(); it != files_.end(); it++) {
names->push_back(it->first);
}
return true;
}
int64_t TestHost::now() { return now_; }
void TestHost::setTimeout(int64_t delay_ms, IClient* client, void* context) {
int64_t expiry_time = now_ + delay_ms;
timers_.push(Timer(expiry_time, client, context));
}
void TestHost::cancel(IClient* client) {
// Filter out the timers for this client and put the rest into |others|.
std::priority_queue<Timer> others;
while (timers_.size()) {
Timer t = timers_.top();
timers_.pop();
if (t.client() != client) {
others.push(t);
}
}
// Now swap the queues.
std::swap(timers_, others);
}