aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/tail/tests/tail_test.sh
blob: 9c941f8a2c2fabe1753094a4d2d018fe9133862a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2016 Alan Somers
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#

atf_test_case empty_r
empty_r_head()
{
	atf_set "descr" "Reverse an empty file"
}
empty_r_body()
{
	touch infile expectfile
	tail -r infile > outfile
	tail -r < infile > outpipe
	atf_check cmp expectfile outfile
	atf_check cmp expectfile outpipe
}

atf_test_case file_r
file_r_head()
{
	atf_set "descr" "Reverse a file"
}
file_r_body()
{
	cat > infile <<HERE
This is the first line
This is the second line
This is the third line
HERE
	cat > expectfile << HERE
This is the third line
This is the second line
This is the first line
HERE
	tail -r infile > outfile
	tail -r < infile > outpipe
	atf_check cmp expectfile outfile
	atf_check cmp expectfile outpipe
}

atf_test_case file_rn2
file_rn2_head()
{
	atf_set "descr" "Reverse the last two lines of a file"
}
file_rn2_body()
{
	cat > infile <<HERE
This is the first line
This is the second line
This is the third line
HERE
	cat > expectfile << HERE
This is the third line
This is the second line
HERE
	tail -rn2 infile > outfile
	tail -rn2 < infile > outpipe
	atf_check cmp expectfile outfile
	atf_check cmp expectfile outpipe
}

# Regression test for PR 222671
# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=222671
atf_test_case pipe_leading_newline_r
pipe_leading_newline_r_head()
{
	atf_set "descr" "Reverse a pipe whose first character is a newline"
}
pipe_leading_newline_r_body()
{
	cat > expectfile << HERE
3
2
1

HERE
	printf '\n1\n2\n3\n' | tail -r > outfile
	printf '\n1\n2\n3\n' | tail -r > outpipe
	atf_check cmp expectfile outfile
	atf_check cmp expectfile outpipe
}

atf_test_case file_rc28
file_rc28_head()
{
	atf_set "descr" "Reverse a file and display the last 28 characters"
}
file_rc28_body()
{
	cat > infile <<HERE
This is the first line
This is the second line
This is the third line
HERE
	cat > expectfile << HERE
This is the third line
line
HERE
	tail -rc28 infile > outfile
	tail -rc28 < infile > outpipe
	atf_check cmp expectfile outfile
	atf_check cmp expectfile outpipe
}

atf_test_case file_rc28
file_rc28_head()
{
	atf_set "descr" "Reverse a file and display the last 28 characters"
}
file_rc28_body()
{
	cat > infile <<HERE
This is the first line
This is the second line
This is the third line
HERE
	cat > expectfile << HERE
This is the third line
line
HERE
	tail -rc28 infile > outfile
	tail -rc28 < infile > outpipe
	atf_check cmp expectfile outfile
	atf_check cmp expectfile outpipe
}

atf_test_case longfile_r
longfile_r_head()
{
	atf_set "descr" "Reverse a long file"
}
longfile_r_body()
{
	jot -w "%0511d" 1030 0 > infile
	jot -w "%0511d" 1030 1029 0 -1 > expectfile
	tail -r infile > outfile
	tail -r < infile > outpipe
	atf_check cmp expectfile outfile
	atf_check cmp expectfile outpipe
}

atf_test_case longfile_r_enomem
longfile_r_enomem_head()
{
	atf_set "descr" "Reverse a file that's too long to store in RAM"
}
longfile_r_enomem_body()
{
	# When we reverse a file that's too long for RAM, tail should drop the
	# first part and just print what it can.  We'll check that the last
	# part is ok
	{
		ulimit -v 32768 || atf_skip "Can't adjust ulimit"
		jot -w "%01023d" 32768 0 | tail -r > outfile ;
	}
	if [ "$?" -ne 1 ]; then
		atf_skip "Didn't get ENOMEM.  Adjust test parameters"
	fi
	# We don't know how much of the input we dropped.  So just check that
	# the first ten lines of tail's output are the same as the last ten of
	# the input
	jot -w "%01023d" 10 32767 0 -1 > expectfile
	head -n 10 outfile > outtrunc
	diff expectfile outtrunc
	atf_check cmp expectfile outtrunc
}

