[DEV] continue work on filesystem test and code

This commit is contained in:
Edouard DUPIN 2018-09-05 13:56:38 +02:00
parent e6bb8fb633
commit 8f02b5ccd4
3 changed files with 228 additions and 32 deletions

View File

@ -64,31 +64,51 @@ bool etk::fs::moveFile(const etk::Path& _path1, const etk::Path& _path2) {
return etk::fs::move(_path1, _path2);
}
bool etk::fs::remove(const etk::Path& _path) {
if (etk::fs::isDirectory(_path) == true) {
return etk::fs::removeDirectory(_path);
namespace detail {
bool removeDirectories(const etk::Path& _path, bool _recursive);
bool removes(const etk::Path& _path, bool _recursive) {
TK_VERBOSE("remove: " << _path);
if (etk::fs::isDirectory(_path) == true) {
return detail::removeDirectories(_path, _recursive);
}
return etk::fs::removeFile(_path);
}
return etk::fs::removeFile(_path);
}
bool etk::fs::removeDirectory(const etk::Path& _path, bool _force) {
if (_force == true) {
if (0 != remove(_path.getString().c_str()) ) {
bool removeDirectories(const etk::Path& _path, bool _recursive) {
TK_VERBOSE("remove Directory: " << _path);
if (_recursive == true) {
etk::Vector<etk::Path> elements = etk::fs::list(_path);
for (auto& it : elements) {
detail::removes(it, _recursive);
}
}
if ( 0 != ::rmdir(_path.getString().c_str()) ) {
if (ENOTEMPTY == errno) {
TK_ERROR("The Directory is not empty...");
}
return false;
}
return true;
}
if ( 0 != ::rmdir(_path.getString().c_str()) ) {
if (ENOTEMPTY == errno) {
TK_ERROR("The Directory is not empty...");
}
return false;
}
return true;
}
bool etk::fs::remove(const etk::Path& _path) {
return detail::removes(_path, false);
}
bool etk::fs::removes(const etk::Path& _path) {
return detail::removes(_path, true);
}
bool etk::fs::removeDirectory(const etk::Path& _path) {
return detail::removeDirectories(_path, false);
}
bool etk::fs::removeDirectories(const etk::Path& _path) {
return detail::removeDirectories(_path, true);
}
bool etk::fs::removeFile(const etk::Path& _path) {
TK_VERBOSE("remove File: " << _path);
if (0 != unlink(_path.getString().c_str()) ) {
return false;
}
@ -96,23 +116,30 @@ bool etk::fs::removeFile(const etk::Path& _path) {
}
bool etk::fs::makeDirectory(const etk::Path& _path, etk::fs::Permissions _permission) {
TK_VERBOSE("Make directory : " << _path << " perm: " << _permission);
if (etk::fs::exist(_path) == true) {
return true;
}
#ifdef __TARGET_OS__Windows
if (0!=mkdir(_path.getString().c_str())) {
return true;
if (::mkdir(_path.getString().c_str()) != 0
&& errno != EEXIST) {
return false;
}
#else
mode_t mode = _permission.getRightValue();
if (0!=mkdir(_path.getString().c_str(), mode)) {
return true;
if ( ::mkdir(_path.getString().c_str(), mode) != 0
&& errno != EEXIST ) {
return false;
}
#endif
return false;
return true;
}
bool etk::fs::makeDirectories(const etk::Path& _path, etk::fs::Permissions _permission) {
TK_VERBOSE("Make dirrectories: " << _path << " perm: " << _permission);
if (etk::fs::exist(_path) == true) {
return true;
}
auto elements = _path.getString().split('/');
etk::Path pathToCreate;
if (elements[0].size() == 0) {
@ -130,9 +157,17 @@ bool etk::fs::makeDirectories(const etk::Path& _path, etk::fs::Permissions _perm
bool etk::fs::touch(const etk::Path& _path) {
TK_DEBUG("Touch FILE : " << _path);
//just open in write an close ==> this will update the time
if (etk::fs::exist(_path) == true ) {
//just open in write an close ==> this will update the time
etk::io::File file{_path};
if (file.open(etk::io::OpenMode::Append) == false) {
return false;
}
return file.close();
}
// Write the file with nothing inside...
etk::io::File file{_path};
if (file.open(etk::io::OpenMode::Append) == false) {
if (file.open(etk::io::OpenMode::Write) == false) {
return false;
}
return file.close();
@ -258,8 +293,22 @@ etk::Path etk::fs::getTemporaryPath() {
return etk::Path{folder};
}
namespace detail {
etk::Path getTemporaryProcessPath(const etk::String& _patern) {
char tmpName[1024];
strcpy(tmpName, _patern.c_str());
mktemp(tmpName);
return etk::fs::getTemporaryPath() / tmpName;
}
}
etk::Path etk::fs::getTemporaryProcessPath() {
static etk::Path out = detail::getTemporaryProcessPath("etk.process.XXXXXX");
return out;
}
etk::Path etk::fs::getTemporaryRandomPath() {
return etk::fs::getTemporaryPath() / "DFGDSF__TODO__SDFSDF";
return detail::getTemporaryProcessPath("etk.random.XXXXXX");
}
static etk::String getHomePathString() {
@ -404,4 +453,28 @@ uint32_t etk::fs::getIdGroup(const etk::Path& _path) {
return statProperty.st_gid;
}
etk::Vector<etk::Path> etk::fs::list(const etk::Path& _path) {
etk::Vector<etk::Path> out;
if (etk::fs::isDirectory(_path) == false) {
return out;
}
DIR *dir = null;
struct dirent *ent = null;
dir = opendir(_path.getString().c_str());
if (dir != null) {
// for each element in the drectory...
while ((ent = readdir(dir)) != null) {
if( strcmp(ent->d_name, ".") == 0
|| strcmp(ent->d_name, "..") == 0) {
// do nothing ...
continue;
}
out.pushBack(_path / ent->d_name);
}
closedir(dir);
} else {
TK_ERROR("could not open directory : '" << _path << "'");
}
return out;
}

View File

@ -69,13 +69,26 @@ namespace etk {
*/
bool remove(const etk::Path& _path);
/**
* @brief Remove a FOLDER path (if possible...)
* @brief Remove a path recursively
* @param[in] _path Path to remove.
* @param[in] _force Remove all data inside.
* @return true Operation succeed.
* @return false Operation Failed.
*/
bool removeDirectory(const etk::Path& _path, bool _force=false);
bool removes(const etk::Path& _path);
/**
* @brief Remove a FOLDER path (if possible...)
* @param[in] _path Path to remove.
* @return true Operation succeed.
* @return false Operation Failed.
*/
bool removeDirectory(const etk::Path& _path);
/**
* @brief Remove a FOLDER path (with all his sub files
* @param[in] _path Path to remove.
* @return true Operation succeed.
* @return false Operation Failed.
*/
bool removeDirectories(const etk::Path& _path);
/**
* @brief Remove a FILE path (if possible...)
* @param[in] _path Path to remove.
@ -177,7 +190,12 @@ namespace etk {
*/
etk::Path getTemporaryPath();
/**
* @brief Get a temporary path that can be write as you want witha a random subfolder.
* @brief Get a temporary path random and unique for all the process axecution.
* @return A system path with gegerated string.
*/
etk::Path getTemporaryProcessPath();
/**
* @brief Get a temporary path random at each call of the application.
* @return A system path with gegerated string.
*/
etk::Path getTemporaryRandomPath();
@ -243,6 +261,12 @@ namespace etk {
* @return Generic permission class.
*/
etk::fs::Permissions getPermission(const etk::Path& _path);
/**
* @brief List the content of a specific path.
* @param[in] Path to parse.
* @return the full list of path in the _path.
*/
etk::Vector<etk::Path> list(const etk::Path& _path);
}
}

View File

@ -27,16 +27,115 @@ TEST(TestFileSystem, getBinaryPath) {
EXPECT_EQ(etk::fs::getBinaryPath().getString().split('/').size() > 2, true);
}
TEST(TestFileSystem, randomProcessPath) {
etk::Path path1 = etk::fs::getTemporaryProcessPath();
etk::Path path2 = etk::fs::getTemporaryProcessPath();
EXPECT_EQ(path1,path2);
}
TEST(TestFileSystem, createDirectory) {
TEST(TestFileSystem, randomPath) {
etk::Path path1 = etk::fs::getTemporaryRandomPath();
etk::Path path2 = etk::fs::getTemporaryRandomPath();
EXPECT_NE(path1,path2);
}
TEST(TestFileSystem, create_and_remove_directory_relative) {
etk::Path path = "hello";
EXPECT_EQ(etk::fs::exist(path), false);
EXPECT_EQ(etk::fs::makeDirectory(path), true);
EXPECT_EQ(etk::fs::exist(path), true);
EXPECT_EQ(etk::fs::makeDirectory(path), true);
EXPECT_EQ(etk::fs::removeDirectory(path), true);
EXPECT_EQ(etk::fs::exist(path), false);
}
TEST(TestFileSystem, createDirectory_relative_error) {
etk::Path path = "hello/sdfsdf";
EXPECT_EQ(etk::fs::exist(path), false);
EXPECT_EQ(etk::fs::makeDirectory(path), false);
EXPECT_EQ(etk::fs::exist(path), false);
}
TEST(TestFileSystem, create_and_remove_directories) {
etk::Path pathRandom = etk::fs::getTemporaryRandomPath();
etk::Path path = pathRandom / "eee" / "kjlk" / "kjhkjh";
TEST_WARNING("path tmp: " << path);
TEST_DEBUG("path tmp: " << path);
EXPECT_EQ(etk::fs::exist(path), false);
EXPECT_EQ(etk::fs::makeDirectories(path), true);
EXPECT_EQ(etk::fs::exist(path), true);
EXPECT_EQ(etk::fs::removeDirectory(pathRandom, true), true);
EXPECT_EQ(etk::fs::removeDirectories(pathRandom), true);
EXPECT_EQ(etk::fs::exist(pathRandom), false);
EXPECT_EQ(etk::fs::exist(path), false);
}
TEST(TestFileSystem, create_and_remove_directories_error) {
etk::Path pathRandom = etk::fs::getTemporaryRandomPath();
etk::Path path = etk::Path("home") / "eee" / "kjlk" / "kjhkjh";
TEST_DEBUG("path tmp: " << path);
EXPECT_EQ(etk::fs::exist(path), false);
EXPECT_EQ(etk::fs::makeDirectories(path), false);
EXPECT_EQ(etk::fs::exist(path), false);
}
TEST(TestFileSystem, move_directory) {
etk::Path pathRandom = etk::fs::getTemporaryRandomPath();
etk::Path path1 = pathRandom / "eee1";
etk::Path path2 = pathRandom / "eee2";
etk::Path offset = etk::Path("kjlk") / "kjhkjh";
EXPECT_EQ(etk::fs::exist(path1), false);
EXPECT_EQ(etk::fs::exist(path2), false);
EXPECT_EQ(etk::fs::exist(path1 / offset), false);
EXPECT_EQ(etk::fs::exist(path2 / offset), false);
EXPECT_EQ(etk::fs::makeDirectories(path1 / offset), true);
EXPECT_EQ(etk::fs::exist(path1), true);
EXPECT_EQ(etk::fs::exist(path2), false);
EXPECT_EQ(etk::fs::exist(path1 / offset), true);
EXPECT_EQ(etk::fs::exist(path2 / offset), false);
EXPECT_EQ(etk::fs::move(path1, path2), true);
EXPECT_EQ(etk::fs::exist(path1), false);
EXPECT_EQ(etk::fs::exist(path2), true);
EXPECT_EQ(etk::fs::exist(path1 / offset), false);
EXPECT_EQ(etk::fs::exist(path2 / offset), true);
EXPECT_EQ(etk::fs::removeDirectories(pathRandom), true);
EXPECT_EQ(etk::fs::exist(pathRandom), false);
}
TEST(TestFileSystem, touch) {
etk::Path pathRandom = etk::fs::getTemporaryRandomPath();
etk::Path path = pathRandom / "eee" / "kjlk" / "kjhkjh.txt";
TEST_DEBUG("path tmp: " << path);
EXPECT_EQ(etk::fs::exist(path), false);
EXPECT_EQ(etk::fs::touch(path), false);
EXPECT_EQ(etk::fs::makeDirectories(path.getParent()), true);
EXPECT_EQ(etk::fs::exist(path), false);
EXPECT_EQ(etk::fs::touch(path), true);
EXPECT_EQ(etk::fs::exist(path), true);
uint64_t touch1 = etk::fs::getModifyTime(path);
EXPECT_EQ(etk::fs::touch(path), true);
EXPECT_EQ(etk::fs::exist(path), true);
uint64_t touch2 = etk::fs::getModifyTime(path);
EXPECT_NE(touch1, touch2);
/*
EXPECT_EQ(etk::fs::removeDirectories(pathRandom), true);
EXPECT_EQ(etk::fs::exist(pathRandom), false);
EXPECT_EQ(etk::fs::exist(path), false);
*/
}
/*
TEST(TestFileSystem, move_file) {
etk::Path pathRandom = etk::fs::getTemporaryRandomPath();
etk::Path path1 = pathRandom / "eee1.txt";
etk::Path path2 = pathRandom / "eee2.mov";
EXPECT_EQ(etk::fs::exist(path1), false);
EXPECT_EQ(etk::fs::exist(path2), false);
EXPECT_EQ(etk::fs::touch(path1), true);
EXPECT_EQ(etk::fs::exist(path1), true);
EXPECT_EQ(etk::fs::exist(path2), false);
EXPECT_EQ(etk::fs::move(path1, path2), true);
EXPECT_EQ(etk::fs::exist(path1), false);
EXPECT_EQ(etk::fs::exist(path2), true);
EXPECT_EQ(etk::fs::removeDirectories(pathRandom), true);
EXPECT_EQ(etk::fs::exist(pathRandom), false);
}
*/