Cleaned up file_store_unittest.cpp

[ Merge of http://go/wvgerrit/209590 ]

The filestore unit tests have not been updated in a while, and
contained several test statements which could crash the test
when failed (accessing elements in a vector or characters in a
string without proper size checks).  Other parts of the tests
had non-obvious purposes without detailed knowledge of how the
file system works on the different platforms.

Significant parts of the tests have been refactored to include
better checking and to add error messages to explain the
expectations.  Several of the tests have been documented, and the
FileSystem header has been updated to explain what the API does.

Bug: 376533901
Test: file_store_unittest on Oriole
Change-Id: I5af9fd2a2ed01aa6186026761c9e0814604ec610
This commit is contained in:
Alex Dale
2024-11-04 17:54:34 -08:00
parent f80e6667f3
commit bc4382b075
2 changed files with 463 additions and 220 deletions

View File

@@ -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);

View File

@@ -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