atf_test_case longfile_r_longlines
longfile_r_longlines_head()
{
	atf_set "descr" "Reverse a long file with extremely long lines"
}
longfile_r_longlines_body()
{
	jot -s " " -w "%07d" 18000 0 > infile
	jot -s " " -w "%07d" 18000 18000 >> infile
	jot -s " " -w "%07d" 18000 36000 >> infile
	jot -s " " -w "%07d" 18000 36000 > expectfile
	jot -s " " -w "%07d" 18000 18000 >> expectfile
	jot -s " " -w "%07d" 18000 0 >> expectfile
	tail -r infile > outfile
	tail -r < infile > outpipe
	atf_check cmp expectfile outfile
	atf_check cmp expectfile outpipe
}

atf_test_case longfile_rc135782
longfile_rc135782_head()
{
	atf_set "descr" "Reverse a long file and print the last 135,782 bytes"
}
longfile_rc135782_body()
{
	jot -w "%063d" 9000 0 > infile
	jot -w "%063d" 2121 8999 0 -1 > expectfile
	echo "0000000000000000000000000000000006878" >> expectfile
	tail -rc135782 infile > outfile
	tail -rc135782 < infile > outpipe
	atf_check cmp expectfile outfile
	atf_check cmp expectfile outpipe
}

atf_test_case longfile_rc145782_longlines
longfile_rc145782_longlines_head()
{
	atf_set "descr" "Reverse a long file with extremely long lines and print the last 145,782 bytes"
}
longfile_rc145782_longlines_body()
{
	jot -s " " -w "%07d" 18000 0 > infile
	jot -s " " -w "%07d" 18000 18000 >> infile
	jot -s " " -w "%07d" 18000 36000 >> infile
	jot -s " " -w "%07d" 18000 36000 > expectfile
	echo -n "35777 " >> expectfile
	jot -s " " -w "%07d" 222 35778 >> expectfile
	tail -rc145782 infile > outfile
	tail -rc145782 < infile > outpipe
	atf_check cmp expectfile outfile
	atf_check cmp expectfile outpipe
}

atf_test_case longfile_rn2500
longfile_rn2500_head()
{
	atf_set "descr" "Reverse a long file and print the last 2,500 lines"
}
longfile_rn2500_body()
{
	jot -w "%063d" 9000 0 > infile
	jot -w "%063d" 2500 8999 0 -1 > expectfile
	tail -rn2500 infile > outfile
	tail -rn2500 < infile > outpipe
	atf_check cmp expectfile outfile
	atf_check cmp expectfile outpipe
}

atf_test_case broken_pipe
broken_pipe_head()
{
	atf_set "descr" "Do not print bogus errno based output on short writes"
}
broken_pipe_body()
{
	atf_check -o save:ints seq -f '%128g' 1 1000
	atf_check -s ignore \
	    -e "inline:tail: stdout\nexit code: 1\n" \
	    -x '(tail -n 856 ints; echo exit code: $? >&2) | sleep 2'
}

atf_test_case stdin
stdin_head()
{
	atf_set "descr" "Check basic operations on standard input"
}
stdin_body()
{
	seq 1 5 > infile
	seq 1 5 > expectfile
	seq 5 1 > expectfile_r

	tail < infile > outfile
	tail -r < infile > outfile_r

	atf_check cmp expectfile outfile
	atf_check cmp expectfile_r outfile_r
}

atf_test_case follow
follow_head()
{
	atf_set "descr" "Basic regression test for -f"
}
follow_body()
{
	local pid

	seq 1 5 > expectfile
	seq 1 3 > infile
	tail -f infile > outfile &
	pid=$!
	sleep 0.1
	seq 4 5 >> infile
	sleep 0.1
	atf_check cmp expectfile outfile
	atf_check kill $pid
}

