[patch] Two problems in testsuite (POSIX, perms)

Brian Poole raj at cerias.purdue.edu
Tue Jan 21 16:12:01 EST 2003


Hello,

Noticed a couple of problems with the rsync testsuite. I have included
a possible patch for each problem (attached & inlined.) 

The first problem is that on OpenBSD when make test is run and tests 
are skipped you see messages like this:

cat: "/tmp/rsync-2/rsync/testtmp.chown/whyskipped": No such file or directory
SKIP    chown ()

After my patch, you get the appropriate output:

SKIP    chown (Can't chown (probably need root))

The problem that you might notice if you have had your coffee already
this morning is that it is attempting to cat the file WITH quotations.

The line that causes the problem is line 233 of runtests.sh:

        echo "SKIP    $testbase (`cat \"$scratchdir/whyskipped\"`)"

This is a POSIXLY_CORRECT behavior on part of the OpenBSD sh according
to the sh man page which has a specific section on it:

     o   Occurrences of \" inside double quoted `..` command substitutions.
         In POSIX mode, the \" is interpreted when the command is interpreted;
         in non-POSIX mode, the backslash is stripped before the command sub-
         stitution is interpreted.  For example, echo "`echo \"hi\"`" produces
         ``"hi"'' in POSIX mode, ``hi'' in non-POSIX mode.  To avoid problems,
         use the $(...) form of command substitution.

(readable at http://www.openbsd.org/cgi-bin/man.cgi?query=sh)

I worked around the problem by using the suggested $(...) form. Quick
testing showed it worked here on sh/zsh/bash so I assume this is the 
correct way to do it. If not, one could also do the assignment before 
the echo and then simply echo a $reason variable in the string.


The second problem is that the daemon-gzip-upload test fails if run 
as root. This is alluded to in the rsync.fns file:

# We need to set the umask to be reproducible.  Note also that when we
# do some daemon tests as root, we will setuid() and therefore the
# directory has to be writable by the nobody user in some cases.  The
# best thing is probably to explicitly chmod those directories after
# creation.

I would guess the best thing to do is to chown the test directories 
to the UID of the rsyncd server when running as root but I'm not 
really sure what is considered best by others though. 

Regardless, if the test can't be run as root and pass (which it can't
because the rsyncd will not have permission to write to the directory
that root just created) then it should skip the test for root. I have
added a patch to implement the chown method as a possible fix (as it
is certainly preferable if the test would actually test what its 
supposed to.)

The failure is not seen in the builds as the build farm machines 
rarely (hopefully never) ever run as root. 


-b

Index: runtests.sh
===================================================================
RCS file: /cvsroot/rsync/runtests.sh,v
retrieving revision 1.33
diff -u -r1.33 runtests.sh
--- runtests.sh	26 Mar 2002 01:25:48 -0000	1.33
+++ runtests.sh	21 Jan 2003 16:06:42 -0000
@@ -100,6 +100,10 @@
 # You cannot do "export VAR=VALUE" all on one line; the export must be
 # separate from the assignment.  (SCO SysV)
 
+# echo "stuff: `cat \"$file\"`" is not POSIX compliant and some shells
+# will attempt to cat the file '"file"', preserving the double 
+# quotes. Use echo "stuff: $(cat "$file")" instead. (OpenBSD)
+
 
 
 # STILL TO DO:
@@ -144,6 +148,8 @@
 
 testuser=`whoami || echo UNKNOWN`
 
+export testuser
+
 echo "    testuser=$testuser"
 echo "    os=`uname -a`"
 
@@ -230,7 +236,7 @@
 	;;
     77)
 	# backticks will fill the whole file onto one line, which is a feature
-	echo "SKIP    $testbase (`cat \"$scratchdir/whyskipped\"`)"
+	echo "SKIP    $testbase ($(cat "$scratchdir/whyskipped"))"
 	skipped=`expr $skipped + 1`
 	maybe_discard_scratch
 	;;
Index: testsuite/daemon-gzip-upload.test
===================================================================
RCS file: /cvsroot/rsync/testsuite/daemon-gzip-upload.test,v
retrieving revision 1.2
diff -u -r1.2 daemon-gzip-upload.test
--- testsuite/daemon-gzip-upload.test	24 Dec 2002 07:25:25 -0000	1.2
+++ testsuite/daemon-gzip-upload.test	21 Jan 2003 16:06:42 -0000
@@ -21,5 +21,14 @@
 export RSYNC_CONNECT_PROG
 
 hands_setup
+
+# If we are root, we must allow the rsyncd process (which runs under
+# a different uid/gid) to write to the destination directory. Source
+# directory must be chown'ed as well so that UIDs & GIDs match when 
+# the source & destination are compared after copying.
+if [ "$testuser" = "root" ]; then
+	chown -R $UID:$GID "$FROM" "$TO"
+fi
+
 checkit "$RSYNC -avvz \"$FROM/\" localhost::test-to/" "$FROM" "$TO"
 
