From 8b5e3e0a8f9ec8852cf2f15dab53bfa4436bea87 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 9 Mar 2017 02:24:54 +0300 Subject: Add mventry(), mvfile() and mvdir() --- tests/mventry/buildfile | 7 ++ tests/mventry/driver.cxx | 49 ++++++++++ tests/mventry/testscript | 245 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 301 insertions(+) create mode 100644 tests/mventry/buildfile create mode 100644 tests/mventry/driver.cxx create mode 100644 tests/mventry/testscript (limited to 'tests/mventry') diff --git a/tests/mventry/buildfile b/tests/mventry/buildfile new file mode 100644 index 0000000..868a2f6 --- /dev/null +++ b/tests/mventry/buildfile @@ -0,0 +1,7 @@ +# file : tests/mventry/buildfile +# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +exe{driver}: cxx{driver} ../../butl/lib{butl} test{testscript} + +include ../../butl/ diff --git a/tests/mventry/driver.cxx b/tests/mventry/driver.cxx new file mode 100644 index 0000000..cf6099c --- /dev/null +++ b/tests/mventry/driver.cxx @@ -0,0 +1,49 @@ +// file : tests/mventry/driver.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include +#include + +#include +#include // operator<<(ostream, exception) +#include + +using namespace std; +using namespace butl; + +// Usage: argv[0] +// +// Rename a file, directory or symlink or move it to the specified directory. +// For the later case the destination path must have a trailing directory +// separator. If succeed then exits with the zero code, otherwise prints the +// error descriptions and exits with the one code. +// +int +main (int argc, const char* argv[]) +try +{ + assert (argc == 3); + + path from (argv[1]); + path to (argv[2]); + + cpflags fl (cpflags::overwrite_permissions | cpflags::overwrite_content); + + if (to.to_directory ()) + mventry_into (from, path_cast (move (to)), fl); + else + mventry (from, to, fl); + + return 0; +} +catch (const invalid_path& e) +{ + cerr << e << ": " << e.path << endl; + return 1; +} +catch (const system_error& e) +{ + cerr << e << endl; + return 1; +} diff --git a/tests/mventry/testscript b/tests/mventry/testscript new file mode 100644 index 0000000..0a0aaa0 --- /dev/null +++ b/tests/mventry/testscript @@ -0,0 +1,245 @@ +# file : tests/mventry/testscript +# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +: file +: +{ + : non-existing + : + $* a b 2>- == 1 + + : over + : + { + : non-existing + : + echo 'foo' >=a &!a; + $* a b &b; + cat b >'foo'; + test -f a == 1 + + : existing-file + : + echo 'foo' >=a &!a; + echo 'bar' >=b; + $* a b; + cat b >'foo'; + test -f a == 1 + + : existing-dir + : + echo 'foo' >=a; + mkdir b; + $* a b 2>- == 1 + } + + : to-dir + : + echo 'foo' >=a &!a; + mkdir b; + $* a b/ &b/a; + cat b/a >'foo'; + test -f a == 1 +} + +: dir +: +{ + : over + { + : non-existing + : + mkdir -p a/b &!a/b/ &!a/; + echo 'foo' >=a/c &!a/c; + $* a b &b/ &b/c &b/b/; + cat b/c >'foo'; + test -d b/b; + test -d a == 1 + + : empty-dir + : + mkdir -p a/b &!a/b/ &!a/; + echo 'foo' >=a/c &!a/c; + mkdir b; + $* a b &b/c &b/b/; + cat b/c >'foo'; + test -d b/b; + test -d a == 1 + + : non-empty-dir + : + mkdir -p a/b; + mkdir -p b/d; + $* a b 2>- == 1 + + : existing-file + : + mkdir a; + touch b; + $* a b 2>- == 1 + } + + : to-dir + : + mkdir a &!a/; + mkdir b; + $* a b/ &b/a/; + test -d b/a; + test -f a == 1 +} + +: symlink +: +: If we are not cross-testing let's test renaming symlynks from and over. On +: Windows that involves mklink command usability test. If we fail to create a +: trial link (say because we are running non-administrative console), then the +: test group will be silently skipped. +: +if ($test.target == $build.host) +{ + +if ($cxx.target.class != 'windows') + lns = ln -s a b + else + echo 'yes' >=a + if cmd /C 'mklink b a' >- 2>- &?b && cat b >'yes' + lns = cmd /C 'mklink b a' >- + end + end + + if! $empty($lns) + { + : file + : + { + : from + : + : Make sure that if source is a symlink it refers the same target after + : rename. + : + echo 'foo' >=a; + $lns; + $* b c &c; + test -f a; + test -f b == 1; + echo 'bar' >=a; + cat c >'bar' + + : to + : + : Make sure that if destination is a symlink it is get overwritten and it's + : target stays intact. + : + echo 'foo' >=a; + $lns &b; + echo 'bar' >=c &!c; + $* c b; + cat a >'foo'; + test -f c == 1; + echo 'baz' >=a; + cat b >'bar' + + : over-existing-dir + : + echo 'foo' >=a; + $lns &b; + mkdir c; + $* b c 2>- == 1 + } + + : dir + : + { + : from + : + : Make sure that if source is a symlink it refers the same target after + : rename. + : + mkdir -p a; + $lns; + $* b c &c; + touch a/b; + test -f c/b; + test -d b == 1 + + : to + : + : Make sure that if destination is a symlink it is get overwritten and + : it's target stays intact. + : + mkdir -p a; + $lns; + echo 'foo' >=c &!c; + $* c b &b; + cat b >'foo'; + test -d a; + test -f c == 1 + + : over-existing-dir + : + mkdir a; + $lns &b; + mkdir c; + $* b c 2>- == 1 + } + } +} + +: different-fs +: +: Note that nested tests may fail for cross-testing as the directory path will +: unlikelly be usable on both host (build2 driver) and target (test driver) +: platforms. +: +if! $empty($config.libbutl.test.rename.dir) +{ + wd = $config.libbutl.test.rename.dir/libbutl-rename + +rm -r -f $wd + +mkdir $wd + + : file + : + { + : over-non-existing + : + { + wd = "$wd/$@"; + mkdir -p $wd; + b = $wd/b; + + echo 'foo' >=a &!a; + $* a $b; + cat $b >'foo'; + test -f a == 1 + } + + : over-file + : + { + wd = "$wd/$@"; + mkdir -p $wd; + b = $wd/b; + + touch $b; + echo 'foo' >=a &!a; + $* a $b; + cat $b >'foo'; + test -f a == 1 + } + } + + : dir + : + : Test that renaming directory to different fs/drive expectedly fails. + : + { + wd = "$wd/$@"; + mkdir -p $wd; + b = $wd/b; + + mkdir a; + $* a $b 2>- == 1 + } + + -rm -r -f $wd +} -- cgit v1.1