summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorBernhard Voelker <mail@bernhard-voelker.de>2013-04-20 16:33:06 +0200
committerBernhard Voelker <mail@bernhard-voelker.de>2013-04-20 16:33:06 +0200
commitd461bfd2743547360793acd2118d4c08ad7b84a8 (patch)
tree6e81dc004be45e9dea0c7b469b7d98c9f0277950 /tests
parent1dd8a33169b69716c4a4b92dbe1bd99336d92b23 (diff)
downloadcoreutils-d461bfd2743547360793acd2118d4c08ad7b84a8.tar.xz
tail: let -f --retry wait for inaccessible files
The --retry option is indeed useful for both following modes by name and by file descriptor. The difference is that in the latter case, it is effective only during the initial open. As a regression of the implementation of the inotify support, tail -f --retry would immediately exit if the given file is inaccessible. * src/tail.c (usage): Change the description of the --retry option: remove the note that this option would mainly be useful when following by name. (main): Change diagnosing dubios uses of --retry option: when the --retry option is used without following, then issue a warning that this option is ignored; when it is used together with --follow=descriptor, then issue a warning that it is only effective for the initial open. Disable inotify also in the case when the initial open in tail_file() failed (which is the actual bug fix). * init.cfg (retry_delay_): Pass excess arguments to the test function. * tests/tail-2/retry.sh: Add new tests. * tests/local.mk (all_tests): Mention it. * doc/coreutils.texi (tail invocation): Enhance the documentation of the --retry option. Clarify the difference in tail's behavior regarding the --retry option when combined with the following modes name versus descriptor. * NEWS (Bug fixes): Mention the fix. Reported by Noel Morrison in: http://lists.gnu.org/archive/html/coreutils/2013-04/msg00003.html
Diffstat (limited to 'tests')
-rw-r--r--tests/local.mk1
-rw-r--r--tests/tail-2/retry.sh94
2 files changed, 95 insertions, 0 deletions
diff --git a/tests/local.mk b/tests/local.mk
index 0b019d951..f47da8d3a 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -390,6 +390,7 @@ all_tests = \
tests/misc/uniq-perf.sh \
tests/misc/xattr.sh \
tests/tail-2/wait.sh \
+ tests/tail-2/retry.sh \
tests/chmod/c-option.sh \
tests/chmod/equal-x.sh \
tests/chmod/equals.sh \
diff --git a/tests/tail-2/retry.sh b/tests/tail-2/retry.sh
new file mode 100644
index 000000000..71d101556
--- /dev/null
+++ b/tests/tail-2/retry.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+# Exercise tail's behavior regarding missing files with/without --retry.
+
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+# Function to check the expected line count in 'out'.
+# Called via retry_delay_(). Sleep some time - see retry_delay_() - if the
+# line count is still smaller than expected.
+wait4lines_ ()
+{
+ local delay=$1
+ local elc=$2 # Expected line count.
+ [ $( wc -l < out ) -ge $elc ] || { sleep $delay; return 1; }
+}
+
+# === Test:
+# Retry without --follow results in a warning.
+touch file
+tail --retry file > out 2>&1 || fail=1
+[ $( wc -l < out ) = 1 ] || fail=1
+grep -F 'tail: warning: --retry ignored' out || fail=1
+
+# === Test:
+# The same with a missing file: expect error message and exit 1.
+tail --retry missing > out 2>&1 && fail=1
+[ $( wc -l < out ) = 2 ] || fail=1
+grep -F 'tail: warning: --retry ignored' out || fail=1
+
+# === Test:
+# Ensure that "tail --retry --follow=name" waits for the file to appear.
+timeout 10 tail -s.1 --follow=name --retry missing >out 2>&1 & pid=$!
+retry_delay_ wait4lines_ .1 6 1 || fail=1 # Wait for "cannot open" error.
+echo "X" > missing || fail=1 # Write "X" into 'missing'.
+retry_delay_ wait4lines_ .1 6 3 || fail=1 # Wait for the expected output.
+kill $pid
+wait $pid
+# Expect 3 lines in the output file.
+[ $( wc -l < out ) = 3 ] || { fail=1; cat out; }
+grep -F 'cannot open' out || { fail=1; cat out; }
+grep -F 'has become accessible' out || { fail=1; cat out; }
+grep '^X$' out || { fail=1; cat out; }
+rm -f missing out || fail=1
+
+# === Test:
+# Ensure that "tail --retry --follow=descriptor" waits for the file to appear.
+# tail-8.21 failed at this (since the implementation of the inotify support).
+timeout 10 tail -s.1 --follow=descriptor --retry missing >out 2>&1 & pid=$!
+retry_delay_ wait4lines_ .1 6 2 || fail=1 # Wait for "cannot open" error.
+echo "X" > missing || fail=1 # Write "X" into 'missing'.
+retry_delay_ wait4lines_ .1 6 4 || fail=1 # Wait for the expected output.
+kill $pid
+wait $pid
+# Expect 4 lines in the output file.
+[ $( wc -l < out ) = 4 ] || { fail=1; cat out; }
+grep -F 'retry only effective for the initial open' out \
+ || { fail=1; cat out; }
+grep -F 'cannot open' out || { fail=1; cat out; }
+grep -F 'has appeared' out || { fail=1; cat out; }
+grep '^X$' out || { fail=1; cat out; }
+rm -f missing out || fail=1
+
+# === Test:
+# Ensure that --follow=descriptor (without --retry) does *not wait* for the
+# file to appear. Expect 2 lines in the output file ("cannot open" +
+# "no files remaining") and exit status 1.
+tail --follow=descriptor missing >out 2>&1 && fail=1
+[ $( wc -l < out ) = 2 ] || { fail=1; cat out; }
+grep -F 'cannot open' out || { fail=1; cat out; }
+grep -F 'no files remaining' out || { fail=1; cat out; }
+
+# === Test:
+# Likewise for --follow=name (without --retry).
+tail --follow=name missing >out 2>&1 && fail=1
+[ $( wc -l < out ) = 2 ] || { fail=1; cat out; }
+grep -F 'cannot open' out || { fail=1; cat out; }
+grep -F 'no files remaining' out || { fail=1; cat out; }
+
+Exit $fail