rsync.fns 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. #! /bin/sh
  2. # Copyright (C) 2001 by Martin Pool <mbp@samba.org>
  3. # General-purpose test functions for rsync.
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License version
  6. # 2 as published by the Free Software Foundation.
  7. #
  8. # This program is distributed in the hope that it will be useful, but
  9. # WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. # Lesser General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU Lesser General Public
  14. # License along with this program; if not, write to the Free Software
  15. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. tmpdir="$scratchdir"
  17. fromdir="$tmpdir/from"
  18. todir="$tmpdir/to"
  19. chkdir="$tmpdir/chk"
  20. # For itemized output:
  21. all_plus='+++++++++'
  22. allspace=' '
  23. dots='.....' # trailing dots after changes
  24. # Berkley's nice.
  25. PATH="$PATH:/usr/ucb"
  26. if diff -u "$srcdir/testsuite/rsync.fns" "$srcdir/testsuite/rsync.fns" >/dev/null 2>&1; then
  27. diffopt="-u"
  28. else
  29. diffopt="-c"
  30. fi
  31. HOME="$scratchdir"
  32. export HOME
  33. runtest() {
  34. echo $ECHO_N "Test $1: $ECHO_C"
  35. if eval "$2"
  36. then
  37. echo "$ECHO_T done."
  38. return 0
  39. else
  40. echo "$ECHO_T failed!"
  41. return 1
  42. fi
  43. }
  44. set_cp_destdir() {
  45. while test $# -gt 1; do
  46. shift
  47. done
  48. destdir="$1"
  49. }
  50. # Perform a "cp -p", making sure that timestamps are really the same,
  51. # even if the copy rounded microsecond times on the destination file.
  52. cp_touch() {
  53. cp -p "${@}" || test_fail "cp -p failed"
  54. if test $# -gt 2 -o -d "$2"; then
  55. set_cp_destdir "${@}" # sets destdir var
  56. while test $# -gt 1; do
  57. destname="$destdir/`basename $1`"
  58. touch -r "$destname" "$1" "$destname"
  59. shift
  60. done
  61. else
  62. touch -r "$2" "$1" "$2"
  63. fi
  64. }
  65. # Call this if you want to filter out verbose messages (-v or -vv) from
  66. # the output of an rsync run (whittling the output down to just the file
  67. # messages). This isn't needed if you use -i without -v.
  68. filter_outfile() {
  69. sed -e '/^building file list /d' \
  70. -e '/^sending incremental file list/d' \
  71. -e '/^created directory /d' \
  72. -e '/^done$/d' \
  73. -e '/ --whole-file$/d' \
  74. -e '/^total: /d' \
  75. -e '/^client charset: /d' \
  76. -e '/^server charset: /d' \
  77. -e '/^$/,$d' \
  78. <"$outfile" >"$outfile.new"
  79. mv "$outfile.new" "$outfile"
  80. }
  81. printmsg() {
  82. echo "$1"
  83. }
  84. rsync_ls_lR() {
  85. find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls" $TLS_ARGS
  86. }
  87. check_perms() {
  88. perms=`"$TOOLDIR/tls" "$1" | sed 's/^[-d]\(.........\).*/\1/'`
  89. if test $perms = $2; then
  90. return 0
  91. fi
  92. echo "permissions: $perms on $1"
  93. echo "should be: $2"
  94. test_fail "failed test $3"
  95. }
  96. rsync_getgroups() {
  97. "$TOOLDIR/getgroups"
  98. }
  99. ####################
  100. # Build test directories $todir and $fromdir, with $fromdir full of files.
  101. hands_setup() {
  102. # Clean before creation
  103. rm -rf "$fromdir"
  104. rm -rf "$todir"
  105. [ -d "$tmpdir" ] || mkdir "$tmpdir"
  106. [ -d "$fromdir" ] || mkdir "$fromdir"
  107. [ -d "$todir" ] || mkdir "$todir"
  108. # On some BSD systems, the umask affects the mode of created
  109. # symlinks, even though the mode apparently has no effect on how
  110. # the links behave in the future, and it cannot be changed using
  111. # chmod! rsync always sets its umask to 000 so that it can
  112. # accurately recreate permissions, but this script is probably run
  113. # with a different umask.
  114. # This causes a little problem that "ls -l" of the two will not be
  115. # the same. So, we need to set our umask before doing any creations.
  116. # set up test data
  117. touch "$fromdir/empty"
  118. mkdir "$fromdir/emptydir"
  119. # a hundred lines of text or so
  120. rsync_ls_lR "$srcdir" > "$fromdir/filelist"
  121. echo $ECHO_N "This file has no trailing lf$ECHO_C" > "$fromdir/nolf"
  122. umask 0
  123. ln -s nolf "$fromdir/nolf-symlink"
  124. umask 022
  125. cat "$srcdir"/*.c > "$fromdir/text"
  126. mkdir "$fromdir/dir"
  127. cp "$fromdir/text" "$fromdir/dir"
  128. mkdir "$fromdir/dir/subdir"
  129. echo some data > "$fromdir/dir/subdir/foobar.baz"
  130. mkdir "$fromdir/dir/subdir/subsubdir"
  131. if [ -r /etc ]; then
  132. ls -ltr /etc > "$fromdir/dir/subdir/subsubdir/etc-ltr-list"
  133. else
  134. ls -ltr / > "$fromdir/dir/subdir/subsubdir/etc-ltr-list"
  135. fi
  136. mkdir "$fromdir/dir/subdir/subsubdir2"
  137. if [ -r /bin ]; then
  138. ls -lt /bin > "$fromdir/dir/subdir/subsubdir2/bin-lt-list"
  139. else
  140. ls -lt / > "$fromdir/dir/subdir/subsubdir2/bin-lt-list"
  141. fi
  142. # echo testing head:
  143. # ls -lR "$srcdir" | head -10 || echo failed
  144. }
  145. ####################
  146. # Many machines do not have "mkdir -p", so we have to build up long paths.
  147. # How boring.
  148. makepath() {
  149. for p in "${@}"; do
  150. (echo " makepath $p"
  151. # Absolut Unix.
  152. if echo $p | grep '^/' >/dev/null
  153. then
  154. cd /
  155. fi
  156. # This will break if $p contains a space.
  157. for c in `echo $p | tr '/' ' '`
  158. do
  159. if [ -d "$c" ] || mkdir "$c"
  160. then
  161. cd "$c" || return $?
  162. else
  163. echo "failed to create $c" >&2; return $?
  164. fi
  165. done)
  166. done
  167. }
  168. ###########################
  169. # Run a test (in '$1') then compare directories $2 and $3 to see if
  170. # there are any difference. If there are, explain them.
  171. # So normally basically $1 should be an rsync command, and $2 and $3
  172. # the source and destination directories. This is only good when you
  173. # expect to transfer the whole directory exactly as is. If some files
  174. # should be excluded, you might need to use something else.
  175. checkit() {
  176. failed=
  177. # We can just write everything to stdout/stderr, because the
  178. # wrapper hides it unless there is a problem.
  179. echo "Running: \"$1\""
  180. eval "$1"
  181. status=$?
  182. if [ $status != 0 ]; then
  183. failed="YES";
  184. fi
  185. echo "-------------"
  186. echo "check how the directory listings compare with diff:"
  187. echo ""
  188. ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
  189. ( cd "$3" && rsync_ls_lR . ) > "$tmpdir/ls-to"
  190. diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to" || failed=YES
  191. echo "-------------"
  192. echo "check how the files compare with diff:"
  193. echo ""
  194. if [ "x$4" != x ]; then
  195. echo " === Skipping (as directed) ==="
  196. else
  197. diff -r $diffopt "$2" "$3" || failed=YES
  198. fi
  199. echo "-------------"
  200. if [ -z "$failed" ] ; then
  201. return 0
  202. else
  203. return 1
  204. fi
  205. }
  206. build_rsyncd_conf() {
  207. # Build an appropriate configuration file
  208. conf="$scratchdir/test-rsyncd.conf"
  209. echo "building configuration $conf"
  210. port=2612
  211. pidfile="$scratchdir/rsyncd.pid"
  212. logfile="$scratchdir/rsyncd.log"
  213. hostname=`uname -n`
  214. cat >"$conf" <<EOF
  215. # rsyncd configuration file autogenerated by $0
  216. pid file = $pidfile
  217. use chroot = no
  218. munge symlinks = no
  219. hosts allow = localhost 127.0.0.0/24 192.168.0.0/16 10.0.0.0/8 $hostname
  220. log file = $logfile
  221. log format = %i %h [%a] %m (%u) %l %f%L
  222. transfer logging = yes
  223. exclude = ? foobar.baz
  224. max verbosity = 9
  225. uid = 0
  226. gid = 0
  227. [test-from]
  228. path = $fromdir
  229. read only = yes
  230. comment = r/o
  231. [test-to]
  232. path = $todir
  233. read only = no
  234. comment = r/w
  235. [test-scratch]
  236. path = $scratchdir
  237. read only = no
  238. [test-hidden]
  239. path = $fromdir
  240. list = no
  241. EOF
  242. # Build a helper script to ignore exit code 23
  243. ignore23="$scratchdir/ignore23"
  244. echo "building help script $ignore23"
  245. cat >"$ignore23" <<'EOT'
  246. if "${@}"; then
  247. exit
  248. fi
  249. ret=$?
  250. if test $ret = 23; then
  251. exit
  252. fi
  253. exit $ret
  254. EOT
  255. chmod +x "$ignore23"
  256. }
  257. build_symlinks() {
  258. mkdir "$fromdir"
  259. date >"$fromdir/referent"
  260. ln -s referent "$fromdir/relative"
  261. ln -s "$fromdir/referent" "$fromdir/absolute"
  262. ln -s nonexistent "$fromdir/dangling"
  263. ln -s "$srcdir/rsync.c" "$fromdir/unsafe"
  264. }
  265. test_fail() {
  266. echo "$@" >&2
  267. exit 1
  268. }
  269. test_skipped() {
  270. echo "$@" >&2
  271. echo "$@" > "$tmpdir/whyskipped"
  272. exit 77
  273. }
  274. # It failed, but we expected that. don't dump out error logs,
  275. # because most users won't want to see them. But do leave
  276. # the working directory around.
  277. test_xfail() {
  278. echo "$@" >&2
  279. exit 78
  280. }
  281. # Determine what shell command will appropriately test for links.
  282. ln -s foo "$scratchdir/testlink"
  283. for cmd in test /bin/test /usr/bin/test /usr/ucb/bin/test /usr/ucb/test
  284. do
  285. for switch in -h -L
  286. do
  287. if $cmd $switch "$scratchdir/testlink" 2>/dev/null
  288. then
  289. # how nice
  290. TEST_SYMLINK_CMD="$cmd $switch"
  291. # i wonder if break 2 is portable?
  292. break 2
  293. fi
  294. done
  295. done
  296. # ok, now get rid of it
  297. rm "$scratchdir/testlink"
  298. if [ "x$TEST_SYMLINK_CMD" = 'x' ]
  299. then
  300. test_fail "Couldn't determine how to test for symlinks"
  301. else
  302. echo "Testing for symlinks using '$TEST_SYMLINK_CMD'"
  303. fi
  304. # Test whether something is a link, allowing for shell peculiarities
  305. is_a_link() {
  306. # note the variable contains the first option and therefore is not quoted
  307. $TEST_SYMLINK_CMD "$1"
  308. }
  309. # We need to set the umask to be reproducible. Note also that when we
  310. # do some daemon tests as root, we will setuid() and therefore the
  311. # directory has to be writable by the nobody user in some cases. The
  312. # best thing is probably to explicitly chmod those directories after
  313. # creation.
  314. umask 022