1#!/usr/bin/ksh
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 of the CDDL is also available via the Internet at
11# http://www.illumos.org/license/CDDL.
12#
13
14#
15# Copyright 2020 Oxide Computer Company
16#
17
18HEAD=${HEAD:=/usr/bin/head}
19TMPFILE=/tmp/head_test.out.$$
20TMPINPUT=/tmp/head_test.in.$$
21
22test_fail() {
23	echo "$*"
24	((failures++))
25}
26
27test_one() {
28	typeset desc="$1"
29	shift
30	typeset input="$1"
31	shift
32	typeset output="$1"
33	shift
34
35	printf "Running %s: " "$desc"
36	if [[ "$input" == "-" ]]; then
37		$HEAD $* > $TMPFILE
38	else
39		printf "$input" | $HEAD $* > $TMPFILE
40	fi
41
42	if [[ $? -ne 0 ]]; then
43		test_fail "head exited non-zero"
44		return
45	fi
46
47	if [[ ! -f "$output" ]]; then
48		test_fail "missing expeced output file $output"
49		return
50	fi
51
52	if ! diff $output $TMPFILE >/dev/null 2>/dev/null; then
53		test_fail "output mismatch"
54		return
55	fi
56
57	printf "passed\n"
58}
59
60if ! cd $(dirname $0); then
61	printf "failed to reach test directory!\n" 1>&2
62	exit 1
63fi
64
65test_one "simple stdin 1" "a\n\n\nb\n" stdin.1.out
66test_one "simple stdin 2 -n 1" "a\n\n\nb\n" stdin.2.out "-n 1"
67test_one "simple stdin 3 -n 3" "a\n\n\nb\n" stdin.3.out "-n 3"
68test_one "simple stdin 4 -n 10000" "a\n\n\nb\n" stdin.1.out "-n 10000"
69test_one "simple stdin 5 -c 1" "a\n\n\nb\n" stdin.5.out "-c 1"
70test_one "simple stdin 6 -c 230" "a\n\n\nb\n" stdin.1.out "-c 230"
71test_one "simple stdin 7 -n 3 -q" "a\n\n\nb\n" stdin.3.out "-n 3" "-q"
72test_one "simple stdin 8 -" "a\n\n\nb\n" stdin.2.out "-1"
73test_one "simple stdin 9 -23" "a\n\n\nb\n" stdin.1.out "-23"
74test_one "simple stdin 10 -q" "a\n\n\nb\n" stdin.1.out "-q"
75#
76# Note, different implementations have different behaviours when -v is specified
77# and there is only standard input. This verifies our current choice.
78#
79test_one "simple stdin 11 -v" "a\n\n\nb\n" stdin.11.out "-v"
80test_one "stdin nul 1" "hello\0regression\n" stdin-nul.1.out
81test_one "stdin nul 2 -c 1" "hello\0regression\n" stdin-nul.2.out "-c 1"
82test_one "stdin nul 3" "this\0\nwas\0an\0\n\nunfortunate\0buf\0\n" \
83    stdin-nul.3.out
84
85test_one "5221 regression" "Old\nBill Joy\nBug\n\nLasts Forever\n" 5221.out \
86    5221.in /dev/stdin
87test_one "/dev/stdin repeated" "Hello\n" stdin.multi.out /dev/stdin /dev/stdin
88test_one "no newline -n 3" "Why do you need newlines?" stdin.nonewline.out \
89    "-n 3"
90
91test_one "simple file 1" - rings.1.out rings.in
92test_one "simple file 2 -c 30" - rings.2.out "-c 30" rings.in
93test_one "simple file 3 -n 7" - rings.3.out "-n 7" rings.in
94test_one "simple file 4 -50" - rings.in "-50" rings.in
95test_one "simple file 5 -v" - rings.5.out "-v" rings.in
96test_one "multi file 1 -n 5 -q" - multi.1.out "-n 5" "-q" rings.in \
97    rings.in rings.in
98test_one "multi file 2 -n 5 -q -v" - multi.1.out "-n 5" "-q" "-v" "-q" \
99    rings.in rings.in rings.in
100test_one "multi file 3 -n 5 -q -v -q" - multi.1.out "-n 5" "-q" "-v" "-q" \
101    rings.in rings.in rings.in
102test_one "multi file 4 -c 100" - multi.4.out "-c 100" rings.in rings.in
103
104#
105# Construct a file larger than 8k in size without a new line to verify that we
106# will do multiple reads beyond the first.
107#
108rm -f $TMPINPUT
109for ((i = 0; i < 10000; i++)); do
110	printf "Lorem ipsum" >> $TMPINPUT
111done
112test_one "large input" - $TMPINPUT $TMPINPUT
113
114rm $TMPFILE $TMPINPUT
115
116if [[ "$failures" -ne 0 ]]; then
117	printf "%u tests failed\n" "$failures" 2>&1
118	exit 1
119fi
120
121printf "All tests passed successfully\n"
122exit 0
123