Merge "Add error details when offline license is not found" into udc-dev

This commit is contained in:
Rahul Frias
2023-05-02 23:41:30 +00:00
committed by Android (Google) Code Review
10 changed files with 183 additions and 38 deletions

View File

@@ -68,6 +68,15 @@ class DeviceFiles {
kIncorrectFileType = kResponseTypeBase + 14,
kIncorrectFileVersion = kResponseTypeBase + 15,
kLicenseNotPresent = kResponseTypeBase + 16,
kFileNotFoundEAcces = kResponseTypeBase + 17,
kFileNotFoundEFault = kResponseTypeBase + 18,
kFileNotFoundELoop = kResponseTypeBase + 19,
kFileNotFoundENameTooLong = kResponseTypeBase + 20,
kFileNotFoundENoEnt = kResponseTypeBase + 21,
kFileNotFoundENoMem = kResponseTypeBase + 22,
kFileNotFoundENotDir = kResponseTypeBase + 23,
kFileNotFoundEOverflow = kResponseTypeBase + 24,
kFileNotFoundOther = kResponseTypeBase + 25,
};
// Converts the different enum types to a human readable C-string for
@@ -75,6 +84,7 @@ class DeviceFiles {
static const char* CertificateStateToString(CertificateState state);
static const char* CertificateTypeToString(CertificateType type);
static const char* ResponseTypeToString(ResponseType type);
static ResponseType ErrnoToResponseType(int errno_value);
// CdmLicenseData represents all of the data that is stored in CDM
// license file. License data is uniquely keyed using |key_set_id|.

View File

@@ -236,9 +236,21 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
DeviceFiles::ResponseTypeToString(sub_error_code),
IdToString(key_set_id));
SetErrorDetail(error_detail, sub_error_code);
return sub_error_code == DeviceFiles::kFileNotFound
? CdmResponseType(KEYSET_ID_NOT_FOUND_4)
: CdmResponseType(GET_LICENSE_ERROR);
switch (sub_error_code) {
case DeviceFiles::kFileNotFound:
case DeviceFiles::kFileNotFoundEAcces:
case DeviceFiles::kFileNotFoundEFault:
case DeviceFiles::kFileNotFoundELoop:
case DeviceFiles::kFileNotFoundENameTooLong:
case DeviceFiles::kFileNotFoundENoEnt:
case DeviceFiles::kFileNotFoundENoMem:
case DeviceFiles::kFileNotFoundENotDir:
case DeviceFiles::kFileNotFoundEOverflow:
case DeviceFiles::kFileNotFoundOther:
return (CdmResponseType(KEYSET_ID_NOT_FOUND_4));
default:
return (CdmResponseType(GET_LICENSE_ERROR));
}
}
offline_init_data_ = std::move(license_data.pssh_data);
key_request_ = std::move(license_data.license_request);

View File

