diff options
Diffstat (limited to 'tests/cpfile/driver.cxx')
-rw-r--r-- | tests/cpfile/driver.cxx | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/tests/cpfile/driver.cxx b/tests/cpfile/driver.cxx new file mode 100644 index 0000000..669ac26 --- /dev/null +++ b/tests/cpfile/driver.cxx @@ -0,0 +1,182 @@ +// file : tests/cpfile/driver.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <string> +#include <cassert> +#include <fstream> +#include <system_error> + +#include <butl/path> +#include <butl/filesystem> + +using namespace std; +using namespace butl; + +static const char text1[] = "ABCDEF\nXYZ"; +static const char text2[] = "12345\nDEF"; +static const char text3[] = "XAB\r\n9"; + +static string +from_file (const path& f) +{ + ifstream ifs; + ifs.exceptions (fstream::badbit | fstream::failbit); + ifs.open (f.string (), ios::binary); + + string s; + getline (ifs, s, '\0'); + return s; +} + +static void +to_file (const path& f, const char* s) +{ + ofstream ofs; + ofs.exceptions (fstream::badbit | fstream::failbit); + ofs.open (f.string (), ios::binary); + ofs << s; +} + +int +main () +{ + dir_path td (dir_path::temp_directory () / dir_path ("butl-cpfile")); + + // Recreate the temporary directory (that possibly exists from the previous + // faulty run) for the test files. Delete the directory only if the test + // succeeds to simplify the failure research. + // + try_rmdir_r (td); + assert (try_mkdir (td) == mkdir_status::success); + + path from (td / path ("from")); + to_file (from, text1); + + permissions p (path_permissions (from)); + path_permissions (from, permissions::ru | permissions::xu); + + // Check that content and permissions of newly created destination file are + // the same as that ones of the source file. + // + path to (td / path ("to")); + cpfile (from, to, cpflags::none); + assert (from_file (to) == text1); + assert (path_permissions (to) == path_permissions (from)); + + // Check that permissions of an existent destination file stays intact if + // their overwrite is not requested. + // + path_permissions (to, p); + cpfile (from, to, cpflags::overwrite_content); + assert (from_file (to) == text1); + assert (path_permissions (to) == p); + + // Check that permissions of an existent destination file get overwritten if + // requested. + // + cpfile ( + from, to, cpflags::overwrite_content | cpflags::overwrite_permissions); + + assert (from_file (to) == text1); + assert (path_permissions (to) == path_permissions (from)); + + path_permissions (to, p); + path_permissions (from, p); + + try + { + cpfile (from, to, cpflags::none); + assert (false); + } + catch (const system_error&) + { + } + + // Copy to the directory. + // + dir_path sd (td / dir_path ("sub")); + assert (try_mkdir (sd) == mkdir_status::success); + + cpfile (from, sd, cpflags::none); + + assert (from_file (sd / path ("from")) == text1); + + // Check that a hard link to the destination file is preserved. + // + path hlink (td / path ("hlink")); + mkhardlink (to, hlink); + to_file (hlink, text1); + + to_file (from, text2); + cpfile (from, to, cpflags::overwrite_content); + + assert (from_file (hlink) == text2); + +#ifndef _WIN32 + + // Check that 'from' being a symbolic link is properly resolved. + // + path fslink (td / path ("fslink")); + mksymlink (from, fslink); + + cpfile (fslink, to, cpflags::overwrite_content); + + // Make sure 'to' is not a symbolic link to 'from' and from_file() just + // follows it. + // + assert (try_rmfile (from) == rmfile_status::success); + assert (from_file (to) == text2); + + // Check that 'to' being a symbolic link is properly resolved. + // + path tslink (td / path ("tslink")); + mksymlink (to, tslink); + + to_file (from, text3); + cpfile (from, tslink, cpflags::overwrite_content); + assert (from_file (to) == text3); + + // Check that permissions are properly overwritten when 'to' is a symbolic + // link. + // + to_file (from, text1); + path_permissions (from, permissions::ru | permissions::xu); + + cpfile ( + from, tslink, cpflags::overwrite_content | cpflags::overwrite_permissions); + + assert (from_file (to) == text1); + assert (path_permissions (to) == path_permissions (from)); + + path_permissions (to, p); + path_permissions (from, p); + + // Check that no-overwrite file copy fails even if 'to' symlink points to + // non-existent file. + // + assert (try_rmfile (to) == rmfile_status::success); + + try + { + cpfile (from, tslink, cpflags::none); + assert (false); + } + catch (const system_error&) + { + } + + // Check that copy fail if 'from' symlink points to non-existent file. + // + try + { + cpfile (tslink, from, cpflags::none); + assert (false); + } + catch (const system_error&) + { + } +#endif + + rmdir_r (td); +} |