Library: also create unique temporary files
...using the same method for sake of uniformity Also move the permissions helpers to the file.hpp support functions and setup a separate unit test for these
This commit is contained in:
parent
a1832b1cb9
commit
18b1d37a3d
6 changed files with 206 additions and 52 deletions
|
|
@ -78,6 +78,33 @@ namespace std::filesystem {
|
|||
fs::canonical(rawPath))
|
||||
: rawPath;
|
||||
}
|
||||
|
||||
|
||||
/** check if the denoted path \a p has at least the given permissions */
|
||||
inline bool
|
||||
has_perm (fs::path const& p, fs::perms permissionMask)
|
||||
{
|
||||
return (fs::status(p).permissions() & permissionMask) == permissionMask;
|
||||
}
|
||||
|
||||
/** check if the owner has read permissions on the denoted file or directory */
|
||||
inline bool
|
||||
can_read (fs::path const& p)
|
||||
{
|
||||
return has_perm (p, fs::perms::owner_read);
|
||||
}
|
||||
|
||||
inline bool
|
||||
can_write (fs::path const& p)
|
||||
{
|
||||
return has_perm (p, fs::perms::owner_write);
|
||||
}
|
||||
|
||||
inline bool
|
||||
can_exec (fs::path const& p)
|
||||
{
|
||||
return has_perm (p, fs::perms::owner_exec);
|
||||
}
|
||||
}//(End)namespace fs
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,9 +37,12 @@
|
|||
#include "lib/stat/file.hpp"
|
||||
#include "include/limits.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
//#include <unordered_map>
|
||||
//#include <iostream>
|
||||
//#include <vector>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
//#include <map>
|
||||
|
||||
|
|
@ -50,30 +53,12 @@ namespace test{
|
|||
namespace error = lumiera::error;
|
||||
|
||||
using util::_Fmt;
|
||||
using util::isnil;
|
||||
using std::string;
|
||||
|
||||
namespace {
|
||||
Literal TEMPFILE_PREFIX = "Lux";
|
||||
}
|
||||
inline bool
|
||||
has_perm (fs::path const& p, fs::perms permissionMask)
|
||||
{
|
||||
return (fs::status(p).permissions() & permissionMask) == permissionMask;
|
||||
}
|
||||
inline bool
|
||||
can_read (fs::path const& p)
|
||||
{
|
||||
return has_perm (p, fs::perms::owner_read);
|
||||
}
|
||||
inline bool
|
||||
can_write (fs::path const& p)
|
||||
{
|
||||
return has_perm (p, fs::perms::owner_write);
|
||||
}
|
||||
inline bool
|
||||
can_exec (fs::path const& p)
|
||||
{
|
||||
return has_perm (p, fs::perms::owner_exec);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -101,9 +86,20 @@ namespace test{
|
|||
}
|
||||
|
||||
fs::path
|
||||
makeFile()
|
||||
makeFile (string name ="")
|
||||
{
|
||||
UNIMPLEMENTED ("make temporary file");
|
||||
if (isnil (name))
|
||||
return establishNewFile (string{TEMPFILE_PREFIX});
|
||||
|
||||
auto newFile = loc_ / name;
|
||||
if (fs::exists (newFile))
|
||||
return establishNewFile (name);
|
||||
|
||||
std::ofstream{newFile};
|
||||
if (fs::exists (newFile) and fs::is_empty(newFile))
|
||||
return newFile;
|
||||
//
|
||||
throw error::Fatal{_Fmt{"Failed to create unique new file %s in TempDir."} % newFile};
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -127,6 +123,26 @@ namespace test{
|
|||
% LUMIERA_MAX_COMPETITION
|
||||
,error::LUMIERA_ERROR_SAFETY_LIMIT };
|
||||
}
|
||||
|
||||
fs::path
|
||||
establishNewFile (string prefix)
|
||||
{
|
||||
for (uint attempt=0; attempt<LUMIERA_MAX_COMPETITION; ++attempt)
|
||||
{
|
||||
auto randName = prefix + "." + util::showHash (entropyGen.u64());
|
||||
auto newPath = loc_ / randName;
|
||||
// attempt to create it....
|
||||
if (fs::exists(newPath))
|
||||
continue;
|
||||
std::ofstream{newPath};
|
||||
if (fs::exists(newPath) and fs::is_empty (newPath))
|
||||
return newPath; // success!
|
||||
}
|
||||
throw error::Fatal{_Fmt{"Failed to create unique new file at %s after %d attempts."}
|
||||
% loc_ % LUMIERA_MAX_COMPETITION
|
||||
,error::LUMIERA_ERROR_SAFETY_LIMIT };
|
||||
}
|
||||
|
||||
void
|
||||
destroyTempDirectory()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -180,6 +180,11 @@ return: 0
|
|||
END
|
||||
|
||||
|
||||
PLANNED "Filesystem manipulations" FileSupport_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
||||
TEST "formatting/string conversion in output" FormatCOUT_test <<END
|
||||
out-lit: Type: int ......
|
||||
out-lit: is_StringLike<int> : No
|
||||
|
|
|
|||
124
tests/library/stat/file-support-test.cpp
Normal file
124
tests/library/stat/file-support-test.cpp
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
FileSupport(Test) - verify additional filesystem helpers
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2024, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
/** @file file-support-test.cpp
|
||||
** unit test \ref FileSupport_test
|
||||
*/
|
||||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/test/temp-dir.hpp"
|
||||
#include "lib/stat/file.hpp"
|
||||
//#include "lib/time/timevalue.hpp"
|
||||
//#include "lib/error.hpp"
|
||||
//#include "lib/util-foreach.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
#include "lib/test/diagnostic-output.hpp"
|
||||
|
||||
//#include <boost/algorithm/string.hpp>
|
||||
#include <fstream>
|
||||
//#include <functional>
|
||||
//#include <string>
|
||||
|
||||
//using util::for_each;
|
||||
//using lumiera::Error;
|
||||
//using lumiera::LUMIERA_ERROR_EXCEPTION;
|
||||
//using lumiera::error::LUMIERA_ERROR_ASSERTION;
|
||||
//using lib::time::TimeVar;
|
||||
//using lib::time::Time;
|
||||
|
||||
//using boost::algorithm::is_lower;
|
||||
//using boost::algorithm::is_digit;
|
||||
//using std::function;
|
||||
//using std::string;
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace stat{
|
||||
namespace test{
|
||||
|
||||
using lib::test::TempDir;
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************//**
|
||||
* @test verify supplemental helper functions for file-handling support,
|
||||
* provided to complement the C++ `<filesystem>` library.
|
||||
* @see file.hpp
|
||||
* @see TempDir_test
|
||||
*/
|
||||
class FileSupport_test : public Test
|
||||
{
|
||||
void
|
||||
run (Arg)
|
||||
{
|
||||
simplifiedPermissionAccess();
|
||||
homedirectoryExpansion();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
simplifiedPermissionAccess()
|
||||
{
|
||||
TempDir temp;
|
||||
SHOW_EXPR(temp)
|
||||
SHOW_EXPR(fs::path{temp})
|
||||
fs::path f = temp.makeFile("Lumiera.nix");
|
||||
SHOW_EXPR(f);
|
||||
SHOW_EXPR(fs::exists(f));
|
||||
std::ofstream out{f};
|
||||
SHOW_EXPR(fs::exists(f));
|
||||
SHOW_EXPR(fs::status(f).permissions())
|
||||
SHOW_EXPR(fs::has_perm(temp, fs::perms::owner_read));
|
||||
SHOW_EXPR(fs::has_perm(temp, fs::perms::owner_write));
|
||||
SHOW_EXPR(fs::has_perm(temp, fs::perms::owner_exec));
|
||||
SHOW_EXPR(fs::has_perm(temp, fs::perms::owner_all));
|
||||
SHOW_EXPR(fs::has_perm(temp, fs::perms::group_read));
|
||||
SHOW_EXPR(fs::has_perm(temp, fs::perms::group_write));
|
||||
SHOW_EXPR(fs::has_perm(temp, fs::perms::group_exec));
|
||||
SHOW_EXPR(fs::has_perm(temp, fs::perms::group_all));
|
||||
SHOW_EXPR(fs::has_perm(temp, fs::perms::others_read));
|
||||
SHOW_EXPR(fs::has_perm(temp, fs::perms::others_write));
|
||||
SHOW_EXPR(fs::has_perm(temp, fs::perms::others_exec));
|
||||
SHOW_EXPR(fs::has_perm(temp, fs::perms::others_all));
|
||||
SHOW_EXPR(fs::has_perm(temp, fs::perms::all));
|
||||
SHOW_EXPR(fs::can_read(temp));
|
||||
SHOW_EXPR(fs::can_write(temp));
|
||||
SHOW_EXPR(fs::can_exec(temp));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @test prints "sizeof()" including some type name. */
|
||||
void
|
||||
homedirectoryExpansion ()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
LAUNCHER (FileSupport_test, "unit common");
|
||||
|
||||
|
||||
}}} // namespace lib::stat::test
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
TempDir(Test) - verify automated temporary working directory
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, Hermann Vosseler <Ichthyostega@web.de>
|
||||
2024, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
|
@ -79,24 +79,6 @@ namespace test{
|
|||
simpleUsage()
|
||||
{
|
||||
TempDir temp;
|
||||
SHOW_EXPR(temp)
|
||||
SHOW_EXPR(fs::path{temp})
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::owner_read));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::owner_write));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::owner_exec));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::owner_all));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::group_read));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::group_write));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::group_exec));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::group_all));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::others_read));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::others_write));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::others_exec));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::others_all));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::all));
|
||||
SHOW_EXPR(can_read(temp));
|
||||
SHOW_EXPR(can_write(temp));
|
||||
SHOW_EXPR(can_exec(temp));
|
||||
auto ff = temp.makeFile();
|
||||
CHECK (fs::exists (ff));
|
||||
CHECK (fs::is_empty (ff));
|
||||
|
|
|
|||
|
|
@ -57246,14 +57246,15 @@
|
|||
<node CREATED="1710185838462" ID="ID_1494325621" MODIFIED="1710185847781" TEXT="modelliert als RAII"/>
|
||||
<node CREATED="1710185850649" ID="ID_507946689" MODIFIED="1710185923149" TEXT="erzeugt einen zufälligen Namen"/>
|
||||
</node>
|
||||
<node CREATED="1710185930891" ID="ID_406086033" MODIFIED="1710185934026" TEXT="Implementierung">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1710185930891" ID="ID_406086033" MODIFIED="1710280179518" TEXT="Implementierung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1710185934990" ID="ID_1561994557" LINK="https://stackoverflow.com/a/58454949" MODIFIED="1710186020053" TEXT="Ausgangspunkt: Lösung von Stackoverflow"/>
|
||||
<node COLOR="#338800" CREATED="1710186086663" ID="ID_206197040" MODIFIED="1710269456216" TEXT="Zufallserzeugung extrahiert">
|
||||
<arrowlink COLOR="#752d90" DESTINATION="ID_588494337" ENDARROW="Default" ENDINCLINATION="33;-54;" ID="Arrow_ID_353980881" STARTARROW="None" STARTINCLINATION="-193;18;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710188183049" ID="ID_91824274" MODIFIED="1710188192430" TEXT="Allokation">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1710188183049" ID="ID_91824274" MODIFIED="1710280175554" TEXT="Allokation">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1710262702973" ID="ID_18843364" MODIFIED="1710266321814" TEXT="Semantik von fs::create_directory ist nicht klar">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1710262728032" ID="ID_1183825932" LINK="https://en.cppreference.com/w/cpp/filesystem/create_directory" MODIFIED="1710262791786">
|
||||
|
|
@ -57266,8 +57267,7 @@
|
|||
Verstehe die Doku so: wenn directory existiert ⟹ <b>kein</b> Fehler
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1710262793847" ID="ID_921510496" LINK="https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html" MODIFIED="1710262817664" TEXT="Doku verweist auf POSIX mkdir()">
|
||||
<node CREATED="1710262820691" ID="ID_715729723" MODIFIED="1710262853435" TEXT="dieses erzeugt Fehler EEXIST"/>
|
||||
|
|
@ -57279,8 +57279,7 @@
|
|||
<body>
|
||||
if -1 is returned, no directory shall be created.
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<node CREATED="1710262914300" ID="ID_1769904987" MODIFIED="1710262918682" TEXT="naja... nicht wirklich"/>
|
||||
<node CREATED="1710262919166" ID="ID_156263596" MODIFIED="1710262926049" TEXT="es existiert, wurde aber nicht created"/>
|
||||
</node>
|
||||
|
|
@ -57331,8 +57330,7 @@
|
|||
⟹ <font size="5" color="#ca0992">JAGNI</font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1710269734115" ID="ID_536611603" MODIFIED="1710269883844" TEXT="Zufallszahl als Hex">
|
||||
|
|
@ -57347,8 +57345,7 @@
|
|||
die gestern implementierte Zufalls-Sequenz <font face="Monospaced" color="#2216ba">entropyGen.u64()</font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1710269833165" ID="ID_1640785265" MODIFIED="1710269871853" TEXT="das util::showHash() von vor zwei Monaten">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
|
|
@ -57379,6 +57376,9 @@
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710188193120" ID="ID_988204568" MODIFIED="1710188200824" TEXT="Destruktion">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1710280159637" ID="ID_1031094481" MODIFIED="1710280171203" TEXT="Eindeutige Dateien dort erzeugen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1710269985121" ID="ID_1475343702" MODIFIED="1710269987814" TEXT="Test">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1710269988763" ID="ID_1423252413" LINK="#ID_992572632" MODIFIED="1710270061936" TEXT="Test für TempDir">
|
||||
|
|
|
|||
Loading…
Reference in a new issue