1 #!/bin/bash 2 # 3 # 4 # This file and its contents are supplied under the terms of the 5 # Common Development and Distribution License ("CDDL"), version 1.0. 6 # You may only use this file in accordance with the terms of version 7 # 1.0 of the CDDL. 8 # 9 # A full copy of the text of the CDDL should have accompanied this 10 # source. A copy is of the CDDL is also available via the Internet 11 # at http://www.illumos.org/license/CDDL. 12 # 13 14 # 15 # Copyright 2010 Chris Love. All rights reserved. 16 # Copyright (c) 2013, Joyent, Inc. All rights reserved. 17 # 18 19 checktest() 20 { 21 local actual=$1 22 local output=$2 23 local test=$3 24 25 if [[ "$actual" != "$output" ]]; then 26 echo "$CMD: test $test: FAIL" 27 echo -e "$CMD: test $test: expected output:\n$o" 28 echo -e "$CMD: test $test: actual output:\n$a" 29 else 30 echo "$CMD: test $test: pass" 31 fi 32 } 33 34 # 35 # Test cases for 'tail', some based on CoreUtils test cases (validated 36 # with legacy Solaris 'tail' and/or xpg4 'tail'). Note that this is designed 37 # to be able to run on BSD systems as well to check our behavior against 38 # theirs (some behavior that is known to be idiosyncratic to illumos is 39 # skipped on non-illumos systems). 40 # 41 PROG=/usr/bin/tail 42 CMD=`basename $0` 43 DIR="" 44 45 while [[ $# -gt 0 ]]; do 46 case $1 in 47 -x) 48 PROG=/usr/xpg4/bin/tail 49 shift 50 ;; 51 -o) 52 PROG=$2 53 shift 2 54 ;; 55 -d) 56 DIR=$2 57 shift 2 58 ;; 59 *) 60 echo "Usage: tailtests.sh" \ 61 "[-x][-o <override tail executable>]" \ 62 "[-d <override output directory>]" 63 exit 1 64 ;; 65 esac 66 done 67 68 # 69 # Shut bash up upon receiving a term so we can drop it on our children 70 # without disrupting the output. 71 # 72 trap "exit 0" TERM 73 74 echo "$CMD: program is $PROG" 75 76 if [[ $DIR != "" ]]; then 77 echo "$CMD: directory is $DIR" 78 fi 79 80 o=`echo -e "bcd"` 81 a=`echo -e "abcd" | $PROG +2c` 82 checktest "$a" "$o" 1 83 84 o=`echo -e ""` 85 a=`echo "abcd" | $PROG +8c` 86 checktest "$a" "$o" 2 87 88 o=`echo -e "abcd"` 89 a=`echo "abcd" | $PROG -9c` 90 checktest "$a" "$o" 3 91 92 o=`echo -e "x"` 93 a=`echo -e "x" | $PROG -1l` 94 checktest "$a" "$o" 4 95 96 o=`echo -e "\n"` 97 a=`echo -e "x\ny\n" | $PROG -1l` 98 checktest "$a" "$o" 5 99 100 o=`echo -e "y\n"` 101 a=`echo -e "x\ny\n" | $PROG -2l` 102 checktest "$a" "$o" 6 103 104 o=`echo -e "y"` 105 a=`echo -e "x\ny" | $PROG -1l` 106 checktest "$a" "$o" 7 107 108 o=`echo -e "x\ny\n"` 109 a=`echo -e "x\ny\n" | $PROG +1l` 110 checktest "$a" "$o" 8 111 112 o=`echo -e "y\n"` 113 a=`echo -e "x\ny\n" | $PROG +2l` 114 checktest "$a" "$o" 9 115 116 o=`echo -e "x"` 117 a=`echo -e "x" | $PROG -1` 118 checktest "$a" "$o" 10 119 120 o=`echo -e "\n"` 121 a=`echo -e "x\ny\n" | $PROG -1` 122 checktest "$a" "$o" 11 123 124 o=`echo -e "y\n"` 125 a=`echo -e "x\ny\n" | $PROG -2` 126 checktest "$a" "$o" 12 127 128 o=`echo -e "y"` 129 a=`echo -e "x\ny" | $PROG -1` 130 checktest "$a" "$o" 13 131 132 o=`echo -e "x\ny\n"` 133 a=`echo -e "x\ny\n" | $PROG +1` 134 checktest "$a" "$o" 14 135 136 o=`echo -e "y\n"` 137 a=`echo -e "x\ny\n" | $PROG +2` 138 checktest "$a" "$o" 15 139 140 o=`echo -e "yyz"` 141 a=`echo -e "xyyyyyyyyyyz" | $PROG +10c` 142 checktest "$a" "$o" 16 143 144 o=`echo -e "y\ny\nz"` 145 a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG +10l` 146 checktest "$a" "$o" 17 147 148 o=`echo -e "y\ny\ny\ny\ny\ny\ny\ny\ny\nz"` 149 a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG -10l` 150 checktest "$a" "$o" 18 151 152 # 153 # For reasons that are presumably as accidental as they are ancient, legacy 154 # (and closed) Solaris tail(1) allows +c, +l and -l to be aliases for +10c, 155 # +10l and -10l, respectively. If we are on SunOS, verify that this silly 156 # behavior is functional. 157 # 158 if [[ `uname -s` == "SunOS" ]]; then 159 o=`echo -e "yyz"` 160 a=`echo -e "xyyyyyyyyyyz" | $PROG +c` 161 checktest "$a" "$o" 16a 162 163 o=`echo -e "y\ny\nz"` 164 a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG +l` 165 checktest "$a" "$o" 17a 166 167 o=`echo -e "y\ny\ny\ny\ny\ny\ny\ny\ny\nz"` 168 a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG -l` 169 checktest "$a" "$o" 18a 170 fi 171 172 o=`echo -e "c\nb\na"` 173 a=`echo -e "a\nb\nc" | $PROG -r` 174 checktest "$a" "$o" 19 175 176 # 177 # Now we want to do a series of follow tests. 178 # 179 if [[ $DIR == "" ]]; then 180 tdir=$(mktemp -d -t tailtest.XXXXXXXX || exit 1) 181 else 182 tdir=$(mktemp -d $DIR/tailtest.XXXXXXXX || exit 1) 183 fi 184 185 follow=$tdir/follow 186 moved=$tdir/follow.moved 187 out=$tdir/out 188 189 # 190 # First, verify that following works in its most basic sense. 191 # 192 echo -e "a\nb\nc" > $follow 193 $PROG -f $follow > $out 2> /dev/null & 194 child=$! 195 sleep 2 196 echo -e "d\ne\nf" >> $follow 197 sleep 1 198 kill $child 199 sleep 1 200 201 o=`echo -e "a\nb\nc\nd\ne\nf\n"` 202 a=`cat $out` 203 checktest "$a" "$o" 20 204 rm $follow 205 206 # 207 # Now verify that following correctly follows the file being moved. 208 # 209 echo -e "a\nb\nc" > $follow 210 $PROG -f $follow > $out 2> /dev/null & 211 child=$! 212 sleep 2 213 mv $follow $moved 214 215 echo -e "d\ne\nf" >> $moved 216 sleep 1 217 kill $child 218 sleep 1 219 220 o=`echo -e "a\nb\nc\nd\ne\nf\n"` 221 a=`cat $out` 222 checktest "$a" "$o" 21 223 rm $moved 224 225 # 226 # And now truncation with the new offset being less than the old offset. 227 # 228 echo -e "a\nb\nc" > $follow 229 $PROG -f $follow > $out 2> /dev/null & 230 child=$! 231 sleep 2 232 echo -e "d\ne\nf" >> $follow 233 sleep 1 234 echo -e "g\nh\ni" > $follow 235 sleep 1 236 kill $child 237 sleep 1 238 239 o=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\n"` 240 a=`cat $out` 241 checktest "$a" "$o" 22 242 rm $follow 243 244 # 245 # And truncation with the new offset being greater than the old offset. 246 # 247 echo -e "a\nb\nc" > $follow 248 sleep 1 249 $PROG -f $follow > $out 2> /dev/null & 250 child=$! 251 sleep 2 252 echo -e "d\ne\nf" >> $follow 253 sleep 1 254 echo -e "g\nh\ni\nj\nk\nl\nm\no\np\nq" > $follow 255 sleep 1 256 kill $child 257 sleep 1 258 259 o=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\no\np\nq"` 260 a=`cat $out` 261 checktest "$a" "$o" 23 262 rm $follow 263 264 # 265 # Verify that we can follow the moved file and correctly see a truncation. 266 # 267 echo -e "a\nb\nc" > $follow 268 $PROG -f $follow > $out 2> /dev/null & 269 child=$! 270 sleep 2 271 mv $follow $moved 272 273 echo -e "d\ne\nf" >> $moved 274 sleep 1 275 echo -e "g\nh\ni\nj\nk\nl\nm\no\np\nq" > $moved 276 sleep 1 277 kill $child 278 sleep 1 279 280 o=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\no\np\nq"` 281 a=`cat $out` 282 checktest "$a" "$o" 24 283 rm $moved 284 285 # 286 # Verify that capital-F follow properly deals with truncation 287 # 288 echo -e "a\nb\nc" > $follow 289 $PROG -F $follow > $out 2> /dev/null & 290 child=$! 291 sleep 2 292 echo -e "d\ne\nf" >> $follow 293 sleep 1 294 echo -e "g\nh\ni" > $follow 295 sleep 1 296 kill $child 297 sleep 1 298 299 o=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\n"` 300 a=`cat $out` 301 checktest "$a" "$o" 25 302 rm $follow 303 304 # 305 # Verify that capital-F follow _won't_ follow the moved file and will 306 # correctly deal with recreation of the original file. 307 # 308 echo -e "a\nb\nc" > $follow 309 $PROG -F $follow > $out 2> /dev/null & 310 child=$! 311 sleep 2 312 mv $follow $moved 313 314 echo -e "x\ny\nz" >> $moved 315 echo -e "d\ne\nf" > $follow 316 sleep 1 317 kill $child 318 sleep 1 319 320 o=`echo -e "a\nb\nc\nd\ne\nf\n"` 321 a=`cat $out` 322 checktest "$a" "$o" 26 323 rm $moved 324 325 # 326 # Verify that following two files works. 327 # 328 echo -e "one" > $follow 329 echo -e "two" > $moved 330 $PROG -f $follow $moved > $out 2> /dev/null & 331 child=$! 332 sleep 2 333 echo -e "three" >> $follow 334 sleep 1 335 echo -e "four" >> $moved 336 sleep 1 337 echo -e "five" >> $follow 338 sleep 1 339 kill $child 340 sleep 1 341 342 # There is a bug where the content comes before the header lines, 343 # where rlines/mapprint happens before the header. A pain to fix. 344 # In this test, just make sure we see both files change. 345 o="one 346 347 ==> $follow <== 348 two 349 350 ==> $moved <== 351 352 ==> $follow <== 353 three 354 355 ==> $moved <== 356 four 357 358 ==> $follow <== 359 five" 360 a=`cat $out` 361 checktest "$a" "$o" 27 362 rm $follow $moved 363 364 echo "$CMD: completed" 365 366 exit $errs 367