From 69d3b7af920cb2a02a692abca7402b59a1ea162c Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 10 Mar 2020 14:47:02 +0300 Subject: Fix directory symlink tests failing on Windows in Developer Mode --- libbutl/filesystem.mxx | 11 +--- tests/dir-iterator/testscript | 24 ++++----- tests/mventry/testscript | 120 ++++++++++++++++++++++-------------------- tests/path-entry/testscript | 34 +++++------- 4 files changed, 88 insertions(+), 101 deletions(-) diff --git a/libbutl/filesystem.mxx b/libbutl/filesystem.mxx index e83c666..186c9db 100644 --- a/libbutl/filesystem.mxx +++ b/libbutl/filesystem.mxx @@ -259,20 +259,13 @@ LIBBUTL_MODEXPORT namespace butl // (@@ TODO: At some point we may want to support creating directory // symlinks if possible and falling back to junctions otherwise. One // potential issue here is with relative target paths which the caller - // cannot rely on staying relative. Plus there is the below bug.) + // cannot rely on staying relative.) // // - Functions other than mksymlink() fully support symlinks, considering // the Windows file symlinks (file-type reparse points referring to files) // as regular file symlinks and the Windows directory symlinks (file-type // reparse points referring to directories) and junctions (directory-type - // reparse points referring to directories) as directory symlinks. The - // known issues are: - // - // - path_entry() call that follows a symlink (but not a junction) with a - // directory target may throw std::system_error due to the underlying - // CreateFile() function call failing with the ERROR_ACCESS_DENIED - // error. This appears to be a bug that has been noticed only on Windows - // with the Developer Mode enabled. + // reparse points referring to directories) as directory symlinks. // // Also note that symlinks are currently not supported properly on Wine due // to some differences in the underlying API behavior. diff --git a/tests/dir-iterator/testscript b/tests/dir-iterator/testscript index 720622f..ec7338d 100644 --- a/tests/dir-iterator/testscript +++ b/tests/dir-iterator/testscript @@ -24,11 +24,13 @@ $* a >"dir b" if ($test.target == $build.host) { +if ($cxx.target.class != 'windows') - lns = ln -s wd/t wd/l &wd/l + lnf = ln -s wd/t wd/l &wd/l + lnd = $lnf else echo 'yes' >=t if cmd /C 'mklink l t' >- 2>- &?l && cat l >'yes' - lns = cmd /C 'mklink wd\l t' &wd/l >- + lnf = cmd /C 'mklink wd\l t' &wd/l >- + lnd = cmd /C 'mklink /D wd\l t' &wd/l >- end jnc = cmd /C 'mklink /J wd\l wd\t' &wd/l >- @@ -36,7 +38,7 @@ if ($test.target == $build.host) : symlink : - if! $empty($lns) + if! $empty($lnf) { : file : @@ -44,7 +46,7 @@ if ($test.target == $build.host) +mkdir wd +touch --no-cleanup wd/t +touch wd/f - +$lns + +$lnf +$* wd >>~%EOO% %(reg f|reg t|sym reg l)%{3} EOO @@ -60,16 +62,10 @@ if ($test.target == $build.host) +mkdir wd +mkdir --no-cleanup wd/t +mkdir wd/d - +$lns - - # Note that this test may fail on Windows (see symlinks known issues in - # libbutl/filesystem.mxx). - # - +if ($cxx.target.class != 'windows') - $* wd >>~%EOO% - %(dir d|dir t|sym dir l)%{3} - EOO - end + +$lnd + +$* wd >>~%EOO% + %(dir d|dir t|sym dir l)%{3} + EOO +rmdir wd/t diff --git a/tests/mventry/testscript b/tests/mventry/testscript index c6cbf45..54a3acc 100644 --- a/tests/mventry/testscript +++ b/tests/mventry/testscript @@ -98,19 +98,21 @@ if ($test.target == $build.host) { +if ($cxx.target.class != 'windows') - lns = ln -s a b + lnf = ln -s t l &l + lnd = $lnf else - echo 'yes' >=a - if cmd /C 'mklink b a' >- 2>- &?b && cat b >'yes' - lns = cmd /C 'mklink b a' >- + echo 'yes' >=t + if cmd /C 'mklink l t' >- 2>- &?l && cat l >'yes' + lnf = cmd /C 'mklink l t' &l >- + lnd = cmd /C 'mklink /D l t' &l >- end - jnc = cmd /C 'mklink /J b a' >- + jnc = cmd /C 'mklink /J l t' &l >- end : symlink : - if! $empty($lns) + if! $empty($lnf) { : file : @@ -120,34 +122,34 @@ if ($test.target == $build.host) : Make sure that if source is a symlink it refers the same target after : rename. : - echo 'foo' >=a; - $lns &!b; - $* b c &c; - test -f a; - test -f b == 1; - echo 'bar' >=a; - cat c >'bar' + echo 'foo' >=t; + $lnf; + $* l ll &!l ≪ + test -f t; + test -f l == 1; + echo 'bar' >=t; + cat ll >'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' + echo 'foo' >=t; + $lnf; + echo 'bar' >=f; + $* f l &!f; + cat t >'foo'; + test -f f == 1; + echo 'baz' >=t; + cat l >'bar' : over-existing-dir : - echo 'foo' >=a; - $lns &b; - mkdir c; - $* b c 2>- == 1 + echo 'foo' >=t; + $lnf; + mkdir d; + $* t d 2>- == 1 } : dir @@ -158,32 +160,33 @@ if ($test.target == $build.host) : Make sure that if source is a symlink it refers the same target after : rename. : - mkdir -p a; - $lns &!b; - $* b c &c; - touch a/b; - test -f c/b; - test -d b == 1 + mkdir -p t; + $lnd; + $* l ll &!l ≪ + touch t/f; + test -f ll/f; + test -f l == 1; + test -d l == 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 + mkdir -p t; + $lnd; + echo 'foo' >=f; + $* f l &!f; + cat l >'foo'; + test -d t; + test -f f == 1 : over-existing-dir : - mkdir a; - $lns &b; - mkdir c; - $* b c 2>- == 1 + mkdir t; + $lnd; + mkdir d; + $* l d 2>- == 1 } } @@ -196,32 +199,33 @@ if ($test.target == $build.host) : Make sure that if source is a junction it refers the same target after : rename. : - mkdir -p a; - $jnc &!b; - $* b c &c; - touch a/b; - test -f c/b; - test -d b == 1 + mkdir -p t; + $jnc; + $* l ll &!l ≪ + touch t/f; + test -f ll/f; + test -f l == 1; + test -d l == 1 : to : : Make sure that if destination is a junction it is get overwritten and : it's target stays intact. : - mkdir -p a; + mkdir -p t; $jnc; - echo 'foo' >=c &!c; - $* c b &b; - cat b >'foo'; - test -d a; - test -f c == 1 + echo 'foo' >=f; + $* f l &!f; + cat l >'foo'; + test -d t; + test -f f == 1 : over-existing-dir : - mkdir a; - $jnc &b; - mkdir c; - $* b c 2>- == 1 + mkdir t; + $jnc; + mkdir d; + $* l d 2>- == 1 } } diff --git a/tests/path-entry/testscript b/tests/path-entry/testscript index 76316bf..0424dff 100644 --- a/tests/path-entry/testscript +++ b/tests/path-entry/testscript @@ -54,11 +54,13 @@ if ($test.target == $build.host) { +if ($cxx.target.class != 'windows') - lns = ln -s t l &l + lnf = ln -s t l &l + lnd = $lnf else echo 'yes' >=t if cmd /C 'mklink l t' >- 2>- &?l && cat l >'yes' - lns = cmd /C 'mklink l t' &l >- + lnf = cmd /C 'mklink l t' &l >- + lnd = cmd /C 'mklink /D l t' &l >- end jnc = cmd /C 'mklink /J l t' &l >- @@ -66,7 +68,7 @@ : symlink : - if! $empty($lns) + if! $empty($lnf) { : file : @@ -78,7 +80,7 @@ : { cat <:'abc' >=t; - $lns; + $lnf; $* -p 400 -m '2020-03-05 00:00:00' -a '2020-03-05 00:00:01' t | set ti; $* -l l >"$ti" } @@ -89,7 +91,7 @@ : { cat <:'abc' >=t; - $lns; + $lnf; $* -p 400 -m '2020-03-05 00:00:00' -a '2020-03-05 00:00:01' l | set ti; sed -n -e 's/permissions: (.+)/\1/p' <"$ti" >~/'4.{2}'/; sed -n -e 's/mtime: (.+)/\1/p' <"$ti" >'2020-03-05 00:00:00'; @@ -102,7 +104,7 @@ : { cat <:'abc' >=t; - $lns; + $lnf; $* t | set ti; sleep 2; $* -t l | set li; @@ -114,10 +116,6 @@ : dir : - : Note that the following tests may fail on Windows (see symlinks known - : issues in libbutl/filesystem.mxx). - : - if ($cxx.target.class != 'windows') { : get-info : @@ -126,10 +124,9 @@ : { mkdir t; - $lns; + $lnd; $* -p 400 -m '2020-03-05 00:00:00' -a '2020-03-05 00:00:01' t | set ti; - $* -l l >"$ti"; - $* -p 600 t >- # @@ TMP; until build2 is staged. + $* -l l >"$ti" } : set-info @@ -138,12 +135,11 @@ : { mkdir t; - $lns; + $lnd; $* -p 400 -m '2020-03-05 00:00:00' -a '2020-03-05 00:00:01' l | set ti; sed -n -e 's/permissions: (.+)/\1/p' <"$ti" >~/'4.{2}'/; sed -n -e 's/mtime: (.+)/\1/p' <"$ti" >'2020-03-05 00:00:00'; - sed -n -e 's/atime: (.+)/\1/p' <"$ti" >'2020-03-05 00:00:01'; - $* -p 600 t >- # @@ TMP; until build2 is staged. + sed -n -e 's/atime: (.+)/\1/p' <"$ti" >'2020-03-05 00:00:01' } } } @@ -161,8 +157,7 @@ mkdir t; $jnc; $* -p 400 -m '2020-03-05 00:00:00' -a '2020-03-05 00:00:01' t | set ti; - $* -l l >"$ti"; - $* -p 600 t >- # @@ TMP; until build2 is staged. + $* -l l >"$ti" } : set-info @@ -175,8 +170,7 @@ $* -p 400 -m '2020-03-05 00:00:00' -a '2020-03-05 00:00:01' l | set ti; sed -n -e 's/permissions: (.+)/\1/p' <"$ti" >~/'4.{2}'/; sed -n -e 's/mtime: (.+)/\1/p' <"$ti" >'2020-03-05 00:00:00'; - sed -n -e 's/atime: (.+)/\1/p' <"$ti" >'2020-03-05 00:00:01'; - $* -p 600 t >- # @@ TMP; until build2 is staged. + sed -n -e 's/atime: (.+)/\1/p' <"$ti" >'2020-03-05 00:00:01' } } } -- cgit v1.1