aboutsummaryrefslogtreecommitdiff
path: root/tests/mventry
diff options
context:
space:
mode:
Diffstat (limited to 'tests/mventry')
-rw-r--r--tests/mventry/buildfile7
-rw-r--r--tests/mventry/driver.cxx49
-rw-r--r--tests/mventry/testscript245
3 files changed, 301 insertions, 0 deletions
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 <iostream>
+#include <system_error>
+
+#include <butl/path>
+#include <butl/utility> // operator<<(ostream, exception)
+#include <butl/filesystem>
+
+using namespace std;
+using namespace butl;
+
+// Usage: argv[0] <old-path> <new-path>
+//
+// 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<dir_path> (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
+}