From b055174307fbfb392ffa8bd95aa6f489defeead0 Mon Sep 17 00:00:00 2001 From: millert Date: Mon, 20 Jan 1997 19:41:39 +0000 Subject: [PATCH] sort(1) test suite --- usr.bin/sort/TEST/stests | 895 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 895 insertions(+) create mode 100644 usr.bin/sort/TEST/stests diff --git a/usr.bin/sort/TEST/stests b/usr.bin/sort/TEST/stests new file mode 100644 index 00000000000..e07a1f3a5f3 --- /dev/null +++ b/usr.bin/sort/TEST/stests @@ -0,0 +1,895 @@ +#!/bin/sh - +# $OpenBSD: stests,v 1.1 1997/01/20 19:41:39 millert Exp $ +# from: @(#)stests 8.1 (Berkeley) 6/6/93 + +#Latest version. My sort passes all tests because I wrote it. +#We differ only on 25E and 25H. +#(I found at least one bug in constructing test 25, and was driven +#to rewrite field parsing to clarify it.) +# +#In 25E, -k2.3,2.1b, the fields are not necessarily out of order. +#Even if they were, it would be legal (11752-3), although certainly +#justification for warning. +# +#On 25H, your answer is as defensible as mine. (Our suggestion +#*1 backs mine.) + + +# Tests for the Unix sort utility +# Test Posix features except for locale. +# Test some nonstandard features if present. + +# Other tests should be made for files too big to fit in memory. + + +# Initialize switches for nonstandard features. +# Use parenthesized settings for supported features. + +o=: # officially obsolescent features: +1 -2, misplaced -o (o=) +g=: # -g numeric sort including e-format numbers (g=) +M=: # -M sort by month names (M=) +s=: # -s stable, do not compare raw bytes on equal keys (s=) +y= # -y user-specified memory size (y=-y10000) + +# Detect what features are supported, assuming bad options cause +# errors. Set switches accordingly. + +echo obsolescent and nonstandard features recognized, if any: +if sort +0 /dev/null; then o= + echo ' +1 -2'; fi +if sort /dev/null -o xx 2>/dev/null; then o= + echo ' displaced -o'; fi +if sort -g /dev/null; then g= + echo ' -g g-format numbers'; fi +if sort -M /dev/null; then M= + echo ' -M months'; fi +if sort -s /dev/null; then s= + echo ' -s stable'; fi +if sort -y10000 /dev/null; then y=-y10000 + echo ' -y space'; fi +if sort -z10000 /dev/null; then + echo ' -z size (not exercised)'; fi +if sort -T. /dev/null; then + echo ' -T tempdir (not exercised)'; fi + + +export TEST # major sequence number of test + +trap "rm -f in in1 out xx -k xsort linecount fields; exit" 0 1 2 13 15 + +# xsort testno options +# Sort file "in" with specified options. +# Compare with file "out" if that is supplied, +# otherwise make plausibility checks on output + +# "sum" must be dumb; insensitive to the +# order of lines within a file. +# System V sum is suitable; sum -5 is the v10 equivalent. + +PATH=.:$PATH +export PATH +cat <<'!' >xsort; chmod +x xsort + + X=$1; shift + + if sort "$@" in >xx && sort -c "$@" xx + then + if test -f out + then + cmp xx out >/dev/null && exit 0 + echo $TEST$X comparison failed + else + test "`cksum -o2 linecount; chmod +x linecount +awk 'END{ if(NR!='$3') print "'$TEST$1' failed" }' $2 +! + +rm -f out + +#--------------------------------------------------------------- +TEST=01; echo $TEST # -c status, checksum + # obsolescent features go together +cat <in +b +a +! +rm -f out -o + +sort -c in 2>/dev/null && echo ${TEST}A failed + +xsort B || '"cksum"' is probably unsuitable - see comments + +$o sort +0 in -o in || echo ${TEST}c failed + +#--------------------------------------------------------------- +TEST=02; echo $TEST # output from -c +cat <in +x +y +! + +sort -cr in >out 2>xx && echo ${TEST}A failed +test -s out && echo ${TEST}B failed +test -s xx && echo option -c is noisy "(probably legal)" +test -s xx || echo option -c is quiet "(legal, not classical)" + +#--------------------------------------------------------------- +TEST=03; echo $TEST # -n +cat <in +-99.0 +-99.1 +-.0002 +-10 +2 +0010.000000000000000000000000000000000001 +10 +3x +x +! +cat <out +-99.1 +-99.0 +-10 +-.0002 +x +2 +3x +10 +0010.000000000000000000000000000000000001 +! + +xsort "" -n + +#--------------------------------------------------------------- +TEST=04; echo $TEST # -b without fields, piping, -c status return +cat <in + b + a +! +cp in out + +xsort A -b + +cat in | sort | cat >xx +cmp xx out >/dev/null || echo ${TEST}B failed + +sort in | sort -cr 2>/dev/null && echo ${TEST}C failed + +#--------------------------------------------------------------- +TEST=05; echo $TEST # fields, reverse fields, -c status return +cat <in +b b p +a b q +x a +! +cat <out +x a +a b q +b b p +! + +$o xsort A +1 -2 + +$o xsort B +1 -2 +2r + +xsort C -k 2,2 + +xsort D -k 2,2 -k 3r + +xsort E -k 2,2.0 + +xsort F -k 2,2 -k 1,1 -k 3 + +sort -c -k 2 in 2>/dev/null && ${TEST}G failed + +#--------------------------------------------------------------- +TEST=06; echo $TEST # -t +cat <in +a: +a! +! +cp in out + +$o xsort A -t : -r +0 + +$o xsort B -t : +0 -1 + +xsort C -t : -r -k 1 + +xsort D -t : -k 1,1 + +#--------------------------------------------------------------- +TEST=07; echo $TEST # -t, character positions in fields + # -t: as 1 arg is not strictly conforming, but classical +cat <in +: ab +:bac +! +cat <out +:bac +: ab +! + +$o xsort A -b -t: +1.1 + +$o xsort B -t: +1.1r + +xsort C -b -t: -k 2.2 + +xsort D -t: -k 2.2r + +#--------------------------------------------------------------- +TEST=08; echo $TEST # space and tab as -t characters +cat <in + b c + b c + b c +! +cp in out + +xsort A -t ' ' -k2,2 + +xsort B -t ' ' -k2.1,2.0 + +cat <out + b c + b c + b c +! + +xsort C -t ' ' -k2,2 + +xsort D -t ' ' -k2.1,2.0 + +cat <out + b c + b c + b c +! + +xsort E -k2 + +cat <out + b c + b c + b c +! + +xsort F -k2b + +#--------------------------------------------------------------- +TEST=09; echo $TEST # alphabetic as -t character +cat <in +zXa +yXa +zXb +! +cp in out + +xsort "" -tX -k2 -k1r,1 + +#--------------------------------------------------------------- +TEST=10; echo $TEST # -m +cat <in +a +ab +ab +bc +ca +! +cat <in1 +Z +a +aa +ac +c +! +cat <out +Z +a +a +aa +ab +ab +ac +bc +c +ca +! + +sort -m in in1 >xx +cmp xx out >/dev/null || echo $TEST failed + +#--------------------------------------------------------------- +TEST=11; echo $TEST # multiple files, -o overwites input, -m, -mu +cat <in +a +b +c +d +! + +sort -o xx in in in in in in in in in in in in in in in in in +linecount A xx 68 +sort -o in -mu in in in in in in in in in in in in in in in in in +linecount B in 4 +sort -o in -m in in in in in in in in in in in in in in in in in + +cmp in xx >/dev/null || echo ${TEST}C failed + +#--------------------------------------------------------------- +TEST=12; echo $TEST # does -mu pick the first among equals? +cat <in +3B +3b +3B2 +~3B2 +4.1 +41 +5 +5. +! +cat <out +3B +3B2 +4.1 +5 +! + +xsort A -mudf || echo "(other behavior is legal, not classical)" + +xsort B -mudf -k1 || echo "(other behavior is legal, not classical)" + +#--------------------------------------------------------------- +TEST=13; echo $TEST # long records (>8000 bytes, keys >16000), -r +awk ' +BEGIN { x="x" + for(i=1; i<=12; i++) x = x x + for(i=15; i<=25; i++) print x i +}' >in +awk ' +BEGIN { x="x" + for(i=1; i<=12; i++) x = x x + for(i=25; i>=15; i--) print x i +}' >out + +xsort A -r + +xsort B -k 1,1r -k 1 + +#--------------------------------------------------------------- +TEST=14; echo $TEST "(3 long parts)" +awk 'BEGIN { for(i=0; i<100000; i++) print rand() }' | grep -v e >in +rm -f out + +xsort A; echo $TEST "(part A done)" + +xsort B -n; echo $TEST "(part B done)" + +# next test is unclean: xx is a hidden side-effect of xsort + +awk ' + $0 < x { print "test '${TEST}C' failed"; exit } + $0 "" != x { print >"out"; x = $0 } +' xx + +xsort C -n -u + +#--------------------------------------------------------------- +TEST=15; echo $TEST "(long)" # force intermediate files if possible +awk 'BEGIN { for(i=0; i<20000; i++) print rand() }' >in +rm -f out + +xsort A -r $y + +sort -r in | awk '$0 "x" != x { print ; x = $0 "x" }' >out + +xsort B -u -r $y + +#--------------------------------------------------------------- +TEST=16; echo $TEST # -nr, -nm, file name - +awk 'BEGIN { for(i=-100; i<=100; i+=2) printf "%.10d\n", i }' >in + +awk 'BEGIN { for(i=-99; i<=100; i+=2) print i }' | sort -nr in - >xx +awk '$0+0 != 101-NR { print "'${TEST}A' failed"; exit }' xx + +awk 'BEGIN { for(i=-99; i<=100; i+=2) print i }' | sort -mn in - >xx +awk '$0+0 != -101+NR { print "'${TEST}B' failed"; exit }' xx + +#--------------------------------------------------------------- +TEST=17; echo $TEST # -d, fields without end, modifier override +cat <in +a-B +a+b +a b +A+b +a b +! +cat <out +a b +a b +A+b +a-B +a+b +! + +$o xsort A -df +0 +0d + +xsort B -df -k 1 -k 1d + +#--------------------------------------------------------------- +TEST=18; echo $TEST # -u on key only +cat <in +12 y +13 z +12 x +! +cat <out +12 x +12 y +13 z +! + +$o xsort A +0 -1 + +xsort B -k 1,1 + +sort -u -k 1,1 in >xx +linecount C xx 2 + +#--------------------------------------------------------------- +TEST=19; echo $TEST # -i, -d, -f +cat <xx.c +run(i,j){ for( ; i<=j; i++) printf("%.3o %c\n",i,i); } +main(){ run(0, 011); /* 012=='\n' */ + run(013, 0377); } +! +cc xx.c +a.out >in +cat <xx.c +run(i,j){ for( ; i<=j; i++) printf("%.3o %c\n",i,i); } +main(){ run(0, 011); + run(013, ' '-1); + run(0177, 0377); + run(' ', 0176); } +! +cc xx.c +a.out >out + +xsort A -i -k 2 + +cat <xx.c +run(i,j){ for( ; i<=j; i++) printf("%.3o %c\n",i,i); } +main(){ run(0, 010); /* 011=='\t', 012=='\n' */ + run(013, ' '-1); + run(' '+1, '0'-1); + run('9'+1, 'A'-1); + run('Z'+1, 'a'-1); + run('z'+1, 0377); + run('\t', '\t'); + run(' ', ' '); + run('0', '9'); + run('A', 'Z'); + run('a', 'z'); } +! +cc xx.c +a.out >out + +xsort B -d -k 2 + +cat <xx.c +run(i,j){ for( ; i<=j; i++) printf("%.3o %c\n",i,i); } +main(){ int i; + run(0, 011); + run(013, 'A'-1); + for(i='A'; i<='Z'; i++) + printf("%.3o %c\n%.3o %c\n",i,i,i+040,i+040); + run('Z'+1, 'a'-1); + run('z'+1, 0377); } +! +cc xx.c +a.out >out +rm xx.c + +xsort C -f -k 2 + +#--------------------------------------------------------------- +TEST=20; echo $TEST # -d, -f, -b applies only to fields +cat <in + b +'C +a +! +cp in out + +xsort A -d + +xsort B -f + +cat <out + b +a +'C +! + +xsort C -dfb + +#--------------------------------------------------------------- +TEST=21; echo $TEST # behavior of null bytes +cat <<'!' >xx.c +main() { printf("%cb\n%ca\n",0,0); } +! +cc xx.c +a.out >in +sort in >xx +cmp in xx >/dev/null && echo ${TEST}A failed +test "`wc -c in +a 2 +a 1 +b 2 +b 1 +! +cat <out +b 1 +b 2 +a 1 +a 2 +! + +xsort "" -r -k1,1 -k2n + +#--------------------------------------------------------------- +TEST=23; echo $TEST # empty file + +sort -o xx /dev/null || echo ${TEST}A failed + +sort -c in +0:2:3:4:5:6:7:8:9 +1:1:3:4:5:6:7:8:9 +1:2:2:4:5:6:7:8:9 +1:2:3:3:5:6:7:8:9 +1:2:3:4:4:6:7:8:9 +1:2:3:4:5:5:7:8:9 +1:2:3:4:5:6:6:8:9 +1:2:3:4:5:6:7:7:9 +1:2:3:4:5:6:7:8:8 +! +cat <out +1:2:3:4:5:6:7:8:8 +1:2:3:4:5:6:7:7:9 +1:2:3:4:5:6:6:8:9 +1:2:3:4:5:5:7:8:9 +1:2:3:4:4:6:7:8:9 +1:2:3:3:5:6:7:8:9 +1:2:2:4:5:6:7:8:9 +1:1:3:4:5:6:7:8:9 +0:2:3:4:5:6:7:8:9 +! + +xsort "" -t: -k9 -k8 -k7 -k6 -k5 -k4 -k3 -k2 -k1 + +#--------------------------------------------------------------- +TEST=25; echo $TEST # variously specified alpha fields + # numbers give the correct orderings +cat <in +01:04:19:01:16:01:21:01 a +02:03:13:15:13:19:15:02 a +03:02:07:09:07:13:09:03 a +04:01:01:03:01:07:03:04 a +05:08:20:16:17:02:20:05 aa +06:07:14:18:14:20:14:06 aa +07:06:08:10:08:14:08:07 aa +08:05:02:04:02:08:02:08 aa +09:16:22:02:22:04:24:13 b +10:15:16:20:19:22:18:14 b +11:14:10:12:10:16:12:15 b +12:13:04:06:04:10:06:16 b +13:24:24:22:24:06:22:21 bb +14:23:18:24:21:24:16:22 bb +15:22:12:14:12:18:10:23 bb +16:21:06:08:06:12:04:24 bb +17:12:21:21:18:03:19:09 ab +18:11:15:19:15:21:13:10 ab +19:10:09:11:09:15:07:11 ab +20:09:03:05:03:09:01:12 ab +21:20:23:17:23:05:23:17 ba +22:19:17:23:20:23:17:18 ba +23:18:11:13:11:17:11:19 ba +24:17:05:07:05:11:05:20 ba +! +sort -k2b -k2 in >xx && + sort -c -t: -k2n xx 2>/dev/null || echo ${TEST}A failed +sort -k2,2.1b -k2 in >xx && + sort -c -t: -k3n xx 2>/dev/null || echo ${TEST}B failed +sort -k2.3 -k2 in >xx && + sort -c -t: -k4n xx 2>/dev/null || echo ${TEST}C failed +sort -k2b,2.3 -k2 in >xx && + sort -c -t: -k5n xx 2>/dev/null || echo ${TEST}D failed +sort -k2.3,2.1b -k2 in >xx && + sort -c -t: -k6n xx 2>/dev/null || echo ${TEST}E failed +sort -k2,2.1b -k2r in >xx && + sort -c -t: -k7n xx 2>/dev/null || echo ${TEST}F failed +sort -b -k2,2 -k2 in >xx && + sort -c -t: -k8n xx 2>/dev/null || echo ${TEST}G failed +sort -b -k2,2b -k2 in >xx && # perhaps same as G + sort -c -t: -k3n xx 2>/dev/null || echo ${TEST}H failed\ + "(standard is not clear on this)" + +#--------------------------------------------------------------- +TEST=26; echo $TEST # empty fields, out of bounds fields +cat <in +0 5 +1 4 +2 3 +3 2 +4 1 +5 0 +! +cp in out + +xsort "" -k2.2,2.1 -k2.3,2.4 + +#--------------------------------------------------------------- +TEST=27; echo $TEST # displaced -o +rm -f out + +$o sort /dev/null -o out || $o echo ${TEST}B failed +$o test -f out || $o echo ${TEST}C failed + +#--------------------------------------------------------------- +TEST=28; echo $TEST # apparently nonmonotone field specs +cat <in +aaaa c +x a +0 b +! +cp in out + +$o xsort A +1 -0.3 +1.4 -1.5 + +xsort B -k2,1.3 -k2.5,2.5 + +#--------------------------------------------------------------- +TEST=29; echo $TEST # determination of end of option list +cat >-k <xx || echo ${TEST}A argument failed +cmp xx -k || echo ${TEST}A comparison failed + +sort - -c /dev/null && echo ${TEST}B failed + +#--------------------------------------------------------------- +TEST=30; echo $TEST # missing newline +awk 'BEGIN{ printf "%s", "x"}' | sort >xx +wc -c in +jan 10 1900 +Feb 26 1900 +feb 25 1900 +January xx 1900 +August 11 1900 +jan 15 1990 +feb 22 1990 +mar 15 1990 +apr 1 1990 +may 45 1990 +jun 14 1990 +jul 4 1990 +aug 1~ 1990 +aug 11 1990 +sep 1 1990 +oct 12 1990 +nov 24 1990 +dec 25 1990 +never 3 1990 + Dec 25 1990 +! +cat <out +January xx 1900 +jan 10 1900 +feb 25 1900 +Feb 26 1900 +August 11 1900 +never 3 1990 +jan 15 1990 +feb 22 1990 +mar 15 1990 +apr 1 1990 +may 45 1990 +jun 14 1990 +jul 4 1990 +aug 1~ 1990 +aug 11 1990 +sep 1 1990 +oct 12 1990 +nov 24 1990 + Dec 25 1990 +dec 25 1990 +! + +$M xsort "" -k3n -k1M -k2n + +#--------------------------------------------------------------- +TEST=32; echo $TEST # -M case insensitivity, -r +cat <in +x +june +january +december +! +cat <out +december +june +january +x +! + +$M xsort "" -Mr + +#--------------------------------------------------------------- +TEST=33; echo $TEST # -g +cat <in +2 +1 +10 +.2 +1e +1E1 +1e. +! +cat <out +.2 +1 +1e +1e. +2 +10 +1E1 +! + +$g xsort "" -g + +#--------------------------------------------------------------- +TEST=34; echo $TEST # -g wide operands +cat <in +.99999999999999999999 +099999999999999999999e-21 +099999999999999999999e-19 +.1e1 +! +cat <out +099999999999999999999e-21 +.99999999999999999999 +.1e1 +099999999999999999999e-19 +! + +$g xsort A -g + +cat <out +.1e1 +.99999999999999999999 +099999999999999999999e-19 +099999999999999999999e-21 +! + +xsort B -n + +#--------------------------------------------------------------- +TEST=35; echo $TEST #-g, -u with different fp reps +cat <in ++0 +-0 +0.10 ++.1 +-.1 +-100e-3 +x +! +cat <out +-.1 +-100e-3 ++0 +-0 +x ++.1 +0.10 +! + +$g xsort A -g + +$g sort -gu in >xx && $g sort -c -gu xx || echo ${TEST}B failed +$g linecount C xx 3 + +#--------------------------------------------------------------- +TEST=36; echo $TEST # -s +cat <in +a 2 +b 1 +c 2 +a 1 +b 2 +c 1 +! +cat <out +a 2 +a 1 +b 1 +b 2 +c 2 +c 1 +! + +$s xsort "" -s -k1,1 + +#--------------------------------------------------------------- +TEST=37; echo $TEST # -s, multiple files +cat <in +a 2 +c 2 +! +cat <in1 +a 1 +b 1 +c 1 +! +cat <out +c 2 +b 1 +a 2 +! + +$s sort -smru -k1,1 in in in1 in1 >xx +$s cmp xx out >/dev/null || echo $TEST failed + +#--------------------------------------------------------------- +TEST=38; echo $TEST # -s +$s awk ' + BEGIN { + for(i=1; i<50; i++) + for(j=1; j<=i; j++) { + print i, 2 >"in" + print i, 1 >"in1" + } + }' + +$s sort -m -s -k1,1n in in1 >out + +$s awk ' + func stop() { print "'$TEST' failed"; exit } + $1!=last1 { if(count!=last1 || $2!=2) stop(); + count = 0} + $1==last1 && $2!=last2 { if(count!=last1 || $2!=1) stop(); + count = 0 } + { count++; last1 = $1; last2 = $2 } + ' out -- 2.20.1