1# SPDX-License-Identifier: BSD-2-Clause 2# 3# Copyright (c) 2016 Alan Somers 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24# SUCH DAMAGE. 25# 26# $FreeBSD$ 27 28atf_test_case empty_r 29empty_r_head() 30{ 31 atf_set "descr" "Reverse an empty file" 32} 33empty_r_body() 34{ 35 touch infile expectfile 36 tail -r infile > outfile 37 tail -r < infile > outpipe 38 atf_check cmp expectfile outfile 39 atf_check cmp expectfile outpipe 40} 41 42atf_test_case file_r 43file_r_head() 44{ 45 atf_set "descr" "Reverse a file" 46} 47file_r_body() 48{ 49 cat > infile <<HERE 50This is the first line 51This is the second line 52This is the third line 53HERE 54 cat > expectfile << HERE 55This is the third line 56This is the second line 57This is the first line 58HERE 59 tail -r infile > outfile 60 tail -r < infile > outpipe 61 atf_check cmp expectfile outfile 62 atf_check cmp expectfile outpipe 63} 64 65atf_test_case file_rn2 66file_rn2_head() 67{ 68 atf_set "descr" "Reverse the last two lines of a file" 69} 70file_rn2_body() 71{ 72 cat > infile <<HERE 73This is the first line 74This is the second line 75This is the third line 76HERE 77 cat > expectfile << HERE 78This is the third line 79This is the second line 80HERE 81 tail -rn2 infile > outfile 82 tail -rn2 < infile > outpipe 83 atf_check cmp expectfile outfile 84 atf_check cmp expectfile outpipe 85} 86 87# Regression test for PR 222671 88# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=222671 89atf_test_case pipe_leading_newline_r 90pipe_leading_newline_r_head() 91{ 92 atf_set "descr" "Reverse a pipe whose first character is a newline" 93} 94pipe_leading_newline_r_body() 95{ 96 cat > expectfile << HERE 973 982 991 100 101HERE 102 printf '\n1\n2\n3\n' | tail -r > outfile 103 printf '\n1\n2\n3\n' | tail -r > outpipe 104 atf_check cmp expectfile outfile 105 atf_check cmp expectfile outpipe 106} 107 108atf_test_case file_rc28 109file_rc28_head() 110{ 111 atf_set "descr" "Reverse a file and display the last 28 characters" 112} 113file_rc28_body() 114{ 115 cat > infile <<HERE 116This is the first line 117This is the second line 118This is the third line 119HERE 120 cat > expectfile << HERE 121This is the third line 122line 123HERE 124 tail -rc28 infile > outfile 125 tail -rc28 < infile > outpipe 126 atf_check cmp expectfile outfile 127 atf_check cmp expectfile outpipe 128} 129 130atf_test_case file_rc28 131file_rc28_head() 132{ 133 atf_set "descr" "Reverse a file and display the last 28 characters" 134} 135file_rc28_body() 136{ 137 cat > infile <<HERE 138This is the first line 139This is the second line 140This is the third line 141HERE 142 cat > expectfile << HERE 143This is the third line 144line 145HERE 146 tail -rc28 infile > outfile 147 tail -rc28 < infile > outpipe 148 atf_check cmp expectfile outfile 149 atf_check cmp expectfile outpipe 150} 151 152atf_test_case longfile_r 153longfile_r_head() 154{ 155 atf_set "descr" "Reverse a long file" 156} 157longfile_r_body() 158{ 159 jot -w "%0511d" 1030 0 > infile 160 jot -w "%0511d" 1030 1029 0 -1 > expectfile 161 tail -r infile > outfile 162 tail -r < infile > outpipe 163 atf_check cmp expectfile outfile 164 atf_check cmp expectfile outpipe 165} 166 167atf_test_case longfile_r_enomem 168longfile_r_enomem_head() 169{ 170 atf_set "descr" "Reverse a file that's too long to store in RAM" 171} 172longfile_r_enomem_body() 173{ 174 # When we reverse a file that's too long for RAM, tail should drop the 175 # first part and just print what it can. We'll check that the last 176 # part is ok 177 { 178 ulimit -v 32768 || atf_skip "Can't adjust ulimit" 179 jot -w "%01023d" 32768 0 | tail -r > outfile ; 180 } 181 if [ "$?" -ne 1 ]; then 182 atf_skip "Didn't get ENOMEM. Adjust test parameters" 183 fi 184 # We don't know how much of the input we dropped. So just check that 185 # the first ten lines of tail's output are the same as the last ten of 186 # the input 187 jot -w "%01023d" 10 32767 0 -1 > expectfile 188 head -n 10 outfile > outtrunc 189 diff expectfile outtrunc 190 atf_check cmp expectfile outtrunc 191} 192 193atf_test_case longfile_r_longlines 194longfile_r_longlines_head() 195{ 196 atf_set "descr" "Reverse a long file with extremely long lines" 197} 198longfile_r_longlines_body() 199{ 200 jot -s " " -w "%07d" 18000 0 > infile 201 jot -s " " -w "%07d" 18000 18000 >> infile 202 jot -s " " -w "%07d" 18000 36000 >> infile 203 jot -s " " -w "%07d" 18000 36000 > expectfile 204 jot -s " " -w "%07d" 18000 18000 >> expectfile 205 jot -s " " -w "%07d" 18000 0 >> expectfile 206 tail -r infile > outfile 207 tail -r < infile > outpipe 208 atf_check cmp expectfile outfile 209 atf_check cmp expectfile outpipe 210} 211 212atf_test_case longfile_rc135782 213longfile_rc135782_head() 214{ 215 atf_set "descr" "Reverse a long file and print the last 135,782 bytes" 216} 217longfile_rc135782_body() 218{ 219 jot -w "%063d" 9000 0 > infile 220 jot -w "%063d" 2121 8999 0 -1 > expectfile 221 echo "0000000000000000000000000000000006878" >> expectfile 222 tail -rc135782 infile > outfile 223 tail -rc135782 < infile > outpipe 224 atf_check cmp expectfile outfile 225 atf_check cmp expectfile outpipe 226} 227 228atf_test_case longfile_rc145782_longlines 229longfile_rc145782_longlines_head() 230{ 231 atf_set "descr" "Reverse a long file with extremely long lines and print the last 145,782 bytes" 232} 233longfile_rc145782_longlines_body() 234{ 235 jot -s " " -w "%07d" 18000 0 > infile 236 jot -s " " -w "%07d" 18000 18000 >> infile 237 jot -s " " -w "%07d" 18000 36000 >> infile 238 jot -s " " -w "%07d" 18000 36000 > expectfile 239 echo -n "35777 " >> expectfile 240 jot -s " " -w "%07d" 222 35778 >> expectfile 241 tail -rc145782 infile > outfile 242 tail -rc145782 < infile > outpipe 243 atf_check cmp expectfile outfile 244 atf_check cmp expectfile outpipe 245} 246 247atf_test_case longfile_rn2500 248longfile_rn2500_head() 249{ 250 atf_set "descr" "Reverse a long file and print the last 2,500 lines" 251} 252longfile_rn2500_body() 253{ 254 jot -w "%063d" 9000 0 > infile 255 jot -w "%063d" 2500 8999 0 -1 > expectfile 256 tail -rn2500 infile > outfile 257 tail -rn2500 < infile > outpipe 258 atf_check cmp expectfile outfile 259 atf_check cmp expectfile outpipe 260} 261 262atf_test_case broken_pipe 263broken_pipe_head() 264{ 265 atf_set "descr" "Do not print bogus errno based output on short writes" 266} 267broken_pipe_body() 268{ 269 atf_check -o save:ints seq -f '%128g' 1 1000 270 atf_check -s ignore \ 271 -e "inline:tail: stdout\nexit code: 1\n" \ 272 -x '(tail -n 856 ints; echo exit code: $? >&2) | sleep 2' 273} 274 275atf_test_case stdin 276stdin_head() 277{ 278 atf_set "descr" "Check basic operations on standard input" 279} 280stdin_body() 281{ 282 seq 1 5 > infile 283 seq 1 5 > expectfile 284 seq 5 1 > expectfile_r 285 286 tail < infile > outfile 287 tail -r < infile > outfile_r 288 289 atf_check cmp expectfile outfile 290 atf_check cmp expectfile_r outfile_r 291} 292 293atf_test_case follow 294follow_head() 295{ 296 atf_set "descr" "Basic regression test for -f" 297} 298follow_body() 299{ 300 local pid 301 302 seq 1 5 > expectfile 303 seq 1 3 > infile 304 tail -f infile > outfile & 305 pid=$! 306 sleep 0.1 307 seq 4 5 >> infile 308 sleep 0.1 309 atf_check cmp expectfile outfile 310 atf_check kill $pid 311} 312 313atf_test_case follow_stdin 314follow_stdin_head() 315{ 316 atf_set "descr" "Verify that -f works with files piped to standard input" 317} 318follow_stdin_body() 319{ 320 local pid 321 322 seq 1 5 > expectfile 323 seq 1 3 > infile 324 tail -f < infile > outfile & 325 pid=$! 326 sleep 0.1 327 seq 4 5 >> infile 328 sleep 0.1 329 atf_check cmp expectfile outfile 330 atf_check kill $pid 331} 332 333atf_test_case follow_rename 334follow_rename_head() 335{ 336 atf_set "descr" "Verify that -F works" 337} 338follow_rename_body() 339{ 340 local pid 341 342 seq 1 5 > expectfile 343 seq 1 3 > infile 344 tail -F infile > outfile & 345 pid=$! 346 seq 4 5 > infile_new 347 atf_check mv infile infile_old 348 atf_check mv infile_new infile 349 # tail -F polls for a new file every 1s. 350 sleep 2 351 atf_check cmp expectfile outfile 352 atf_check kill $pid 353} 354 355atf_test_case silent_header 356silent_header_head() { 357 atf_set "descr" "Test tail(1)'s silent header feature" 358} 359silent_header_body() { 360 jot 11 1 11 > file1 361 jot 11 2 12 > file2 362 jot 10 2 11 > expectfile 363 jot 10 3 12 >> expectfile 364 tail -q file1 file2 > outfile 365 atf_check cmp outfile expectfile 366} 367 368atf_test_case verbose_header 369verbose_header_head() { 370 atf_set "descr" "Test tail(1)'s verbose header feature" 371} 372verbose_header_body() { 373 jot 11 1 11 > file1 374 echo '==> file1 <==' > expectfile 375 jot 10 2 11 >> expectfile 376 tail -v file1 > outfile 377 atf_check cmp outfile expectfile 378} 379 380atf_test_case si_number 381si_number_head() { 382 atf_set "descr" "Test tail(1)'s SI number feature" 383} 384si_number_body() { 385 jot -b aaaaaaa 129 > file1 386 jot -b aaaaaaa 128 > expectfile 387 tail -c 1k file1 > outfile 388 atf_check cmp outfile expectfile 389 jot 1025 1 1025 > file1 390 jot 1024 2 1025 > expectfile 391 tail -n 1k file1 > outfile 392 atf_check cmp outfile expectfile 393} 394 395atf_test_case no_lf_at_eof 396no_lf_at_eof_head() 397{ 398 atf_set "descr" "File does not end in newline" 399} 400no_lf_at_eof_body() 401{ 402 printf "a\nb\nc" >infile 403 atf_check -o inline:"c" tail -1 infile 404 atf_check -o inline:"b\nc" tail -2 infile 405 atf_check -o inline:"a\nb\nc" tail -3 infile 406 atf_check -o inline:"a\nb\nc" tail -4 infile 407} 408 409atf_init_test_cases() 410{ 411 atf_add_test_case empty_r 412 atf_add_test_case file_r 413 atf_add_test_case file_rc28 414 atf_add_test_case file_rn2 415 atf_add_test_case pipe_leading_newline_r 416 # The longfile tests are designed to exercise behavior in r_buf(), 417 # which operates on 128KB blocks 418 atf_add_test_case longfile_r 419 atf_add_test_case longfile_r_enomem 420 atf_add_test_case longfile_r_longlines 421 atf_add_test_case longfile_rc135782 422 atf_add_test_case longfile_rc145782_longlines 423 atf_add_test_case longfile_rn2500 424 atf_add_test_case broken_pipe 425 atf_add_test_case stdin 426 atf_add_test_case follow 427 atf_add_test_case follow_stdin 428 atf_add_test_case follow_rename 429 atf_add_test_case silent_header 430 atf_add_test_case verbose_header 431 atf_add_test_case si_number 432 atf_add_test_case no_lf_at_eof 433} 434