atf_test_case follow_stdin
follow_stdin_head()
{
	atf_set "descr" "Verify that -f works with files piped to standard input"
}
follow_stdin_body()
{
	local pid

	seq 1 5 > expectfile
	seq 1 3 > infile
	tail -f < infile > outfile &
	pid=$!
	sleep 0.1
	seq 4 5 >> infile
	sleep 0.1
	atf_check cmp expectfile outfile
	atf_check kill $pid
}

atf_test_case follow_create
follow_create_head()
{
	atf_set "descr" "Verify that -F works when a file is created"
}
follow_create_body()
{
	local pid

	rm -f infile
	tail -F infile > outfile &
	pid=$!
	seq 1 5 >infile
	sleep 2
	atf_check cmp infile outfile
	atf_check kill $pid
}

atf_test_case follow_rename
follow_rename_head()
{
	atf_set "descr" "Verify that -F works when a file is replaced"
}
follow_rename_body()
{
	local pid

	seq 1 5 > expectfile
	seq 1 3 > infile
	tail -F infile > outfile &
	pid=$!
	seq 4 5 > infile_new
	atf_check mv infile infile_old
	atf_check mv infile_new infile
	# tail -F polls for a new file every 1s.
	sleep 2
	atf_check cmp expectfile outfile
	atf_check kill $pid
}

atf_test_case silent_header
silent_header_head() {
	atf_set "descr" "Test tail(1)'s silent header feature"
}
silent_header_body() {
	jot 11 1 11 > file1
	jot 11 2 12 > file2
	jot 10 2 11 > expectfile
	jot 10 3 12 >> expectfile
	tail -q file1 file2 > outfile
	atf_check cmp outfile expectfile
}

atf_test_case verbose_header
verbose_header_head() {
	atf_set "descr" "Test tail(1)'s verbose header feature"
}
verbose_header_body() {
	jot 11 1 11 > file1
	echo '==> file1 <==' > expectfile
	jot 10 2 11 >> expectfile
	tail -v file1 > outfile
	atf_check cmp outfile expectfile
}

atf_test_case si_number
si_number_head() {
	atf_set "descr" "Test tail(1)'s SI number feature"
}
si_number_body() {
	jot -b aaaaaaa 129 > file1
	jot -b aaaaaaa 128 > expectfile
	tail -c 1k file1 > outfile
	atf_check cmp outfile expectfile
	jot 1025 1 1025 > file1
	jot 1024 2 1025 > expectfile
	tail -n 1k file1 > outfile
	atf_check cmp outfile expectfile
}

atf_test_case no_lf_at_eof
no_lf_at_eof_head()
{
	atf_set "descr" "File does not end in newline"
}
no_lf_at_eof_body()
{
	printf "a\nb\nc" >infile
	atf_check -o inline:"c" tail -1 infile
	atf_check -o inline:"b\nc" tail -2 infile
	atf_check -o inline:"a\nb\nc" tail -3 infile
	atf_check -o inline:"a\nb\nc" tail -4 infile
}

atf_init_test_cases()
{
	atf_add_test_case empty_r
	atf_add_test_case file_r
	atf_add_test_case file_rc28
	atf_add_test_case file_rn2
	atf_add_test_case pipe_leading_newline_r
	# The longfile tests are designed to exercise behavior in r_buf(),
	# which operates on 128KB blocks
	atf_add_test_case longfile_r
	atf_add_test_case longfile_r_enomem
	atf_add_test_case longfile_r_longlines
	atf_add_test_case longfile_rc135782
	atf_add_test_case longfile_rc145782_longlines
	atf_add_test_case longfile_rn2500
	atf_add_test_case broken_pipe
	atf_add_test_case stdin
	atf_add_test_case follow
	atf_add_test_case follow_stdin
	atf_add_test_case follow_create
	atf_add_test_case follow_rename
	atf_add_test_case silent_header
	atf_add_test_case verbose_header
	atf_add_test_case si_number
	atf_add_test_case no_lf_at_eof
}