#
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy is of the CDDL is also available via the Internet
#
#
# Copyright 2010 Chris Love. All rights reserved.
# Copyright (c) 2013, Joyent, Inc. All rights reserved.
#
{
local actual=$1
local output=$2
local test=$3
else
fi
}
#
# Test cases for 'tail', some based on CoreUtils test cases (validated
# 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).
#
DIR=""
while [[ $# -gt 0 ]]; do
case $1 in
-x)
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
if [[ $DIR != "" ]]; then
fi
o=`echo -e "bcd"`
o=`echo -e ""`
o=`echo -e "abcd"`
o=`echo -e "x"`
o=`echo -e "\n"`
o=`echo -e "y\n"`
o=`echo -e "y"`
o=`echo -e "x\ny\n"`
o=`echo -e "y\n"`
o=`echo -e "x"`
o=`echo -e "\n"`
o=`echo -e "y\n"`
o=`echo -e "y"`
o=`echo -e "x\ny\n"`
o=`echo -e "y\n"`
o=`echo -e "yyz"`
o=`echo -e "y\ny\nz"`
o=`echo -e "y\ny\ny\ny\ny\ny\ny\ny\ny\nz"`
#
# 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"`
o=`echo -e "y\ny\nz"`
o=`echo -e "y\ny\ny\ny\ny\ny\ny\ny\ny\nz"`
fi
o=`echo -e "c\nb\na"`
#
# 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
#
# First, verify that following works in its most basic sense.
#
echo -e "a\nb\nc" > $follow
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"`
#
# Now verify that following correctly follows the file being moved.
#
echo -e "a\nb\nc" > $follow
child=$!
sleep 2
echo -e "d\ne\nf" >> $moved
sleep 1
kill $child
sleep 1
o=`echo -e "a\nb\nc\nd\ne\nf\n"`
#
# And now truncation with the new offset being less than the old offset.
#
echo -e "a\nb\nc" > $follow
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"`
#
# And truncation with the new offset being greater than the old offset.
#
echo -e "a\nb\nc" > $follow
sleep 1
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"`
#
# Verify that we can follow the moved file and correctly see a truncation.
#
echo -e "a\nb\nc" > $follow
child=$!
sleep 2
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"`
#
# Verify that capital-F follow properly deals with truncation
#
echo -e "a\nb\nc" > $follow
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"`
#
# 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
child=$!
sleep 2
echo -e "x\ny\nz" >> $moved
#
# At this point, tail is polling on stat'ing the missing file; we need to
# be sure to sleep long enough after recreating it to know that it will pick
# it up.
#
echo -e "d\ne\nf" > $follow
sleep 5
kill $child
sleep 1
o=`echo -e "a\nb\nc\nd\ne\nf\n"`
#
# Verify that following two files works.
#
echo -e "one" > $follow
echo -e "two" > $moved
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,
# In this test, just make sure we see both files change.
o="one
==> $follow <==
two
==> $moved <==
==> $follow <==
three
==> $moved <==
four
==> $follow <==
five"
if [[ `uname -s` == "SunOS" ]]; then
#
# Use DTrace to truncate the file between the return from port_get()
# and the reassociation of the file object with the port, exposing
# any race conditions whereby FILE_TRUNC events are lost.
#
#pragma D option destructive
#pragma D option quiet
pid\$target::port_get:return
/++i == 5/
{
stop();
system("cat /dev/null > $follow");
system("prun %d", pid);
}
tick-1sec
{
system("echo %d >> $follow", j++);
}
tick-1sec
/j == 10/
{
exit(0);
}
EOF
o=`echo -e "0\n1\n2\n3\n5\n6\n7\n8\n9\n"`
#pragma D option destructive
#pragma D option quiet
pid\$target::port_get:return
/++i == 5/
{
stop();
system("mv $follow $moved");
system("cat /dev/null > $moved");
system("prun %d", pid);
}
tick-1sec
{
system("echo %d >> %s", j++,
i < 5 ? "$follow" : "$moved");
}
tick-1sec
/j == 10/
{
exit(0);
}
EOF
o=`echo -e "0\n1\n2\n3\n5\n6\n7\n8\n9\n"`
#
# Verify that -F will deal properly with the file being truncated
# not by truncation, but rather via an ftruncate() from logadm.
#
child=$!
echo -e "a\nb\nc\nd\ne\nf" >> $follow
sleep 2
echo -e "g\nh\ni" >> $follow
sleep 2
kill $child
sleep 1
o=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\n"`
fi
#
# We're now going to test that while we may miss output due to truncations
# occurring faster than tail can read, we don't ever repeat output.
#
tchild=$!
child=$!
sleep 10
kill $tchild
kill $child
o=1
echo "$CMD: completed"
exit $errs