@@ -358,12 +358,56 @@ const char* DeviceFiles::ResponseTypeToString(ResponseType type) {
return "IncorrectFileVersion";
case kLicenseNotPresent:
return "LicenseNotFound";
case kFileNotFoundEAcces:
return "FileNotFound_EAcces";
case kFileNotFoundEFault:
return "FileNotFound_EFault";
case kFileNotFoundELoop:
return "FileNotFound_ELoop";
case kFileNotFoundENameTooLong:
return "FileNotFound_ENameTooLong";
case kFileNotFoundENoEnt:
return "FileNotFound_ENoEnt";
case kFileNotFoundENoMem:
return "FileNotFound_ENoMem";
case kFileNotFoundENotDir:
return "FileNotFound_ENotDir";
case kFileNotFoundEOverflow:
return "FileNotFound_EOverflow";
case kFileNotFoundOther:
return "FileNotFound_Other";
case kResponseTypeBase: // Not a valid value.
break;
}
return UnknownEnumValueToString(static_cast<int>(type));
}
// static
DeviceFiles::ResponseType DeviceFiles::ErrnoToResponseType(int errno_value) {
switch (errno_value) {
case 0:
return kNoError;
case EACCES:
return kFileNotFoundEAcces;
case EFAULT:
return kFileNotFoundEFault;
case ELOOP:
return kFileNotFoundELoop;
case ENAMETOOLONG:
return kFileNotFoundENameTooLong;
case ENOENT:
return kFileNotFoundENoEnt;
case ENOMEM:
return kFileNotFoundENoMem;
case ENOTDIR:
return kFileNotFoundENotDir;
case EOVERFLOW:
return kFileNotFoundEOverflow;
default:
return kFileNotFoundOther;
}
}
// static
std::set<std::string> DeviceFiles::reserved_license_ids_;
std::mutex DeviceFiles::reserved_license_ids_mutex_;
@@ -1999,9 +2043,12 @@ DeviceFiles::ResponseType DeviceFiles::RetrieveHashedFile(
path += name;
if (!file_system_->Exists(path)) {
LOGW("File does not exist: path = %s", path.c_str());
return kFileNotFound;
int errno_value = 0;
if (!file_system_->Exists(path, &errno_value)) {
const ResponseType result = ErrnoToResponseType(errno_value);
LOGW("File does not exist: path = %s, error = %s", path.c_str(),
ResponseTypeToString(result));
return result;
}
const ssize_t file_size = file_system_->FileSize(path);

View File

@@ -4432,6 +4432,7 @@ class MockFileSystem : public wvutil::FileSystem {
MOCK_METHOD(std::unique_ptr<File>, Open, (const std::string&, int flags),
(override));
MOCK_METHOD(bool, Exists, (const std::string&), (override));
MOCK_METHOD(bool, Exists, (const std::string&, int*), (override));
MOCK_METHOD(bool, Remove, (const std::string&), (override));
MOCK_METHOD(ssize_t, FileSize, (const std::string&), (override));
MOCK_METHOD(bool, List, (const std::string&, std::vector<std::string>*),
@@ -4640,6 +4641,9 @@ TEST_F(DeviceFilesTest, RetrieveAtscCertificate) {
// Call to Open will return a unique_ptr, freeing this object.
MockFile* file = new MockFile();
EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path), NotNull()))
.Times(AtLeast(1))
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path)))
.Times(AtLeast(1))
.WillRepeatedly(Return(true));
@@ -4908,6 +4912,9 @@ TEST_F(DeviceFilesTest, RetrieveDefaultCertificateNeverExpires) {
EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path)))
.Times(AtLeast(1))
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path), NotNull()))
.Times(AtLeast(1))
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(device_certificate_path)))
.WillOnce(Return(data.size()));
EXPECT_CALL(file_system, Open(StrEq(device_certificate_path), _))
@@ -4955,6 +4962,9 @@ TEST_P(RetrieveDefaultCertificateTest, ErrorScenarios) {
EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path)))
.Times(AtLeast(1))
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path), NotNull()))
.Times(AtLeast(1))
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(device_certificate_path)))
.WillOnce(Return(data.size()));
EXPECT_CALL(file_system, Open(StrEq(device_certificate_path), _))
@@ -5009,6 +5019,10 @@ TEST_F(DeviceFilesTest, RetrieveCertificateWithoutKeyType) {
EXPECT_CALL(file_system, Exists(StrEq(device_legacy_certificate_path)))
.Times(AtLeast(1))
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system,
Exists(StrEq(device_legacy_certificate_path), NotNull()))
.Times(AtLeast(1))
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(device_default_certificate_path)))
.Times(AtLeast(1))
.WillRepeatedly(Return(false));
@@ -5311,7 +5325,7 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
// Call to Open will return a unique_ptr, freeing this object.
MockFile* file = new MockFile();
EXPECT_CALL(file_system, Exists(StrEq(license_path)))
EXPECT_CALL(file_system, Exists(StrEq(license_path), NotNull()))
.WillOnce(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(license_path)))
.WillOnce(Return(size));
@@ -5383,7 +5397,8 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) {
// Call to Open will return a unique_ptr, freeing this object.
MockFile* file = new MockFile();
EXPECT_CALL(file_system, Exists(StrEq(license_path))).WillOnce(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(license_path), NotNull()))
.WillOnce(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(license_path)))
.WillOnce(Return(size));
EXPECT_CALL(file_system, Open(StrEq(license_path), _))
@@ -5474,10 +5489,9 @@ TEST_F(DeviceFilesTest, DeleteLicense) {
// Call to Open will return a unique_ptr, freeing this object.
MockFile* file = new MockFile();
EXPECT_CALL(file_system, Exists(StrEq(license_path)))
.Times(2)
.WillOnce(Return(true))
.WillOnce(Return(false));
EXPECT_CALL(file_system, Exists(StrEq(license_path))).WillOnce(Return(false));
EXPECT_CALL(file_system, Exists(StrEq(license_path), NotNull()))
.WillOnce(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(license_path)))
.WillOnce(Return(size));
EXPECT_CALL(file_system, Open(StrEq(license_path), _))
@@ -5579,10 +5593,12 @@ TEST_F(DeviceFilesTest, OkpInfo_FileDoesNotExist) {
MockFileSystem file_system;
DeviceFiles device_files(&file_system);
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
int errno_value = ENOENT;
const std::string kOkpInfoPath =
device_base_path_ + DeviceFiles::GetOkpInfoFileName();
EXPECT_CALL(file_system, Exists(kOkpInfoPath)).WillOnce(Return(false));
EXPECT_CALL(file_system, Exists(StrEq(kOkpInfoPath), NotNull()))
.WillRepeatedly(DoAll(SetArgPointee<1>(errno_value), (Return(false))));
okp::SystemFallbackInfo info;
EXPECT_FALSE(device_files.RetrieveOkpInfo(&info));
@@ -5641,7 +5657,8 @@ TEST_F(DeviceFilesTest, OkpInfo_StoreAndRetrieve) {
// Set retrieve expectations.
file = new MockFile();
EXPECT_CALL(file_system, Exists(kOkpInfoPath)).WillOnce(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(kOkpInfoPath), NotNull()))
.WillOnce(Return(true));
EXPECT_CALL(file_system, FileSize(kOkpInfoPath))
.WillOnce(Return(serialized.size()));
EXPECT_CALL(file_system, Open(kOkpInfoPath, _))
@@ -5676,6 +5693,7 @@ TEST_P(DeviceFilesDeleteMultipleUsageInfoTest, DeleteAllButOne) {
file_path += kUsageInfoFileName;
EXPECT_CALL(file_system, Exists(_)).WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(_, NotNull())).WillOnce(Return(true));
EXPECT_CALL(file_system, FileSize(file_path))
.WillOnce(Return(kHashedUsageInfoFileWithThreeKeySetIds.size()));
@@ -5733,6 +5751,7 @@ TEST_F(DeviceFilesDeleteMultipleUsageInfoTest, DeleteAllKeySetIds) {
// File read expectations.
MockFile* file_in = new MockFile();
EXPECT_CALL(file_system, Exists(_)).WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(_, NotNull())).WillRepeatedly(Return(true));
EXPECT_CALL(file_system, FileSize(file_path))
.WillOnce(Return(kHashedUsageInfoFileWithThreeKeySetIds.size()));
EXPECT_CALL(file_system, Open(file_path, wvutil::FileSystem::kReadOnly))
@@ -5763,6 +5782,7 @@ TEST_F(DeviceFilesDeleteMultipleUsageInfoTest, DeleteNone) {
file_path += kUsageInfoFileName;
EXPECT_CALL(file_system, Exists(_)).WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(_, NotNull())).WillRepeatedly(Return(true));
// Call, not providing any key set IDs. Should return true without any
// action, assuming the file exists.
@@ -5803,6 +5823,7 @@ TEST_F(DeviceFilesDeleteMultipleUsageInfoTest, DeleteOne) {
file_path += kUsageInfoFileName;
EXPECT_CALL(file_system, Exists(_)).WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(_, NotNull())).WillRepeatedly(Return(true));
EXPECT_CALL(file_system, FileSize(file_path))
.WillOnce(Return(kHashedUsageInfoFileWithTwoKeySetIds.size()));
@@ -5857,6 +5878,7 @@ TEST_F(DeviceFilesDeleteMultipleUsageInfoTest, BadFile) {
// File is missing hash.
MockFile* file_in = new MockFile();
EXPECT_CALL(file_system, Exists(_)).WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(_, NotNull())).WillRepeatedly(Return(true));
EXPECT_CALL(file_system, FileSize(file_path))
.WillOnce(Return(kHashlessUsageInfoFile.size()));
EXPECT_CALL(file_system, Open(file_path, wvutil::FileSystem::kReadOnly))
@@ -5903,9 +5925,9 @@ TEST_F(DeviceFilesUsageInfoTest, ListUsageIds) {
if (index >= 0) {
// Call to Open will return a unique_ptr, freeing this object.
MockFile* file = new MockFile();
EXPECT_CALL(file_system, Exists(StrEq(path)))
.Times(2)
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path), NotNull()))
.WillOnce(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(path)))
.Times(2)
.WillRepeatedly(Return(file_data.size()));
@@ -6038,9 +6060,9 @@ TEST_P(DeviceFilesUsageInfoTest, Retrieve) {
if (index >= 0) {
// Call to Open will return a unique_ptr, freeing this object.
MockFile* file = new MockFile();
EXPECT_CALL(file_system, Exists(StrEq(path)))
.Times(2)
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path), NotNull()))
.WillOnce(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(path)))
.Times(2)
.WillRepeatedly(Return(file_data.size()));
@@ -6101,9 +6123,9 @@ TEST_P(DeviceFilesUsageInfoTest, ListKeySetIds) {
if (index >= 0) {
// Call to Open will return a unique_ptr, freeing this object.
MockFile* file = new MockFile();
EXPECT_CALL(file_system, Exists(StrEq(path)))
.Times(2)
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path), NotNull()))
.WillOnce(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(path)))
.Times(2)
.WillRepeatedly(Return(file_data.size()));
@@ -6153,9 +6175,9 @@ TEST_P(DeviceFilesUsageInfoTest, ListProviderSessionTokenIds) {
if (index >= 0) {
// Call to Open will return a unique_ptr, freeing this object.
MockFile* file = new MockFile();
EXPECT_CALL(file_system, Exists(StrEq(path)))
.Times(2)
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path), NotNull()))
.WillOnce(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(path)))
.Times(2)
.WillRepeatedly(Return(file_data.size()));
@@ -6215,7 +6237,8 @@ TEST_P(DeviceFilesUsageInfoTest, RetrieveByProviderSessionToken) {
kUsageInfoTestData[index < 0 ? 0 : index]
.usage_data.provider_session_token;
EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path), NotNull()))
.WillOnce(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(path)))
.WillOnce(Return(file_data.size()));
EXPECT_CALL(file_system, Open(StrEq(path), _))
@@ -6299,9 +6322,9 @@ TEST_P(DeviceFilesUsageInfoTest, UpdateUsageInfo) {
(index < 0) ? kEmptyUsageInfoFileData
: kUsageInfoTestData[max_index_by_app_id].file_data;
EXPECT_CALL(file_system, Exists(StrEq(path)))
.Times(2)
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path), NotNull()))
.WillOnce(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(path)))
.WillOnce(Return(file_data.size()));
EXPECT_CALL(*file, Read(NotNull(), Eq(file_data.size())))
@@ -6344,7 +6367,8 @@ TEST_P(DeviceFilesHlsAttributesTest, Read) {
std::string path = device_base_path_ + param->key_set_id +
DeviceFiles::GetHlsAttributesFileNameExtension();
EXPECT_CALL(file_system, Exists(StrEq(path))).WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path), NotNull()))
.WillOnce(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(path)))
.WillRepeatedly(Return(param->file_data.size()));
EXPECT_CALL(file_system, Open(StrEq(path), _))
@@ -6452,7 +6476,8 @@ TEST_P(DeviceFilesUsageTableTest, Read) {
std::string path = device_base_path_ + DeviceFiles::GetUsageTableFileName();
const std::string& file_data = kUsageTableInfoTestData[index].file_data;
EXPECT_CALL(file_system, Exists(StrEq(path))).WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path), NotNull()))
.WillOnce(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(path)))
.WillRepeatedly(Return(file_data.size()));
EXPECT_CALL(file_system, Open(StrEq(path), _))
@@ -6505,7 +6530,8 @@ TEST_F(DeviceFilesUsageTableTest, ReadWithoutLruData) {
const std::string path =
device_base_path_ + DeviceFiles::GetUsageTableFileName();
MockFileSystem file_system;
EXPECT_CALL(file_system, Exists(StrEq(path))).WillRepeatedly(Return(true));
EXPECT_CALL(file_system, Exists(StrEq(path), NotNull()))
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(path)))
.WillRepeatedly(Return(kUsageTableWithoutLruData.size()));
EXPECT_CALL(file_system, Open(StrEq(path), _))
@@ -6619,7 +6645,7 @@ TEST_F(DeviceFilesTest, RetrieveOemCertificateSuccess) {
device_base_path_ + wvutil::kOemCertificateFileName;
// Call to Open will return a unique_ptr, freeing this object.
MockFile* read_file = new MockFile();
EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path)))
EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path), NotNull()))
.Times(AtLeast(1))
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(device_certificate_path)))
@@ -6650,7 +6676,7 @@ TEST_F(DeviceFilesTest, RetrieveOemCertificateRandomCertFail) {
std::string ramdom_cert = "random_cert";
// Call to Open will return a unique_ptr, freeing this object.
MockFile* read_file = new MockFile();
EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path)))
EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path), NotNull()))
.Times(AtLeast(1))
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, FileSize(StrEq(device_certificate_path)))
@@ -6676,9 +6702,10 @@ TEST_F(DeviceFilesTest, RetrieveOemCertificateNotFoundFail) {
MockFileSystem file_system;
const std::string device_certificate_path =
device_base_path_ + wvutil::kOemCertificateFileName;
EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path)))
int errno_value = ENOENT;
EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path), NotNull()))
.Times(AtLeast(1))
.WillRepeatedly(Return(false));
.WillRepeatedly(DoAll(SetArgPointee<1>(errno_value), (Return(false))));
DeviceFiles device_files(&file_system);
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));

