OEMCrypto and OPK 18.8
This commit is contained in:
@@ -7,7 +7,8 @@
|
||||
#ifndef WVCDM_UTIL_FILE_STORE_H_
|
||||
#define WVCDM_UTIL_FILE_STORE_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -18,16 +19,35 @@
|
||||
|
||||
namespace wvutil {
|
||||
|
||||
// Fixed filename for ATSC DRM certificate pre-installed
|
||||
// on ATSC devices for ATSC licenses.
|
||||
static const std::string kAtscCertificateFileName = "atsccert.bin";
|
||||
// General filename for either global or unmapped app-origin
|
||||
// DRM certificates.
|
||||
static const std::string kCertificateFileName = "cert1.bin";
|
||||
// File extension for DRM and OEM certificate files.
|
||||
static const std::string kCertificateFileNameExt = ".bin";
|
||||
static const std::string kCertificateFileNamePrefix = "cert1_";
|
||||
// Filename prefix for mapped (scoped) DRM certificate filenames
|
||||
// specific to a particular app-origin.
|
||||
static const std::string kScopedCertificateFilenamePrefix = "cert1_";
|
||||
// TODO(b/376533901): Replace this constant with
|
||||
// kScopedCertificateFilenamePrefix in source code..
|
||||
static const std::string kCertificateFileNamePrefix =
|
||||
kScopedCertificateFilenamePrefix;
|
||||
// Legacy general filename for either global or unmapped app-origin
|
||||
// DRM certificates.
|
||||
static const std::string kLegacyCertificateFileName = "cert.bin";
|
||||
static const std::string kLegacyCertificateFileNamePrefix = "cert";
|
||||
// Legacy filename prefix for mapped (scoped) DRM certificate filenames
|
||||
// specific to a particular app-origin.
|
||||
static const std::string kLegacyScopedCertificateFilenamePrefix = "cert";
|
||||
// TODO(b/376533901): Replace this constant with
|
||||
// kLegacyScopedCertificateFilenamePrefix in source code..
|
||||
static const std::string kLegacyCertificateFileNamePrefix =
|
||||
kLegacyScopedCertificateFilenamePrefix;
|
||||
// Filename for global OEM certificates.
|
||||
static const std::string kOemCertificateFileName = "oemcert.bin";
|
||||
static const std::string kOemCertificateFileNamePrefix = "oemcert_";
|
||||
|
||||
// File class. The implementation is platform dependent.
|
||||
// File interface. The implementation is platform dependent.
|
||||
class File {
|
||||
public:
|
||||
File() {}
|
||||
@@ -35,35 +55,70 @@ class File {
|
||||
virtual ssize_t Read(char* buffer, size_t bytes) = 0;
|
||||
virtual ssize_t Write(const char* buffer, size_t bytes) = 0;
|
||||
|
||||
friend class FileSystem;
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(File);
|
||||
};
|
||||
|
||||
// File system base class. The implementation is platform dependent.
|
||||
class FileSystem {
|
||||
public:
|
||||
FileSystem();
|
||||
FileSystem(const std::string& origin, void* extra_data);
|
||||
virtual ~FileSystem();
|
||||
|
||||
// Concreate implementation of FileSystem.
|
||||
// Depending on the platform, this may be vendor or Widevine implemented.
|
||||
class Impl;
|
||||
|
||||
// defines as bit flag
|
||||
enum OpenFlags {
|
||||
kNoFlags = 0,
|
||||
kCreate = 1,
|
||||
kReadOnly = 2, // defaults to read and write access
|
||||
kTruncate = 4
|
||||
};
|
||||
// Flags for calls to Open.
|
||||
static constexpr int kNoFlags = 0;
|
||||
// Create file if does not already exist, open file if it does exist.
|
||||
static constexpr int kCreate = (1 << 0);
|
||||
// Open file as read-only; typically should not be used with kCreate.
|
||||
static constexpr int kReadOnly = (1 << 1);
|
||||
// Open file and truncated. May be used with kCreate; should not
|
||||
// be used with kReadOnly.
|
||||
static constexpr int kTruncate = (1 << 2);
|
||||
|
||||
virtual std::unique_ptr<File> Open(const std::string& file_path, int flags);
|
||||
|
||||
virtual bool Exists(const std::string& file_path);
|
||||
virtual bool Exists(const std::string& file_path, int* errno_value);
|
||||
virtual bool Remove(const std::string& file_path);
|
||||
// Checks if the |path| exists. The |path| may be a file or directory.
|
||||
// Return true if an entry in the file system exists; false otherwise.
|
||||
virtual bool Exists(const std::string& path);
|
||||
// Same as above, except the optional parameter of |errno_value| should
|
||||
// be set to 0 or the value of C errno when attempting to check
|
||||
// the existence of a file.
|
||||
virtual bool Exists(const std::string& path, int* errno_value);
|
||||
|
||||
// Removes the specified |path|.
|
||||
//
|
||||
// If |path| is a regular file, the file should be removed.
|
||||
// If |path| is a directory, both the directory and the directory
|
||||
// contents should be removed.
|
||||
//
|
||||
// Implementation must support a |path| containing a single wildcard
|
||||
// character in the filename component of the path.
|
||||
//
|
||||
// Return value:
|
||||
// - true : File/directory was removed, or file/directory did not exist
|
||||
// - false : File/directory could not be removed, or other error.
|
||||
virtual bool Remove(const std::string& path);
|
||||
|
||||
// Obtain the size of a file in bytes. |file_path| must be a file,
|
||||
// and not a directory.
|
||||
//
|
||||
// Return value:
|
||||
// - non-negative : size of file in bytes if file exists
|
||||
// - negative : file does not exist, or error occurred.
|
||||
virtual ssize_t FileSize(const std::string& file_path);
|
||||
|
||||
// Return the filenames stored at dir_path.
|
||||
// dir_path will be stripped from the returned names.
|
||||
// Return the entries stored at |dir_path| (includes both files
|
||||
// and directories).
|
||||
//
|
||||
// Return value:
|
||||
// - true : Directory exists, and directory entry names are stored
|
||||
// in |names|; |names| may be empty if directory was empty.
|
||||
// - false : Directory does not exist, |dir_path| is not a directory,
|
||||
// or error was encountered.
|
||||
virtual bool List(const std::string& dir_path,
|
||||
std::vector<std::string>* names);
|
||||
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#include "file_store.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
@@ -11,18 +16,20 @@
|
||||
#include "test_vectors.h"
|
||||
|
||||
namespace wvutil {
|
||||
|
||||
namespace {
|
||||
const std::string kTestDirName = "test_dir";
|
||||
const std::string kTestFileName = "test.txt";
|
||||
const std::string kTestFileName2 = "test2.txt";
|
||||
const std::string kTestFileName3 = "test3.other";
|
||||
const std::string kTestFileNameExt = ".txt";
|
||||
const std::string kTestFileNameExt3 = ".other";
|
||||
const std::string kTestIdentifier1 = "some_identifier";
|
||||
const std::string kTestIdentifier2 = "some_other_identifier";
|
||||
const std::string kWildcard = "*";
|
||||
const std::string kUnderscore = "_";
|
||||
constexpr char kTestFilename[] = "sample.txt";
|
||||
|
||||
constexpr char kTestIdentifier1[] = "some_identifier";
|
||||
constexpr char kTestIdentifier2[] = "some_other_identifier";
|
||||
|
||||
constexpr int kNoError = 0;
|
||||
constexpr int kEntryDoesNotExist = ENOENT;
|
||||
|
||||
bool StartsWith(const std::string& haystack, const std::string& needle) {
|
||||
if (needle.empty()) return true;
|
||||
if (haystack.size() < needle.size()) return false;
|
||||
return haystack.find(needle) == 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class FileTest : public testing::Test {
|
||||
@@ -32,7 +39,19 @@ class FileTest : public testing::Test {
|
||||
void TearDown() override { RemoveTestDir(); }
|
||||
|
||||
void RemoveTestDir() {
|
||||
EXPECT_TRUE(file_system_.Remove(wvcdm::test_vectors::kTestDir));
|
||||
ASSERT_TRUE(file_system_.Remove(wvcdm::test_vectors::kTestDir))
|
||||
<< "Failed to update test directory: " << wvcdm::test_vectors::kTestDir;
|
||||
}
|
||||
|
||||
std::string PathJoin(const std::string& base_path,
|
||||
const std::string& add_path) {
|
||||
if (base_path.empty()) return add_path;
|
||||
std::string path = base_path;
|
||||
if (path.back() != '/') {
|
||||
path.push_back('/');
|
||||
}
|
||||
path.append(add_path);
|
||||
return path;
|
||||
}
|
||||
|
||||
FileSystem file_system_;
|
||||
@@ -40,336 +59,505 @@ class FileTest : public testing::Test {
|
||||
|
||||
TEST_F(FileTest, FileExists) {
|
||||
int errno_value = -1;
|
||||
EXPECT_TRUE(file_system_.Exists(wvcdm::test_vectors::kExistentFile));
|
||||
EXPECT_TRUE(file_system_.Exists(wvcdm::test_vectors::kExistentFile))
|
||||
<< "path = " << wvcdm::test_vectors::kExistentFile;
|
||||
EXPECT_TRUE(
|
||||
file_system_.Exists(wvcdm::test_vectors::kExistentFile, &errno_value));
|
||||
EXPECT_EQ(0, errno_value);
|
||||
EXPECT_TRUE(file_system_.Exists(wvcdm::test_vectors::kExistentDir));
|
||||
file_system_.Exists(wvcdm::test_vectors::kExistentFile, &errno_value))
|
||||
<< "path = " << wvcdm::test_vectors::kExistentFile;
|
||||
EXPECT_EQ(kNoError, errno_value);
|
||||
}
|
||||
|
||||
EXPECT_FALSE(file_system_.Exists(wvcdm::test_vectors::kNonExistentFile));
|
||||
TEST_F(FileTest, FileDoesNotExist) {
|
||||
int errno_value = -1;
|
||||
EXPECT_FALSE(file_system_.Exists(wvcdm::test_vectors::kNonExistentFile))
|
||||
<< "path = " << wvcdm::test_vectors::kNonExistentFile;
|
||||
EXPECT_FALSE(
|
||||
file_system_.Exists(wvcdm::test_vectors::kNonExistentFile, &errno_value));
|
||||
EXPECT_EQ(ENOENT, errno_value);
|
||||
EXPECT_FALSE(file_system_.Exists(wvcdm::test_vectors::kNonExistentDir));
|
||||
file_system_.Exists(wvcdm::test_vectors::kNonExistentFile, &errno_value))
|
||||
<< "path = " << wvcdm::test_vectors::kNonExistentFile;
|
||||
EXPECT_EQ(kEntryDoesNotExist, errno_value);
|
||||
}
|
||||
|
||||
TEST_F(FileTest, DirectoryExists) {
|
||||
int errno_value = -1;
|
||||
EXPECT_TRUE(file_system_.Exists(wvcdm::test_vectors::kExistentDir))
|
||||
<< "path = " << wvcdm::test_vectors::kExistentDir;
|
||||
EXPECT_TRUE(
|
||||
file_system_.Exists(wvcdm::test_vectors::kExistentDir, &errno_value))
|
||||
<< "path = " << wvcdm::test_vectors::kExistentDir;
|
||||
EXPECT_EQ(kNoError, errno_value);
|
||||
}
|
||||
|
||||
TEST_F(FileTest, DirectoryDoesNotExist) {
|
||||
int errno_value = -1;
|
||||
EXPECT_FALSE(file_system_.Exists(wvcdm::test_vectors::kNonExistentDir))
|
||||
<< "path = " << wvcdm::test_vectors::kNonExistentDir;
|
||||
EXPECT_FALSE(
|
||||
file_system_.Exists(wvcdm::test_vectors::kNonExistentDir, &errno_value))
|
||||
<< "path = " << wvcdm::test_vectors::kNonExistentDir;
|
||||
EXPECT_EQ(kEntryDoesNotExist, errno_value);
|
||||
}
|
||||
|
||||
TEST_F(FileTest, RemoveDir) {
|
||||
EXPECT_TRUE(file_system_.Remove(wvcdm::test_vectors::kTestDir));
|
||||
EXPECT_FALSE(file_system_.Exists(wvcdm::test_vectors::kTestDir));
|
||||
EXPECT_TRUE(file_system_.Remove(wvcdm::test_vectors::kTestDir))
|
||||
<< "path = " << wvcdm::test_vectors::kTestDir;
|
||||
EXPECT_FALSE(file_system_.Exists(wvcdm::test_vectors::kTestDir))
|
||||
<< "path = " << wvcdm::test_vectors::kTestDir;
|
||||
}
|
||||
|
||||
TEST_F(FileTest, OpenFile) {
|
||||
std::string path = wvcdm::test_vectors::kTestDir + kTestFileName;
|
||||
EXPECT_TRUE(file_system_.Remove(path));
|
||||
const std::string path =
|
||||
PathJoin(wvcdm::test_vectors::kTestDir, kTestFilename);
|
||||
EXPECT_TRUE(file_system_.Remove(path)) << "path = " << path;
|
||||
|
||||
std::unique_ptr<File> file = file_system_.Open(path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create file: " << path;
|
||||
|
||||
EXPECT_TRUE(file_system_.Exists(path));
|
||||
EXPECT_TRUE(file_system_.Exists(path)) << "path = " << path;
|
||||
}
|
||||
|
||||
TEST_F(FileTest, RemoveDirAndFile) {
|
||||
std::string path = wvcdm::test_vectors::kTestDir + kTestFileName;
|
||||
const std::string path =
|
||||
PathJoin(wvcdm::test_vectors::kTestDir, kTestFilename);
|
||||
|
||||
std::unique_ptr<File> file = file_system_.Open(path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create file: " << path;
|
||||
|
||||
EXPECT_TRUE(file_system_.Exists(path));
|
||||
EXPECT_TRUE(file_system_.Remove(path));
|
||||
EXPECT_FALSE(file_system_.Exists(path));
|
||||
EXPECT_TRUE(file_system_.Exists(path)) << "path = " << path;
|
||||
EXPECT_TRUE(file_system_.Remove(path)) << "path = " << path;
|
||||
EXPECT_FALSE(file_system_.Exists(path)) << "path = " << path;
|
||||
|
||||
file = file_system_.Open(path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create file: " << path;
|
||||
|
||||
EXPECT_TRUE(file_system_.Exists(path));
|
||||
RemoveTestDir();
|
||||
EXPECT_FALSE(file_system_.Exists(wvcdm::test_vectors::kTestDir));
|
||||
EXPECT_FALSE(file_system_.Exists(path));
|
||||
EXPECT_TRUE(file_system_.Exists(path)) << "path = " << path;
|
||||
ASSERT_NO_FATAL_FAILURE(RemoveTestDir());
|
||||
EXPECT_FALSE(file_system_.Exists(wvcdm::test_vectors::kTestDir))
|
||||
<< "path = " << path;
|
||||
EXPECT_FALSE(file_system_.Exists(path)) << "path = " << path;
|
||||
}
|
||||
|
||||
TEST_F(FileTest, RemoveWildcardFiles) {
|
||||
std::string path1 = wvcdm::test_vectors::kTestDir + kTestFileName;
|
||||
std::string path2 = wvcdm::test_vectors::kTestDir + kTestFileName2;
|
||||
std::string wildcard_path =
|
||||
wvcdm::test_vectors::kTestDir + kWildcard + kTestFileNameExt;
|
||||
const std::string path1 =
|
||||
PathJoin(wvcdm::test_vectors::kTestDir, "first.txt");
|
||||
const std::string path2 =
|
||||
PathJoin(wvcdm::test_vectors::kTestDir, "second.txt");
|
||||
const std::string wildcard_path =
|
||||
PathJoin(wvcdm::test_vectors::kTestDir, "*.txt");
|
||||
|
||||
std::unique_ptr<File> file = file_system_.Open(path1, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create file (1): " << path1;
|
||||
file = file_system_.Open(path2, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create file (2): " << path2;
|
||||
|
||||
EXPECT_TRUE(file_system_.Exists(path1));
|
||||
EXPECT_TRUE(file_system_.Exists(path2));
|
||||
EXPECT_TRUE(file_system_.Remove(wildcard_path));
|
||||
EXPECT_FALSE(file_system_.Exists(path1));
|
||||
EXPECT_FALSE(file_system_.Exists(path2));
|
||||
EXPECT_TRUE(file_system_.Exists(path1)) << "path = " << path1;
|
||||
EXPECT_TRUE(file_system_.Exists(path2)) << "path = " << path2;
|
||||
EXPECT_TRUE(file_system_.Remove(wildcard_path))
|
||||
<< "wildcard_path = " << wildcard_path;
|
||||
EXPECT_FALSE(file_system_.Exists(path1)) << "path = " << path1;
|
||||
EXPECT_FALSE(file_system_.Exists(path2)) << "path = " << path2;
|
||||
}
|
||||
|
||||
TEST_F(FileTest, FileSize) {
|
||||
std::string path = wvcdm::test_vectors::kTestDir + kTestFileName;
|
||||
const std::string path =
|
||||
PathJoin(wvcdm::test_vectors::kTestDir, kTestFilename);
|
||||
file_system_.Remove(path);
|
||||
|
||||
std::string write_data = CdmRandom::RandomData(600);
|
||||
size_t write_data_size = write_data.size();
|
||||
std::unique_ptr<File> file = file_system_.Open(path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
EXPECT_EQ(file->Write(write_data.data(), write_data_size), write_data_size);
|
||||
EXPECT_TRUE(file_system_.Exists(path));
|
||||
constexpr size_t kDataSize = 600;
|
||||
const std::string write_data = CdmRandom::RandomData(kDataSize);
|
||||
ASSERT_EQ(write_data.size(), kDataSize);
|
||||
|
||||
EXPECT_EQ(static_cast<ssize_t>(write_data_size), file_system_.FileSize(path));
|
||||
std::unique_ptr<File> file = file_system_.Open(path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file) << "Failed to create file: " << path;
|
||||
|
||||
EXPECT_EQ(file->Write(write_data.data(), write_data.size()),
|
||||
write_data.size());
|
||||
file.reset(); // Close file.
|
||||
|
||||
EXPECT_TRUE(file_system_.Exists(path)) << "path = " << path;
|
||||
|
||||
EXPECT_EQ(static_cast<ssize_t>(kDataSize), file_system_.FileSize(path))
|
||||
<< "path = " << path;
|
||||
}
|
||||
|
||||
TEST_F(FileTest, WriteReadBinaryFile) {
|
||||
std::string path = wvcdm::test_vectors::kTestDir + kTestFileName;
|
||||
const std::string path =
|
||||
PathJoin(wvcdm::test_vectors::kTestDir, kTestFilename);
|
||||
file_system_.Remove(path);
|
||||
|
||||
std::string write_data = CdmRandom::RandomData(600);
|
||||
size_t write_data_size = write_data.size();
|
||||
std::unique_ptr<File> file = file_system_.Open(path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
EXPECT_EQ(file->Write(write_data.data(), write_data_size), write_data_size);
|
||||
EXPECT_TRUE(file_system_.Exists(path));
|
||||
constexpr size_t kDataSize = 600;
|
||||
const std::string write_data = CdmRandom::RandomData(kDataSize);
|
||||
ASSERT_EQ(write_data.size(), kDataSize);
|
||||
|
||||
std::unique_ptr<File> file = file_system_.Open(path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file) << "Failed to create file: " << path;
|
||||
|
||||
constexpr ssize_t kExpectedFileSizeResult = static_cast<ssize_t>(kDataSize);
|
||||
EXPECT_EQ(file->Write(write_data.data(), write_data.size()),
|
||||
kExpectedFileSizeResult)
|
||||
<< "path = " << path;
|
||||
file.reset(); // Close file.
|
||||
|
||||
EXPECT_TRUE(file_system_.Exists(path)) << "path = " << path;
|
||||
|
||||
std::string read_data;
|
||||
read_data.resize(file_system_.FileSize(path));
|
||||
size_t read_data_size = read_data.size();
|
||||
file = file_system_.Open(path, FileSystem::kReadOnly);
|
||||
ASSERT_TRUE(file);
|
||||
EXPECT_EQ(file->Read(&read_data[0], read_data_size), read_data_size);
|
||||
ASSERT_TRUE(file) << "Failed to re-open file: " << path;
|
||||
|
||||
std::string read_data(kDataSize, '\0');
|
||||
;
|
||||
ASSERT_EQ(file->Read(&read_data[0], read_data.size()),
|
||||
kExpectedFileSizeResult)
|
||||
<< "path = " << path;
|
||||
EXPECT_EQ(write_data, read_data);
|
||||
}
|
||||
|
||||
TEST_F(FileTest, ListFiles) {
|
||||
std::vector<std::string> names;
|
||||
const std::string kTxtFilename1 = "data.txt";
|
||||
const std::string kTxtFilename2 = "other.txt";
|
||||
const std::string kBinFilename = "sample.bin";
|
||||
|
||||
std::string not_path("zzz");
|
||||
std::string path1 = wvcdm::test_vectors::kTestDir + kTestFileName;
|
||||
std::string path2 = wvcdm::test_vectors::kTestDir + kTestFileName2;
|
||||
std::string path3 = wvcdm::test_vectors::kTestDir + kTestFileName3;
|
||||
std::string path_dir = wvcdm::test_vectors::kTestDir;
|
||||
const std::string dir_path = wvcdm::test_vectors::kTestDir;
|
||||
const std::string path1 = PathJoin(dir_path, kTxtFilename1);
|
||||
const std::string path2 = PathJoin(dir_path, kTxtFilename2);
|
||||
const std::string path3 = PathJoin(dir_path, kBinFilename);
|
||||
|
||||
// Create files.
|
||||
std::unique_ptr<File> file = file_system_.Open(path1, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create file (1): " << path1;
|
||||
file = file_system_.Open(path2, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create file (2): " << path2;
|
||||
file = file_system_.Open(path3, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create file (3): " << path3;
|
||||
file.reset(); // Close file
|
||||
|
||||
EXPECT_TRUE(file_system_.Exists(path1));
|
||||
EXPECT_TRUE(file_system_.Exists(path2));
|
||||
EXPECT_TRUE(file_system_.Exists(path3));
|
||||
|
||||
// Ask for non-existent path.
|
||||
EXPECT_FALSE(file_system_.List(not_path, &names));
|
||||
std::vector<std::string> names;
|
||||
ASSERT_TRUE(file_system_.List(dir_path, &names)) << "dir_path = " << dir_path;
|
||||
|
||||
// Valid path, but no way to return names.
|
||||
EXPECT_FALSE(file_system_.List(path_dir, nullptr));
|
||||
size_t expected_file_count = 3;
|
||||
EXPECT_EQ(names.size(), expected_file_count);
|
||||
|
||||
// Valid path, valid return.
|
||||
EXPECT_TRUE(file_system_.List(path_dir, &names));
|
||||
|
||||
// Should find three files. Order not important.
|
||||
EXPECT_EQ(3u, names.size());
|
||||
// Should find the three files. Order not important.
|
||||
EXPECT_THAT(names, ::testing::UnorderedElementsAre(
|
||||
kTestFileName, kTestFileName2, kTestFileName3));
|
||||
kTxtFilename1, kTxtFilename2, kBinFilename));
|
||||
|
||||
std::string wild_card_path = path_dir + kWildcard + kTestFileNameExt;
|
||||
EXPECT_TRUE(file_system_.Remove(wild_card_path));
|
||||
EXPECT_TRUE(file_system_.List(path_dir, &names));
|
||||
// Remove .txt files.
|
||||
const std::string txt_wildcard_path = PathJoin(dir_path, "*.txt");
|
||||
|
||||
EXPECT_EQ(1u, names.size());
|
||||
EXPECT_TRUE(names[0].compare(kTestFileName3) == 0);
|
||||
EXPECT_TRUE(file_system_.Remove(txt_wildcard_path))
|
||||
<< "txt_wildcard_path = " << txt_wildcard_path;
|
||||
EXPECT_TRUE(file_system_.List(dir_path, &names)) << "dir_path = " << dir_path;
|
||||
|
||||
std::string wild_card_path2 = path_dir + kWildcard + kTestFileNameExt3;
|
||||
EXPECT_TRUE(file_system_.Remove(wild_card_path2));
|
||||
EXPECT_TRUE(file_system_.List(path_dir, &names));
|
||||
expected_file_count = 1;
|
||||
ASSERT_EQ(names.size(), expected_file_count);
|
||||
EXPECT_EQ(names.front(), kBinFilename);
|
||||
|
||||
EXPECT_EQ(0u, names.size());
|
||||
const std::string bin_wildcard_path = PathJoin(dir_path, "*.bin");
|
||||
EXPECT_TRUE(file_system_.Remove(bin_wildcard_path))
|
||||
<< "bin_wildcard_path = " << bin_wildcard_path;
|
||||
|
||||
// All files should be removed, but listing should still succeed.
|
||||
EXPECT_TRUE(file_system_.List(dir_path, &names)) << "dir_path = " << dir_path;
|
||||
expected_file_count = 0;
|
||||
EXPECT_EQ(expected_file_count, names.size());
|
||||
}
|
||||
|
||||
TEST_F(FileTest, CreateGlobalCertificates) {
|
||||
// Clear directory
|
||||
TEST_F(FileTest, ListFiles_NotAPath) {
|
||||
const std::string not_path("zzz/xxx");
|
||||
std::vector<std::string> names;
|
||||
std::string path_dir = wvcdm::test_vectors::kTestDir;
|
||||
std::string wild_card_path = path_dir + kWildcard;
|
||||
file_system_.Remove(wild_card_path);
|
||||
if (file_system_.List(path_dir, &names)) {
|
||||
EXPECT_EQ(0u, names.size());
|
||||
// Ask for non-existent path.
|
||||
EXPECT_FALSE(file_system_.List(not_path, &names));
|
||||
}
|
||||
|
||||
TEST_F(FileTest, ListFiles_NullParameter) {
|
||||
const std::string dir_path = wvcdm::test_vectors::kTestDir;
|
||||
const std::string path = PathJoin(dir_path, kTestFilename);
|
||||
|
||||
std::unique_ptr<File> file = file_system_.Open(path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file) << "Failed to create file: " << path;
|
||||
file.reset(); // Close file.
|
||||
|
||||
// Valid path, but no way to return names.
|
||||
EXPECT_FALSE(file_system_.List(dir_path, nullptr));
|
||||
}
|
||||
|
||||
// On certain platforms, the FileSystem may perform special
|
||||
// name translations on certificate filenames which make them behave
|
||||
// differently from non-certificate filenames.
|
||||
TEST_F(FileTest, CreateGlobalCertificates) {
|
||||
ASSERT_TRUE(file_system_.IsGlobal())
|
||||
<< "Test case requires global file system";
|
||||
|
||||
const std::string dir_path = wvcdm::test_vectors::kTestDir;
|
||||
|
||||
// Clear directory
|
||||
const std::string all_file_wildcard_path = PathJoin(dir_path, "*");
|
||||
file_system_.Remove(all_file_wildcard_path);
|
||||
// Ensure directory is empty.
|
||||
std::vector<std::string> names;
|
||||
if (file_system_.List(dir_path, &names)) {
|
||||
constexpr size_t kZero = 0;
|
||||
ASSERT_EQ(kZero, names.size()) << "Test requires empty directory";
|
||||
}
|
||||
|
||||
// Create certificates and verify that they exist
|
||||
std::string certificate_path =
|
||||
wvcdm::test_vectors::kTestDir + kCertificateFileName;
|
||||
std::string legacy_certificate_path =
|
||||
wvcdm::test_vectors::kTestDir + kLegacyCertificateFileName;
|
||||
const std::string certificate_path = PathJoin(dir_path, kCertificateFileName);
|
||||
const std::string legacy_certificate_path =
|
||||
PathJoin(dir_path, kLegacyCertificateFileName);
|
||||
|
||||
// Create certificates and verify that they exist
|
||||
std::unique_ptr<File> file =
|
||||
file_system_.Open(certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create certificate file: "
|
||||
<< certificate_path;
|
||||
|
||||
file = file_system_.Open(legacy_certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
EXPECT_TRUE(file_system_.IsGlobal());
|
||||
ASSERT_TRUE(file) << "Failed to create legacy certificate file: "
|
||||
<< legacy_certificate_path;
|
||||
file.reset(); // Close file.
|
||||
|
||||
EXPECT_TRUE(file_system_.Exists(certificate_path));
|
||||
EXPECT_TRUE(file_system_.Exists(legacy_certificate_path));
|
||||
EXPECT_TRUE(file_system_.Exists(certificate_path))
|
||||
<< "certificate_path = " << certificate_path;
|
||||
EXPECT_TRUE(file_system_.Exists(legacy_certificate_path))
|
||||
<< "legacy_certificate_path = " << legacy_certificate_path;
|
||||
|
||||
EXPECT_TRUE(file_system_.List(path_dir, &names));
|
||||
ASSERT_TRUE(file_system_.List(dir_path, &names));
|
||||
|
||||
// Should find two files. Order not important.
|
||||
EXPECT_EQ(2u, names.size());
|
||||
constexpr size_t kExpectedCount = 2;
|
||||
EXPECT_EQ(kExpectedCount, names.size());
|
||||
EXPECT_THAT(names, ::testing::UnorderedElementsAre(
|
||||
kCertificateFileName, kLegacyCertificateFileName));
|
||||
}
|
||||
|
||||
// On certain platforms, the FileSystem may perform special
|
||||
// name translations on certificate filenames which make them behave
|
||||
// differently from non-certificate filenames.
|
||||
TEST_F(FileTest, CreateCertificates) {
|
||||
ASSERT_TRUE(file_system_.IsGlobal())
|
||||
<< "Test case requires starting with a global file system";
|
||||
const std::string dir_path = wvcdm::test_vectors::kTestDir;
|
||||
|
||||
// Clear directory
|
||||
const std::string all_file_wildcard_path = PathJoin(dir_path, "*");
|
||||
file_system_.Remove(all_file_wildcard_path);
|
||||
// Ensure directory is empty.
|
||||
std::vector<std::string> names;
|
||||
std::string path_dir = wvcdm::test_vectors::kTestDir;
|
||||
std::string wild_card_path = path_dir + kWildcard;
|
||||
file_system_.Remove(wild_card_path);
|
||||
if (file_system_.List(path_dir, &names)) {
|
||||
EXPECT_EQ(0u, names.size());
|
||||
if (file_system_.List(dir_path, &names)) {
|
||||
constexpr size_t kZero = 0;
|
||||
ASSERT_EQ(kZero, names.size()) << "Test requires empty directory";
|
||||
}
|
||||
|
||||
std::string certificate_path =
|
||||
wvcdm::test_vectors::kTestDir + kCertificateFileName;
|
||||
std::string legacy_certificate_path =
|
||||
wvcdm::test_vectors::kTestDir + kLegacyCertificateFileName;
|
||||
const std::string certificate_path = PathJoin(dir_path, kCertificateFileName);
|
||||
const std::string legacy_certificate_path =
|
||||
PathJoin(dir_path, kLegacyCertificateFileName);
|
||||
|
||||
// Create Global certificates
|
||||
// Create Global certificates.
|
||||
std::unique_ptr<File> file =
|
||||
file_system_.Open(certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create global certificate: "
|
||||
<< certificate_path;
|
||||
file = file_system_.Open(legacy_certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
EXPECT_TRUE(file_system_.IsGlobal());
|
||||
ASSERT_TRUE(file) << "Failed to create global legacy certificate: "
|
||||
<< legacy_certificate_path;
|
||||
file.reset(); // Close file.
|
||||
|
||||
EXPECT_TRUE(file_system_.Exists(certificate_path))
|
||||
<< "Global certificate: " << certificate_path;
|
||||
EXPECT_TRUE(file_system_.Exists(legacy_certificate_path))
|
||||
<< "Global legacy certificate: " << legacy_certificate_path;
|
||||
|
||||
// Switch to first identifier.
|
||||
file_system_.set_identifier(kTestIdentifier1);
|
||||
ASSERT_FALSE(file_system_.IsGlobal()) << "identifier = " << kTestIdentifier1;
|
||||
|
||||
// Global certificates should not be visible once identifier has been
|
||||
// specified.
|
||||
EXPECT_FALSE(file_system_.Exists(certificate_path))
|
||||
<< kTestIdentifier1 << " certificate: " << certificate_path;
|
||||
EXPECT_FALSE(file_system_.Exists(legacy_certificate_path))
|
||||
<< kTestIdentifier1 << " legacy certificate: " << legacy_certificate_path;
|
||||
|
||||
// Create certificates with first identifier
|
||||
file_system_.set_identifier(kTestIdentifier1);
|
||||
file = file_system_.Open(certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create " << kTestIdentifier1
|
||||
<< " certificate: " << certificate_path;
|
||||
file = file_system_.Open(legacy_certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
EXPECT_TRUE(!file_system_.IsGlobal());
|
||||
ASSERT_TRUE(file) << "Failed to create " << kTestIdentifier1
|
||||
<< " legacy certificate: " << legacy_certificate_path;
|
||||
file.reset(); // Close file.
|
||||
|
||||
// Verify they now exist.
|
||||
EXPECT_TRUE(file_system_.Exists(certificate_path))
|
||||
<< kTestIdentifier1 << " certificate: " << certificate_path;
|
||||
EXPECT_TRUE(file_system_.Exists(legacy_certificate_path))
|
||||
<< kTestIdentifier1 << " legacy certificate: " << legacy_certificate_path;
|
||||
|
||||
// Switch to second identifier.
|
||||
file_system_.set_identifier(kTestIdentifier2);
|
||||
ASSERT_FALSE(file_system_.IsGlobal()) << "identifier = " << kTestIdentifier2;
|
||||
|
||||
// Global and first identifier certificates should not be
|
||||
// visible.
|
||||
EXPECT_FALSE(file_system_.Exists(certificate_path))
|
||||
<< kTestIdentifier2 << " certificate: " << certificate_path;
|
||||
EXPECT_FALSE(file_system_.Exists(legacy_certificate_path))
|
||||
<< kTestIdentifier2 << " legacy certificate: " << legacy_certificate_path;
|
||||
|
||||
// Create certificates with second identifier
|
||||
file_system_.set_identifier(kTestIdentifier2);
|
||||
file = file_system_.Open(certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create " << kTestIdentifier2
|
||||
<< " certificate: " << certificate_path;
|
||||
file = file_system_.Open(legacy_certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
EXPECT_TRUE(!file_system_.IsGlobal());
|
||||
ASSERT_TRUE(file) << "Failed to create " << kTestIdentifier2
|
||||
<< " legacy certificate: " << legacy_certificate_path;
|
||||
file.reset(); // Close file.
|
||||
|
||||
EXPECT_TRUE(file_system_.Exists(certificate_path));
|
||||
EXPECT_TRUE(file_system_.Exists(legacy_certificate_path));
|
||||
// Verify they now exist.
|
||||
EXPECT_TRUE(file_system_.Exists(certificate_path))
|
||||
<< kTestIdentifier2 << " certificate: " << certificate_path;
|
||||
EXPECT_TRUE(file_system_.Exists(legacy_certificate_path))
|
||||
<< kTestIdentifier2 << " legacy certificate: " << legacy_certificate_path;
|
||||
|
||||
EXPECT_TRUE(file_system_.List(path_dir, &names));
|
||||
// FileSystem::List is expected to still return all certificate files
|
||||
// (both global and scoped).
|
||||
ASSERT_TRUE(file_system_.List(dir_path, &names)) << "dir_path = " << dir_path;
|
||||
|
||||
// Should find six files. Order not important.
|
||||
constexpr size_t kExpectedTotalCertCount = 6;
|
||||
ASSERT_EQ(names.size(), kExpectedTotalCertCount);
|
||||
|
||||
bool is_global_certificate_present = false;
|
||||
bool is_global_legacy_certificate_present = false;
|
||||
size_t certificate_count = 0;
|
||||
size_t legacy_certificate_count = 0;
|
||||
EXPECT_EQ(6u, names.size());
|
||||
for (size_t i = 0; i < names.size(); ++i) {
|
||||
if (names[i].size() > kCertificateFileName.size()) {
|
||||
if (names[i].compare(0, kCertificateFileNamePrefix.size(),
|
||||
kCertificateFileNamePrefix) == 0)
|
||||
++certificate_count;
|
||||
else if (names[i].compare(0, kLegacyCertificateFileNamePrefix.size(),
|
||||
kLegacyCertificateFileNamePrefix) == 0)
|
||||
++legacy_certificate_count;
|
||||
} else if (names[i].compare(kCertificateFileName) == 0) {
|
||||
is_global_certificate_present = true;
|
||||
} else if (names[i].compare(kLegacyCertificateFileName) == 0) {
|
||||
for (const auto& filename : names) {
|
||||
if (filename == kLegacyCertificateFileName) {
|
||||
is_global_legacy_certificate_present = true;
|
||||
} else if (filename == kCertificateFileName) {
|
||||
is_global_certificate_present = true;
|
||||
} else if (StartsWith(filename, kScopedCertificateFilenamePrefix)) {
|
||||
certificate_count++;
|
||||
} else if (StartsWith(filename, kLegacyScopedCertificateFilenamePrefix)) {
|
||||
legacy_certificate_count++;
|
||||
} else {
|
||||
EXPECT_TRUE(false);
|
||||
ADD_FAILURE() << "Unexpected filename: " << filename;
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(2, certificate_count);
|
||||
EXPECT_EQ(2, legacy_certificate_count);
|
||||
EXPECT_TRUE(is_global_certificate_present);
|
||||
EXPECT_TRUE(is_global_legacy_certificate_present);
|
||||
constexpr size_t kExpectedScopedCertCount = 2;
|
||||
EXPECT_EQ(certificate_count, kExpectedScopedCertCount)
|
||||
<< "Missing certificates";
|
||||
EXPECT_EQ(legacy_certificate_count, kExpectedScopedCertCount)
|
||||
<< "Missing legacy certificates";
|
||||
EXPECT_TRUE(is_global_certificate_present)
|
||||
<< "Missing global certificate: " << kCertificateFileName;
|
||||
EXPECT_TRUE(is_global_legacy_certificate_present)
|
||||
<< "Missing legacy global certificate: " << kLegacyCertificateFileName;
|
||||
}
|
||||
|
||||
// On certain platforms, the FileSystem may perform special
|
||||
// name translations on certificate file names which make them behave
|
||||
// differently from non-certificate file names.
|
||||
TEST_F(FileTest, RemoveCertificates) {
|
||||
ASSERT_TRUE(file_system_.IsGlobal())
|
||||
<< "Test case requires starting with a global file system";
|
||||
const std::string dir_path = wvcdm::test_vectors::kTestDir;
|
||||
|
||||
// Clear directory
|
||||
const std::string all_file_wildcard_path = PathJoin(dir_path, "*");
|
||||
file_system_.Remove(all_file_wildcard_path);
|
||||
// Ensure directory is empty.
|
||||
std::vector<std::string> names;
|
||||
std::string path_dir = wvcdm::test_vectors::kTestDir;
|
||||
std::string wild_card_path = path_dir + kWildcard;
|
||||
file_system_.Remove(wild_card_path);
|
||||
if (file_system_.List(path_dir, &names)) {
|
||||
EXPECT_EQ(0u, names.size());
|
||||
if (file_system_.List(dir_path, &names)) {
|
||||
constexpr size_t kZero = 0;
|
||||
ASSERT_EQ(kZero, names.size()) << "Test requires empty directory";
|
||||
}
|
||||
|
||||
std::string certificate_path =
|
||||
wvcdm::test_vectors::kTestDir + kCertificateFileName;
|
||||
std::string legacy_certificate_path =
|
||||
wvcdm::test_vectors::kTestDir + kLegacyCertificateFileName;
|
||||
const std::string certificate_path = PathJoin(dir_path, kCertificateFileName);
|
||||
const std::string legacy_certificate_path =
|
||||
PathJoin(dir_path, kLegacyCertificateFileName);
|
||||
|
||||
// Create Global certificates
|
||||
// Create Global certificates.
|
||||
std::unique_ptr<File> file =
|
||||
file_system_.Open(certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create global certificate: "
|
||||
<< certificate_path;
|
||||
file = file_system_.Open(legacy_certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
EXPECT_TRUE(file_system_.IsGlobal());
|
||||
ASSERT_TRUE(file) << "Failed to create global legacy certificate: "
|
||||
<< legacy_certificate_path;
|
||||
file.reset(); // Close file.
|
||||
|
||||
// Switch to first identifier.
|
||||
file_system_.set_identifier(kTestIdentifier1);
|
||||
ASSERT_FALSE(file_system_.IsGlobal()) << "identifier = " << kTestIdentifier1;
|
||||
|
||||
// Create certificates with first identifier
|
||||
file_system_.set_identifier(kTestIdentifier1);
|
||||
file = file_system_.Open(certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create " << kTestIdentifier1
|
||||
<< " certificate: " << certificate_path;
|
||||
file = file_system_.Open(legacy_certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
EXPECT_TRUE(!file_system_.IsGlobal());
|
||||
ASSERT_TRUE(file) << "Failed to create " << kTestIdentifier1
|
||||
<< " legacy certificate: " << legacy_certificate_path;
|
||||
file.reset(); // Close file.
|
||||
|
||||
// Switch to second identifier.
|
||||
file_system_.set_identifier(kTestIdentifier2);
|
||||
ASSERT_FALSE(file_system_.IsGlobal()) << "identifier = " << kTestIdentifier2;
|
||||
|
||||
// Create certificates with second identifier
|
||||
file_system_.set_identifier(kTestIdentifier2);
|
||||
file = file_system_.Open(certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
ASSERT_TRUE(file) << "Failed to create " << kTestIdentifier2
|
||||
<< " certificate: " << certificate_path;
|
||||
file = file_system_.Open(legacy_certificate_path, FileSystem::kCreate);
|
||||
ASSERT_TRUE(file);
|
||||
EXPECT_TRUE(!file_system_.IsGlobal());
|
||||
ASSERT_TRUE(file) << "Failed to create " << kTestIdentifier2
|
||||
<< " legacy certificate: " << legacy_certificate_path;
|
||||
file.reset(); // Close file.
|
||||
|
||||
EXPECT_TRUE(file_system_.Exists(certificate_path));
|
||||
EXPECT_TRUE(file_system_.Exists(legacy_certificate_path));
|
||||
|
||||
EXPECT_TRUE(file_system_.List(path_dir, &names));
|
||||
|
||||
EXPECT_EQ(6u, names.size());
|
||||
// FileSystem::List is expected to still return all certificate files
|
||||
// (both global and scoped).
|
||||
ASSERT_TRUE(file_system_.List(dir_path, &names)) << "dir_path = " << dir_path;
|
||||
// Should find six files. Order not important.
|
||||
constexpr size_t kExpectedTotalCertCount = 6;
|
||||
ASSERT_EQ(names.size(), kExpectedTotalCertCount);
|
||||
|
||||
std::set<std::string> removed_certs;
|
||||
// Remove all even number listed files
|
||||
for (size_t i = 0; i < names.size(); ++i) {
|
||||
if (i % 2 == 0) {
|
||||
EXPECT_TRUE(
|
||||
file_system_.Remove(wvcdm::test_vectors::kTestDir + names[i]));
|
||||
}
|
||||
if ((i % 2) != 0) continue;
|
||||
const std::string& cert_filename = names[i];
|
||||
const std::string cert_path = PathJoin(dir_path, cert_filename);
|
||||
ASSERT_TRUE(file_system_.Remove(cert_path))
|
||||
<< "Failed to remove cert: " << cert_path;
|
||||
removed_certs.insert(cert_filename);
|
||||
}
|
||||
|
||||
// Verify that they have been removed
|
||||
for (size_t i = 0; i < names.size(); ++i) {
|
||||
if (i % 2 == 1) {
|
||||
EXPECT_TRUE(
|
||||
file_system_.Exists(wvcdm::test_vectors::kTestDir + names[i]));
|
||||
for (const std::string& cert_filename : names) {
|
||||
const std::string cert_path = PathJoin(dir_path, cert_filename);
|
||||
if (removed_certs.find(cert_filename) == removed_certs.end()) {
|
||||
// Ensure still exists.
|
||||
ASSERT_TRUE(file_system_.Exists(cert_path))
|
||||
<< "Cert missing: " << cert_filename;
|
||||
} else {
|
||||
EXPECT_FALSE(
|
||||
file_system_.Exists(wvcdm::test_vectors::kTestDir + names[i]));
|
||||
ASSERT_FALSE(file_system_.Exists(cert_path))
|
||||
<< "Cert not removed: " << cert_filename;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all odd number listed files
|
||||
for (size_t i = 0; i < names.size(); ++i) {
|
||||
if (i % 2 == 1) {
|
||||
EXPECT_TRUE(
|
||||
file_system_.Remove(wvcdm::test_vectors::kTestDir + names[i]));
|
||||
}
|
||||
// Remove all remaining.
|
||||
for (const std::string& cert_filename : names) {
|
||||
if (removed_certs.find(cert_filename) != removed_certs.end()) continue;
|
||||
const std::string cert_path = PathJoin(dir_path, cert_filename);
|
||||
ASSERT_TRUE(file_system_.Remove(cert_path))
|
||||
<< "Failed to remove cert: " << cert_path;
|
||||
}
|
||||
|
||||
// Verify that all have been removed
|
||||
for (size_t i = 0; i < names.size(); ++i) {
|
||||
EXPECT_FALSE(file_system_.Exists(wvcdm::test_vectors::kTestDir + names[i]));
|
||||
for (const std::string& cert_filename : names) {
|
||||
const std::string cert_path = PathJoin(dir_path, cert_filename);
|
||||
EXPECT_FALSE(file_system_.Exists(cert_path))
|
||||
<< "Cert not removed: " << cert_filename;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wvutil
|
||||
|
||||
Reference in New Issue
Block a user