Implement modular POSIX filesystem support for deleting files and directories.
We also provide tests to make sure all API requirements are satisfied. Just a small sized part of work for modular filesystem plugins. For more details, consult the RFC at https://github.com/tensorflow/community/blob/master/rfcs/20190506-filesystem-plugin-modular-tensorflow.md PiperOrigin-RevId: 281107956 Change-Id: I0be89ff20d2c865fe552a9eeee12573eff63eb01
This commit is contained in:
parent
837b26bd57
commit
c455ab4555
@ -137,9 +137,15 @@ Status ModularFileSystem::GetMatchingPaths(const std::string& pattern,
|
||||
}
|
||||
|
||||
Status ModularFileSystem::DeleteFile(const std::string& fname) {
|
||||
// TODO(mihaimaruseac): Implementation to come in a new change
|
||||
return Status(error::UNIMPLEMENTED,
|
||||
"Modular filesystem stub not implemented yet");
|
||||
if (ops_->delete_file == nullptr)
|
||||
return errors::Unimplemented(tensorflow::strings::StrCat(
|
||||
"Filesystem for ", fname, " does not support DeleteFile()"));
|
||||
|
||||
UniquePtrTo_TF_Status plugin_status(TF_NewStatus(), TF_DeleteStatus);
|
||||
std::string translated_name = TranslateName(fname);
|
||||
ops_->delete_file(filesystem_.get(), translated_name.c_str(),
|
||||
plugin_status.get());
|
||||
return StatusFromTF_Status(plugin_status.get());
|
||||
}
|
||||
|
||||
Status ModularFileSystem::DeleteRecursively(const std::string& dirname,
|
||||
@ -151,9 +157,15 @@ Status ModularFileSystem::DeleteRecursively(const std::string& dirname,
|
||||
}
|
||||
|
||||
Status ModularFileSystem::DeleteDir(const std::string& dirname) {
|
||||
// TODO(mihaimaruseac): Implementation to come in a new change
|
||||
return Status(error::UNIMPLEMENTED,
|
||||
"Modular filesystem stub not implemented yet");
|
||||
if (ops_->delete_dir == nullptr)
|
||||
return errors::Unimplemented(tensorflow::strings::StrCat(
|
||||
"Filesystem for ", dirname, " does not support DeleteDir()"));
|
||||
|
||||
UniquePtrTo_TF_Status plugin_status(TF_NewStatus(), TF_DeleteStatus);
|
||||
std::string translated_name = TranslateName(dirname);
|
||||
ops_->delete_dir(filesystem_.get(), translated_name.c_str(),
|
||||
plugin_status.get());
|
||||
return StatusFromTF_Status(plugin_status.get());
|
||||
}
|
||||
|
||||
Status ModularFileSystem::RecursivelyCreateDir(const std::string& dirname) {
|
||||
|
@ -427,6 +427,118 @@ TEST_P(ModularFileSystemTest, TestCreateDirPathIsInvalid) {
|
||||
EXPECT_PRED2(UninmplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
|
||||
}
|
||||
|
||||
TEST_P(ModularFileSystemTest, TestDeleteFile) {
|
||||
const std::string filepath = GetURIForPath("a_file");
|
||||
std::unique_ptr<WritableFile> new_file;
|
||||
Status status = env_->NewWritableFile(filepath, &new_file);
|
||||
if (!status.ok()) GTEST_SKIP() << "NewWritableFile() not supported";
|
||||
|
||||
status = env_->DeleteFile(filepath);
|
||||
EXPECT_PRED2(UninmplementedOrReturnsCode, status, Code::OK);
|
||||
}
|
||||
|
||||
TEST_P(ModularFileSystemTest, TestDeleteFileFromDirectory) {
|
||||
const std::string dirpath = GetURIForPath("a_dir");
|
||||
Status status = env_->CreateDir(dirpath);
|
||||
if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported";
|
||||
|
||||
const std::string filepath = GetURIForPath("a_dir/a_file");
|
||||
std::unique_ptr<WritableFile> new_file;
|
||||
status = env_->NewWritableFile(filepath, &new_file);
|
||||
if (!status.ok()) GTEST_SKIP() << "NewWritableFile() not supported";
|
||||
|
||||
status = env_->DeleteFile(filepath);
|
||||
EXPECT_PRED2(UninmplementedOrReturnsCode, status, Code::OK);
|
||||
}
|
||||
|
||||
TEST_P(ModularFileSystemTest, TestDeleteFileDoesNotExist) {
|
||||
const std::string filepath = GetURIForPath("a_file");
|
||||
Status status = env_->DeleteFile(filepath);
|
||||
EXPECT_PRED2(UninmplementedOrReturnsCode, status, Code::NOT_FOUND);
|
||||
}
|
||||
|
||||
TEST_P(ModularFileSystemTest, TestDeleteFileWhichIsDirectory) {
|
||||
const std::string dirpath = GetURIForPath("a_dir");
|
||||
Status status = env_->CreateDir(dirpath);
|
||||
if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported";
|
||||
|
||||
status = env_->DeleteFile(dirpath);
|
||||
EXPECT_PRED2(UninmplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
|
||||
}
|
||||
|
||||
TEST_P(ModularFileSystemTest, TestDeleteFilePathIsInvalid) {
|
||||
const std::string filepath = GetURIForPath("a_file");
|
||||
std::unique_ptr<WritableFile> file;
|
||||
Status status = env_->NewWritableFile(filepath, &file);
|
||||
if (!status.ok()) GTEST_SKIP() << "NewWritableFile() not supported";
|
||||
|
||||
const std::string new_path = GetURIForPath("a_file/a_new_file");
|
||||
status = env_->DeleteFile(new_path);
|
||||
EXPECT_PRED2(UninmplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
|
||||
}
|
||||
|
||||
TEST_P(ModularFileSystemTest, TestDeleteDirectory) {
|
||||
const std::string dirpath = GetURIForPath("a_dir");
|
||||
Status status = env_->CreateDir(dirpath);
|
||||
if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported";
|
||||
|
||||
status = env_->DeleteDir(dirpath);
|
||||
EXPECT_PRED2(UninmplementedOrReturnsCode, status, Code::OK);
|
||||
}
|
||||
|
||||
TEST_P(ModularFileSystemTest, TestDeleteDirectoryFromDirectory) {
|
||||
const std::string dirpath = GetURIForPath("a_dir");
|
||||
Status status = env_->CreateDir(dirpath);
|
||||
if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported";
|
||||
|
||||
const std::string target_path = GetURIForPath("a_dir/another_dir");
|
||||
EXPECT_EQ(env_->CreateDir(target_path).code(), Code::OK);
|
||||
|
||||
status = env_->DeleteDir(target_path);
|
||||
EXPECT_PRED2(UninmplementedOrReturnsCode, status, Code::OK);
|
||||
}
|
||||
|
||||
TEST_P(ModularFileSystemTest, TestDeleteDirectoryDoesNotExist) {
|
||||
const std::string dirpath = GetURIForPath("a_dir");
|
||||
Status status = env_->DeleteDir(dirpath);
|
||||
EXPECT_PRED2(UninmplementedOrReturnsCode, status, Code::NOT_FOUND);
|
||||
}
|
||||
|
||||
TEST_P(ModularFileSystemTest, TestDeleteDirectoryNotEmpty) {
|
||||
const std::string dirpath = GetURIForPath("a_dir");
|
||||
Status status = env_->CreateDir(dirpath);
|
||||
if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported";
|
||||
|
||||
const std::string filepath = GetURIForPath("a_dir/a_file");
|
||||
std::unique_ptr<WritableFile> new_file;
|
||||
status = env_->NewWritableFile(filepath, &new_file);
|
||||
if (!status.ok()) GTEST_SKIP() << "NewWritableFile() not supported";
|
||||
|
||||
status = env_->DeleteDir(dirpath);
|
||||
EXPECT_PRED2(UninmplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
|
||||
}
|
||||
|
||||
TEST_P(ModularFileSystemTest, TestDeleteDirectoryWhichIsFile) {
|
||||
const std::string filepath = GetURIForPath("a_file");
|
||||
std::unique_ptr<WritableFile> new_file;
|
||||
Status status = env_->NewWritableFile(filepath, &new_file);
|
||||
if (!status.ok()) GTEST_SKIP() << "NewWritableFile() not supported";
|
||||
|
||||
status = env_->DeleteDir(filepath);
|
||||
EXPECT_PRED2(UninmplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
|
||||
}
|
||||
|
||||
TEST_P(ModularFileSystemTest, TestDeleteDirectoryPathIsInvalid) {
|
||||
const std::string filepath = GetURIForPath("a_file");
|
||||
std::unique_ptr<WritableFile> file;
|
||||
Status status = env_->NewWritableFile(filepath, &file);
|
||||
if (!status.ok()) GTEST_SKIP() << "NewWritableFile() not supported";
|
||||
|
||||
const std::string new_path = GetURIForPath("a_file/a_dir");
|
||||
status = env_->DeleteDir(new_path);
|
||||
EXPECT_PRED2(UninmplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
|
||||
}
|
||||
|
||||
TEST_P(ModularFileSystemTest, TestAppendAndTell) {
|
||||
const std::string filename = GetURIForPath("a_file");
|
||||
std::unique_ptr<WritableFile> file;
|
||||
|
@ -271,6 +271,22 @@ static void CreateDir(const TF_Filesystem* filesystem, const char* path,
|
||||
TF_SetStatus(status, TF_OK, "");
|
||||
}
|
||||
|
||||
static void DeleteFile(const TF_Filesystem* filesystem, const char* path,
|
||||
TF_Status* status) {
|
||||
if (unlink(path) != 0)
|
||||
TF_SetStatusFromIOError(status, errno, path);
|
||||
else
|
||||
TF_SetStatus(status, TF_OK, "");
|
||||
}
|
||||
|
||||
static void DeleteDir(const TF_Filesystem* filesystem, const char* path,
|
||||
TF_Status* status) {
|
||||
if (rmdir(path) != 0)
|
||||
TF_SetStatusFromIOError(status, errno, path);
|
||||
else
|
||||
TF_SetStatus(status, TF_OK, "");
|
||||
}
|
||||
|
||||
// TODO(mihaimaruseac): More implementations to follow in subsequent changes.
|
||||
|
||||
} // namespace tf_posix_filesystem
|
||||
@ -298,6 +314,9 @@ void TF_InitPlugin(TF_Status* status) {
|
||||
tf_posix_filesystem::NewAppendableFile,
|
||||
tf_posix_filesystem::NewReadOnlyMemoryRegionFromFile,
|
||||
tf_posix_filesystem::CreateDir,
|
||||
/*recursively_create_dir=*/nullptr,
|
||||
tf_posix_filesystem::DeleteFile,
|
||||
tf_posix_filesystem::DeleteDir,
|
||||
nullptr,
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user