Index: testsuite/rsync.fns
===================================================================
RCS file: /cvsroot/rsync/testsuite/rsync.fns,v
retrieving revision 1.50
diff -u -r1.50 rsync.fns
--- testsuite/rsync.fns	10 Jan 2003 15:06:10 -0000	1.50
+++ testsuite/rsync.fns	21 Jan 2003 16:06:42 -0000
@@ -24,6 +24,13 @@
 LOG=${TMP}/log
 RSYNC="$rsync_bin"
 
+# UID & GID to run rsyncd as if testsuite is running as root
+#
+# We don't know if this machine has "nobody" or "nogroup", so use the
+# quasi-canonical values of (uint16_t) -2. 
+UID=65534
+GID=65534
+
 # Berkley's nice.
 PATH="$PATH:/usr/ucb"
 
@@ -191,11 +198,8 @@
 hosts allow = localhost, 127.0.0.1
 log file = $logfile
 
-# We don't know if this machine has "nobody" or "nogroup", so use the quasi-canonical
-# values of (uint16_t) -2. 
-
-uid = 65534
-gid = 65534
+uid = $UID 
+gid = $GID 
 
 [test-from]
 	path = $FROM
-------------- next part --------------
Index: runtests.sh
===================================================================
RCS file: /cvsroot/rsync/runtests.sh,v
retrieving revision 1.33
diff -u -r1.33 runtests.sh
--- runtests.sh	26 Mar 2002 01:25:48 -0000	1.33
+++ runtests.sh	21 Jan 2003 16:06:42 -0000
@@ -100,6 +100,10 @@
 # You cannot do "export VAR=VALUE" all on one line; the export must be
 # separate from the assignment.  (SCO SysV)
 
+# echo "stuff: `cat \"$file\"`" is not POSIX compliant and some shells
+# will attempt to cat the file '"file"', preserving the double 
+# quotes. Use echo "stuff: $(cat "$file")" instead. (OpenBSD)
+
 
 
 # STILL TO DO:
@@ -144,6 +148,8 @@
 
 testuser=`whoami || echo UNKNOWN`
 
+export testuser
+
 echo "    testuser=$testuser"
 echo "    os=`uname -a`"
 
@@ -230,7 +236,7 @@
 	;;
     77)
 	# backticks will fill the whole file onto one line, which is a feature
-	echo "SKIP    $testbase (`cat \"$scratchdir/whyskipped\"`)"
+	echo "SKIP    $testbase ($(cat "$scratchdir/whyskipped"))"
 	skipped=`expr $skipped + 1`
 	maybe_discard_scratch
 	;;
Index: testsuite/daemon-gzip-upload.test
===================================================================
RCS file: /cvsroot/rsync/testsuite/daemon-gzip-upload.test,v
retrieving revision 1.2
diff -u -r1.2 daemon-gzip-upload.test
--- testsuite/daemon-gzip-upload.test	24 Dec 2002 07:25:25 -0000	1.2
+++ testsuite/daemon-gzip-upload.test	21 Jan 2003 16:06:42 -0000
@@ -21,5 +21,14 @@
 export RSYNC_CONNECT_PROG
 
 hands_setup
+
+# If we are root, we must allow the rsyncd process (which runs under
+# a different uid/gid) to write to the destination directory. Source
+# directory must be chown'ed as well so that UIDs & GIDs match when 
+# the source & destination are compared after copying.
+if [ "$testuser" = "root" ]; then
+	chown -R $UID:$GID "$FROM" "$TO"
+fi
+
 checkit "$RSYNC -avvz \"$FROM/\" localhost::test-to/" "$FROM" "$TO"
 
Index: testsuite/rsync.fns
===================================================================
RCS file: /cvsroot/rsync/testsuite/rsync.fns,v
retrieving revision 1.50
diff -u -r1.50 rsync.fns
--- testsuite/rsync.fns	10 Jan 2003 15:06:10 -0000	1.50
+++ testsuite/rsync.fns	21 Jan 2003 16:06:42 -0000
@@ -24,6 +24,13 @@
 LOG=${TMP}/log
 RSYNC="$rsync_bin"
 
+# UID & GID to run rsyncd as if testsuite is running as root
+#
+# We don't know if this machine has "nobody" or "nogroup", so use the
+# quasi-canonical values of (uint16_t) -2. 
+UID=65534
+GID=65534
+
 # Berkley's nice.
 PATH="$PATH:/usr/ucb"
 
@@ -191,11 +198,8 @@
 hosts allow = localhost, 127.0.0.1
 log file = $logfile
 
-# We don't know if this machine has "nobody" or "nogroup", so use the quasi-canonical
-# values of (uint16_t) -2. 
-
-uid = 65534
-gid = 65534
+uid = $UID 
+gid = $GID 
 
 [test-from]
 	path = $FROM


More information about the rsync mailing list