From 5b1c20f2315cd7fc624ffd31abdcc03b409bfcb2 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Sat, 2 Jul 2016 17:21:54 +0300 Subject: Add cpfile() --- tests/cpfile/buildfile | 7 ++ tests/cpfile/driver.cxx | 182 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+) create mode 100644 tests/cpfile/buildfile create mode 100644 tests/cpfile/driver.cxx (limited to 'tests/cpfile') diff --git a/tests/cpfile/buildfile b/tests/cpfile/buildfile new file mode 100644 index 0000000..7d02738 --- /dev/null +++ b/tests/cpfile/buildfile @@ -0,0 +1,7 @@ +# file : tests/cpfile/buildfile +# copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +exe{driver}: cxx{driver} ../../butl/lib{butl} + +include ../../butl/ 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 +#include +#include +#include + +#include +#include + +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); +} -- cgit v1.1