Print this page
3484 enhance and document tail follow support
Reviewed by: Joshua M. Clulow <jmc@joyent.com>

*** 11,141 **** # at http://www.illumos.org/license/CDDL. # # # Copyright 2010 Chris Love. All rights reserved. # # # Test cases for 'tail', some based on CoreUtils test cases (validated ! # with legacy Solaris 'tail' and/or xpg4 'tail') # PROG=/usr/bin/tail ! case $1 in -x) PROG=/usr/xpg4/bin/tail ;; -o) PROG=$2 ;; ! -?) ! echo "Usage: tailtests.sh [-x][-o <override tail executable>]" exit 1 ;; ! esac ! echo "Using $PROG" o=`echo -e "bcd"` a=`echo -e "abcd" | $PROG +2c` ! [[ "$a" != "$o" ]] && echo "Fail test 1 - $a" o=`echo -e ""` a=`echo "abcd" | $PROG +8c` ! [[ "$a" != "$o" ]] && echo "Fail test 2 - $a" o=`echo -e "abcd"` a=`echo "abcd" | $PROG -9c` ! [[ "$a" != "$o" ]] && echo "Fail test 3 - $a" o=`echo -e "x"` a=`echo -e "x" | $PROG -1l` ! [[ "$a" != "x" ]] && echo "Fail test 4 - $a" o=`echo -e "\n"` a=`echo -e "x\ny\n" | $PROG -1l` ! [[ "$a" != "$o" ]] && echo "Fail test 5 - $a" o=`echo -e "y\n"` a=`echo -e "x\ny\n" | $PROG -2l` ! [[ "$a" != "$o" ]] && echo "Fail test 6 - $a" o=`echo -e "y"` a=`echo -e "x\ny" | $PROG -1l` ! [[ "$a" != "$o" ]] && echo "Fail test 7 - $a" o=`echo -e "x\ny\n"` a=`echo -e "x\ny\n" | $PROG +1l` ! [[ "$a" != "$o" ]] && echo "Fail test 8 - $a" o=`echo -e "y\n"` a=`echo -e "x\ny\n" | $PROG +2l` ! [[ "$a" != "$o" ]] && echo "Fail test 9 - $a" o=`echo -e "x"` a=`echo -e "x" | $PROG -1` ! [[ "$a" != "$o" ]] && echo "Fail test 10 - $a" o=`echo -e "\n"` a=`echo -e "x\ny\n" | $PROG -1` ! [[ "$a" != "$o" ]] && echo "Fail test 11 - $a" o=`echo -e "y\n"` a=`echo -e "x\ny\n" | $PROG -2` ! [[ "$a" != "$o" ]] && echo "Fail test 12 - $a" o=`echo -e "y"` a=`echo -e "x\ny" | $PROG -1` ! [[ "$a" != "$o" ]] && echo "Fail test 13 - $a" o=`echo -e "x\ny\n"` a=`echo -e "x\ny\n" | $PROG +1` ! [[ "$a" != "$o" ]] && echo "Fail test 14 - $a" o=`echo -e "y\n"` a=`echo -e "x\ny\n" | $PROG +2` ! [[ "$a" != "$o" ]] && echo "Fail test 15 - $a" - # For compatibility with Legacy Solaris tail this should also work as '+c' o=`echo -e "yyz"` a=`echo -e "xyyyyyyyyyyz" | $PROG +10c` ! [[ "$a" != "$o" ]] && echo "Fail test 16 - $a" - o=`echo -e "yyz"` - a=`echo -e "xyyyyyyyyyyz" | $PROG +c` - [[ "$a" != "$o" ]] && echo "Fail test 16a - $a" - - - # For compatibility with Legacy Solaris tail this should also work as '+l' o=`echo -e "y\ny\nz"` a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG +10l` ! [[ "$a" != "$o" ]] && echo "Fail test 17 - $a" - o=`echo -e "y\ny\nz"` - a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG +l` - [[ "$a" != "$o" ]] && echo "Fail test 17a - $a" - - - # For compatibility with Legacy Solaris tail this should also work as '-l' o=`echo -e "y\ny\ny\ny\ny\ny\ny\ny\ny\nz"` a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG -10l` ! [[ "$a" != "$o" ]] && echo "Fail test 18 - $a" ! o=`echo -e "y\ny\ny\ny\ny\ny\ny\ny\ny\nz"` ! a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG -l` ! [[ "$a" != "$o" ]] && echo "Fail test 18a - $a" o=`echo -e "c\nb\na"` a=`echo -e "a\nb\nc" | $PROG -r` ! [[ "$a" != "$o" ]] && echo "Fail test 19 - $a" ! echo "Completed" ! exit 0 ! # Template for additional test cases ! #o=`echo -e ""` ! #a=`echo -e "" | $PROG ` ! #[[ "$a" != "$o" ]] && echo "Fail test - $a" --- 11,367 ---- # at http://www.illumos.org/license/CDDL. # # # Copyright 2010 Chris Love. All rights reserved. + # Copyright (c) 2013, Joyent, Inc. All rights reserved. # + checktest() + { + local actual=$1 + local output=$2 + local test=$3 + if [[ "$actual" != "$output" ]]; then + echo "$CMD: test $test: FAIL" + echo -e "$CMD: test $test: expected output:\n$o" + echo -e "$CMD: test $test: actual output:\n$a" + else + echo "$CMD: test $test: pass" + fi + } + # # Test cases for 'tail', some based on CoreUtils test cases (validated ! # with legacy Solaris 'tail' and/or xpg4 'tail'). Note that this is designed ! # to be able to run on BSD systems as well to check our behavior against ! # theirs (some behavior that is known to be idiosyncratic to illumos is ! # skipped on non-illumos systems). # PROG=/usr/bin/tail + CMD=`basename $0` + DIR="" ! while [[ $# -gt 0 ]]; do ! case $1 in -x) PROG=/usr/xpg4/bin/tail + shift ;; -o) PROG=$2 + shift 2 ;; ! -d) ! DIR=$2 ! shift 2 ! ;; ! *) ! echo "Usage: tailtests.sh" \ ! "[-x][-o <override tail executable>]" \ ! "[-d <override output directory>]" exit 1 ;; ! esac ! done ! # ! # Shut bash up upon receiving a term so we can drop it on our children ! # without disrupting the output. ! # ! trap "exit 0" TERM + echo "$CMD: program is $PROG" + + if [[ $DIR != "" ]]; then + echo "$CMD: directory is $DIR" + fi + o=`echo -e "bcd"` a=`echo -e "abcd" | $PROG +2c` ! checktest "$a" "$o" 1 o=`echo -e ""` a=`echo "abcd" | $PROG +8c` ! checktest "$a" "$o" 2 o=`echo -e "abcd"` a=`echo "abcd" | $PROG -9c` ! checktest "$a" "$o" 3 o=`echo -e "x"` a=`echo -e "x" | $PROG -1l` ! checktest "$a" "$o" 4 o=`echo -e "\n"` a=`echo -e "x\ny\n" | $PROG -1l` ! checktest "$a" "$o" 5 o=`echo -e "y\n"` a=`echo -e "x\ny\n" | $PROG -2l` ! checktest "$a" "$o" 6 o=`echo -e "y"` a=`echo -e "x\ny" | $PROG -1l` ! checktest "$a" "$o" 7 o=`echo -e "x\ny\n"` a=`echo -e "x\ny\n" | $PROG +1l` ! checktest "$a" "$o" 8 o=`echo -e "y\n"` a=`echo -e "x\ny\n" | $PROG +2l` ! checktest "$a" "$o" 9 o=`echo -e "x"` a=`echo -e "x" | $PROG -1` ! checktest "$a" "$o" 10 o=`echo -e "\n"` a=`echo -e "x\ny\n" | $PROG -1` ! checktest "$a" "$o" 11 o=`echo -e "y\n"` a=`echo -e "x\ny\n" | $PROG -2` ! checktest "$a" "$o" 12 o=`echo -e "y"` a=`echo -e "x\ny" | $PROG -1` ! checktest "$a" "$o" 13 o=`echo -e "x\ny\n"` a=`echo -e "x\ny\n" | $PROG +1` ! checktest "$a" "$o" 14 o=`echo -e "y\n"` a=`echo -e "x\ny\n" | $PROG +2` ! checktest "$a" "$o" 15 o=`echo -e "yyz"` a=`echo -e "xyyyyyyyyyyz" | $PROG +10c` ! checktest "$a" "$o" 16 o=`echo -e "y\ny\nz"` a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG +10l` ! checktest "$a" "$o" 17 o=`echo -e "y\ny\ny\ny\ny\ny\ny\ny\ny\nz"` a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG -10l` ! checktest "$a" "$o" 18 ! # ! # For reasons that are presumably as accidental as they are ancient, legacy ! # (and closed) Solaris tail(1) allows +c, +l and -l to be aliases for +10c, ! # +10l and -10l, respectively. If we are on SunOS, verify that this silly ! # behavior is functional. ! # ! if [[ `uname -s` == "SunOS" ]]; then ! o=`echo -e "yyz"` ! a=`echo -e "xyyyyyyyyyyz" | $PROG +c` ! checktest "$a" "$o" 16a + o=`echo -e "y\ny\nz"` + a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG +l` + checktest "$a" "$o" 17a + + o=`echo -e "y\ny\ny\ny\ny\ny\ny\ny\ny\nz"` + a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG -l` + checktest "$a" "$o" 18a + fi + o=`echo -e "c\nb\na"` a=`echo -e "a\nb\nc" | $PROG -r` ! checktest "$a" "$o" 19 + # + # Now we want to do a series of follow tests. + # + if [[ $DIR == "" ]]; then + tdir=$(mktemp -d -t tailtest.XXXXXXXX || exit 1) + else + tdir=$(mktemp -d $DIR/tailtest.XXXXXXXX || exit 1) + fi ! follow=$tdir/follow ! moved=$tdir/follow.moved ! out=$tdir/out ! # ! # First, verify that following works in its most basic sense. ! # ! echo -e "a\nb\nc" > $follow ! $PROG -f $follow > $out 2> /dev/null & ! child=$! ! sleep 2 ! echo -e "d\ne\nf" >> $follow ! sleep 1 ! kill $child ! sleep 1 ! o=`echo -e "a\nb\nc\nd\ne\nf\n"` ! a=`cat $out` ! checktest "$a" "$o" 20 ! rm $follow ! ! # ! # Now verify that following correctly follows the file being moved. ! # ! echo -e "a\nb\nc" > $follow ! $PROG -f $follow > $out 2> /dev/null & ! child=$! ! sleep 2 ! mv $follow $moved ! ! echo -e "d\ne\nf" >> $moved ! sleep 1 ! kill $child ! sleep 1 ! ! o=`echo -e "a\nb\nc\nd\ne\nf\n"` ! a=`cat $out` ! checktest "$a" "$o" 21 ! rm $moved ! ! # ! # And now truncation with the new offset being less than the old offset. ! # ! echo -e "a\nb\nc" > $follow ! $PROG -f $follow > $out 2> /dev/null & ! child=$! ! sleep 2 ! echo -e "d\ne\nf" >> $follow ! sleep 1 ! echo -e "g\nh\ni" > $follow ! sleep 1 ! kill $child ! sleep 1 ! ! o=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\n"` ! a=`cat $out` ! checktest "$a" "$o" 22 ! rm $follow ! ! # ! # And truncation with the new offset being greater than the old offset. ! # ! echo -e "a\nb\nc" > $follow ! sleep 1 ! $PROG -f $follow > $out 2> /dev/null & ! child=$! ! sleep 2 ! echo -e "d\ne\nf" >> $follow ! sleep 1 ! echo -e "g\nh\ni\nj\nk\nl\nm\no\np\nq" > $follow ! sleep 1 ! kill $child ! sleep 1 ! ! o=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\no\np\nq"` ! a=`cat $out` ! checktest "$a" "$o" 23 ! rm $follow ! ! # ! # Verify that we can follow the moved file and correctly see a truncation. ! # ! echo -e "a\nb\nc" > $follow ! $PROG -f $follow > $out 2> /dev/null & ! child=$! ! sleep 2 ! mv $follow $moved ! ! echo -e "d\ne\nf" >> $moved ! sleep 1 ! echo -e "g\nh\ni\nj\nk\nl\nm\no\np\nq" > $moved ! sleep 1 ! kill $child ! sleep 1 ! ! o=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\no\np\nq"` ! a=`cat $out` ! checktest "$a" "$o" 24 ! rm $moved ! ! # ! # Verify that capital-F follow properly deals with truncation ! # ! echo -e "a\nb\nc" > $follow ! $PROG -F $follow > $out 2> /dev/null & ! child=$! ! sleep 2 ! echo -e "d\ne\nf" >> $follow ! sleep 1 ! echo -e "g\nh\ni" > $follow ! sleep 1 ! kill $child ! sleep 1 ! ! o=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\n"` ! a=`cat $out` ! checktest "$a" "$o" 25 ! rm $follow ! ! # ! # Verify that capital-F follow _won't_ follow the moved file and will ! # correctly deal with recreation of the original file. ! # ! echo -e "a\nb\nc" > $follow ! $PROG -F $follow > $out 2> /dev/null & ! child=$! ! sleep 2 ! mv $follow $moved ! ! echo -e "x\ny\nz" >> $moved ! echo -e "d\ne\nf" > $follow ! sleep 1 ! kill $child ! sleep 1 ! ! o=`echo -e "a\nb\nc\nd\ne\nf\n"` ! a=`cat $out` ! checktest "$a" "$o" 26 ! rm $moved ! ! # ! # Verify that following two files works. ! # ! echo -e "one" > $follow ! echo -e "two" > $moved ! $PROG -f $follow $moved > $out 2> /dev/null & ! child=$! ! sleep 2 ! echo -e "three" >> $follow ! sleep 1 ! echo -e "four" >> $moved ! sleep 1 ! echo -e "five" >> $follow ! sleep 1 ! kill $child ! sleep 1 ! ! # There is a bug where the content comes before the header lines, ! # where rlines/mapprint happens before the header. A pain to fix. ! # In this test, just make sure we see both files change. ! o="one ! ! ==> $follow <== ! two ! ! ==> $moved <== ! ! ==> $follow <== ! three ! ! ==> $moved <== ! four ! ! ==> $follow <== ! five" ! a=`cat $out` ! checktest "$a" "$o" 27 ! rm $follow $moved ! ! echo "$CMD: completed" ! ! exit $errs !