View File

@@ -58,6 +58,7 @@ class FileSystem {
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);
virtual ssize_t FileSize(const std::string& file_path);

View File

@@ -16,6 +16,7 @@ bool IsCurrentOrParentDirectory(const char* dir);
class FileUtils {
public:
static bool Exists(const std::string& src);
static bool Exists(const std::string& src, int* errno_value);
// The caller may only specifying a single wildcard
static bool Remove(const std::string& src);
static bool Copy(const std::string& src, const std::string& dest);

View File

@@ -497,6 +497,11 @@ std::unique_ptr<File> FileSystem::Open(const std::string& file_name,
return std::unique_ptr<File>(new AndroidFile(fd, flags, file_path));
}
bool FileSystem::Exists(const std::string& path, int* errno_value) {
return FileUtils::Exists(GetFileNameForIdentifier(path, identifier_),
errno_value);
}
bool FileSystem::Exists(const std::string& path) {
return FileUtils::Exists(GetFileNameForIdentifier(path, identifier_));
}

View File

@@ -25,11 +25,22 @@ bool IsCurrentOrParentDirectory(const char* dir) {
}
bool FileUtils::Exists(const std::string& path) {
return Exists(path, nullptr);
}
bool FileUtils::Exists(const std::string& path, int* errno_value) {
struct stat buf;
int error = 0;
int res = stat(path.c_str(), &buf) == 0;
if (!res) {
LOGV("File::Exists: stat failed: %d, %s", errno, strerror(errno));
error = errno;
if (error == ENOENT) {
LOGI("stat failed: ENOENT");
} else {
LOGE("stat failed: %d, %s", error, strerror(error));
}
}
if (errno_value != nullptr) *errno_value = error;
return res;
}

View File

@@ -39,9 +39,17 @@ 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, &errno_value));
EXPECT_EQ(0, errno_value);
EXPECT_TRUE(file_system_.Exists(wvcdm::test_vectors::kExistentDir));
EXPECT_FALSE(file_system_.Exists(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));
}

View File

@@ -98,6 +98,29 @@ TEST_F(FileUtilsTest, IsRegularFile) {
EXPECT_FALSE(FileUtils::IsRegularFile(wvcdm::test_vectors::kTestDir));
}
TEST_F(FileUtilsTest, FileExists) {
std::string path = wvcdm::test_vectors::kTestDir + kTestFileName;
std::string path2 = wvcdm::test_vectors::kTestDir + kTestFileName2;
file_system_.Remove(path);
file_system_.Remove(path2);
std::unique_ptr<File> file = file_system_.Open(path, FileSystem::kCreate);
EXPECT_TRUE(file);
EXPECT_TRUE(file_system_.Exists(path));
int errno_value = -1;
EXPECT_TRUE(file_system_.Exists(path, &errno_value));
EXPECT_EQ(0, errno_value);
EXPECT_TRUE(file_system_.Exists(wvcdm::test_vectors::kTestDir));
EXPECT_TRUE(file_system_.Exists(path, nullptr));
EXPECT_FALSE(file_system_.Exists(path2));
EXPECT_FALSE(file_system_.Exists(path2, &errno_value));
EXPECT_EQ(ENOENT, errno_value);
EXPECT_TRUE(file_system_.Exists(wvcdm::test_vectors::kTestDir));
EXPECT_FALSE(file_system_.Exists(path2, nullptr));
}
TEST_F(FileUtilsTest, CopyFile) {
std::string path = wvcdm::test_vectors::kTestDir + kTestFileName;
file_system_.Remove(path);