mkfiles: add 'mk test' support

9front has several tests scattered throughout the source,
as well as more tests in an external 'regress' repository.
Many of these tests are broken, because there is no easy
way to build and track all of them.

This pulls in several tests from different sources, deletes
the broken tests, tests with missing data, and adds a single
command that can be run from the root of the src directory
to test our system.

The hope is that as we develop new code, we add more tests,
and eventually start running the tests on every commit.
Please enter the commit message for your changes. Lines starting
This commit is contained in:
Ori Bernstein 2023-02-19 20:44:56 -05:00
parent c3ba64f693
commit 31913a8524
74 changed files with 2228 additions and 44 deletions

View file

@ -1,9 +1,9 @@
</$objtype/mkfile </$objtype/mkfile
none:VQ: none:VQ:
echo mk all, install, clean, nuke, installall, update echo mk all, install, clean, nuke, installall, update, test
all install clean nuke installall update:V: all install clean nuke installall update test:V:
@{cd bin/source; mk $target} @{cd bin/source; mk $target}
@{cd news/src; mk $target} @{cd news/src; mk $target}
@{cd wiki/src; mk $target} @{cd wiki/src; mk $target}

View file

@ -84,10 +84,11 @@ fn merge1 {@{
base=/dev/null base=/dev/null
if(! test -f $theirs) if(! test -f $theirs)
theirs=/dev/null theirs=/dev/null
if(! ape/diff3 -3 -m $ours $base $theirs > $tmp)
echo merge needed: $out >[1=2]
if(mergeperm $ours $base $theirs){ if(mergeperm $ours $base $theirs){
mkdir -p `{basename -d $tmp}
if(! ape/diff3 -3 -m $ours $base $theirs > $tmp)
echo merge needed: $out >[1=2]
mv $tmp $out mv $tmp $out
git/add $out git/add $out
chmod $mergedperms $out chmod $mergedperms $out

View file

@ -27,3 +27,6 @@ cmd.%:V:
9src.%:V: 9src.%:V:
cd 9src cd 9src
mk $stem mk $stem
test:VQ:
# nothing

View file

@ -4,7 +4,7 @@
TARGET=flacdec TARGET=flacdec
CC=pcc CC=pcc
CFLAGS=-I. -I../libFLAC -I../libFLAC/FLAC -D_POSIX_SOURCE -D_BSD_EXTENSION -DPlan9 -c CFLAGS=-I. -I../libFLAC -I../libFLAC/FLAC -D_POSIX_SOURCE -D_BSD_EXTENSION -DPlan9
%.$O: %.c %.$O: %.c
$CC $CFLAGS -c $stem.c $CC $CFLAGS -c $stem.c
@ -19,3 +19,6 @@ clean:V:
install:V: $O.$TARGET install:V: $O.$TARGET
cp $O.$TARGET $BIN/$TARGET cp $O.$TARGET $BIN/$TARGET
test:VQ:
# nothing

View file

@ -19,3 +19,6 @@ clean:V:
install:V: $O.$TARGET install:V: $O.$TARGET
cp $O.$TARGET $BIN/$TARGET cp $O.$TARGET $BIN/$TARGET
test:VQ:
# nothing

View file

@ -60,3 +60,9 @@ safeinstallall:V:
cd $i cd $i
mk clean mk clean
} }
test:V:
for (i in $DIRS) @{
cd $i
mk test
}

View file

@ -59,7 +59,3 @@ LDFLAGS= # -p
testcase.new.mp3: testcase.wav $O.out testcase.new.mp3: testcase.wav $O.out
$O.out --nores -h testcase.wav testcase.new.mp3 $O.out --nores -h testcase.wav testcase.new.mp3
test:V: testcase.new.mp3
cmp -l testcase.new.mp3 testcase.mp3 | wc -l
rm testcase.new.mp3

View file

@ -19,3 +19,6 @@ clean:V:
install:V: $O.$TARGET install:V: $O.$TARGET
cp $O.$TARGET $BIN/$TARGET cp $O.$TARGET $BIN/$TARGET
test:VQ:
# nothing

View file

@ -19,3 +19,6 @@ clean:V:
install:V: $O.$TARGET install:V: $O.$TARGET
cp $O.$TARGET $BIN/$TARGET cp $O.$TARGET $BIN/$TARGET
test:VQ:
# nothing

View file

@ -18,20 +18,6 @@ BIN=/$objtype/bin
CFLAGS=$CFLAGS -p -DPLAN9 -Ilib CFLAGS=$CFLAGS -p -DPLAN9 -Ilib
test:V: $O.bzip2 $O.bunzip2
./$O.bzip2 -1 < sample1.ref > sample1.rb2
./$O.bzip2 -2 < sample2.ref > sample2.rb2
./$O.bzip2 -3 < sample3.ref > sample3.rb2
./$O.bunzip2 < sample1.bz2 > sample1.tst
./$O.bunzip2 < sample2.bz2 > sample2.tst
./$O.bunzip2 < sample3.bz2 > sample3.tst
cmp sample1.bz2 sample1.rb2
cmp sample2.bz2 sample2.rb2
cmp sample3.bz2 sample3.rb2
cmp sample1.tst sample1.ref
cmp sample2.tst sample2.ref
cmp sample3.tst sample3.ref
bzip2recover.$O: bzip2recover.c bzip2recover.$O: bzip2recover.c
pcc -D_POSIX_SOURCE -D_BSD_EXTENSION -c bzip2recover.c pcc -D_POSIX_SOURCE -D_BSD_EXTENSION -c bzip2recover.c

View file

@ -13,3 +13,6 @@ cwfs64x.%:V:
cd cwfs64x && mk $stem cd cwfs64x && mk $stem
cleanall:V: clean emelie.clean fs64.clean cwfs64.clean cwfs64x.clean cleanall:V: clean emelie.clean fs64.clean cwfs64.clean cwfs64x.clean
test:VQ:
# nothing

0
sys/src/cmd/git/add Normal file → Executable file
View file

0
sys/src/cmd/git/commit Normal file → Executable file
View file

0
sys/src/cmd/git/compat Normal file → Executable file
View file

0
sys/src/cmd/git/diff Normal file → Executable file
View file

0
sys/src/cmd/git/import Normal file → Executable file
View file

0
sys/src/cmd/git/rebase Normal file → Executable file
View file

0
sys/src/cmd/git/revert Normal file → Executable file
View file

View file

@ -0,0 +1,9 @@
A a
A b
A dir/a
A dir/b
A extra/a
A extra/b
A more/a
A more/b
A more/c

34
sys/src/cmd/git/test/add.rc Executable file
View file

@ -0,0 +1,34 @@
#!/bin/rc
. util.rc
rm -fr scratch
mkdir -p scratch/repo
echo @@ abs paths @@
@{
rfork ne
cd scratch/repo
pwd=`{pwd}
$G/init
mkdir dir
mkdir another
mkdir more
mkdir extra
touch a b c
touch dir/^(a b c)
touch another/^(a b c)
touch more/^(a b c)
touch extra/^(a b c)
$G/add a
$G/add $pwd/b
$G/add dir/a
$G/add $pwd/dir/b
$G/add more
@{cd more && $G/add ../extra/a}
@{cd more && $G/add $pwd/extra/b}
$G/$O.fs
$G/$O.walk > ../added
}
diff -c scratch/added add.expected >/dev/null || die wrong files

67
sys/src/cmd/git/test/basic.rc Executable file
View file

@ -0,0 +1,67 @@
#!/bin/rc
. util.rc
wrkdir=`{pwd}
rm -fr scratch
mkdir -p scratch/upstream
echo @@ version1 @@
@{
cd scratch/upstream
q $G/init
echo version1 > file.txt
q $G/add file.txt
q $G/commit -m version1 file.txt
}
@{
cd scratch
$G/clone $wrkdir/scratch/upstream downstream
}
diff -c scratch/upstream/file.txt scratch/downstream/file.txt || die mismatch
echo @@ version2 @@
@{
cd scratch/upstream
echo version2 > file.txt
q $G/commit -m version2 file.txt
}
@{
cd scratch/downstream
q $G/pull
}
q diff -c scratch/upstream/file.txt scratch/downstream/file.txt || die mismatch
echo @@ version3 @@
@{
cd scratch/upstream
echo version3 > file2.txt
$G/add file2.txt
q $G/commit -m version3 file2.txt
}
@{
cd scratch/downstream
q $G/pull
}
q diff -c scratch/upstream/file.txt scratch/downstream/file.txt || die mismatch
q diff -c scratch/upstream/file2.txt scratch/downstream/file2.txt || die mismatch
echo @@ version4 @@
@{
cd scratch/upstream
echo version4 > file.txt
$G/rm file2.txt
rm file2.txt
q $G/commit -m version4 file.txt file2.txt
}
@{
cd scratch/downstream
q $G/pull
}
q diff -c scratch/upstream/file.txt scratch/downstream/file.txt || die mismatch
! test -e scratch/upstream/file2.txt || die mismatch
! test -e scratch/downstream/file2.txt || die mismatch

40
sys/src/cmd/git/test/export.rc Executable file
View file

@ -0,0 +1,40 @@
#!/bin/rc
. util.rc
rm -fr scratch
mkdir -p scratch
cd scratch
# setup test repo
@{
rfork ne
q $G/init a
cd a
echo hello > a
echo goodbye > b
q $G/add a b
q $G/commit -m v1 .
cd ..
pwd
q $G/clone `{pwd}^/a b
}
echo @@ export and apply @@
@{
rfork ne
@{
cd b
echo hihi > b
q $G/commit -m export1 b
$G/export > ../export1.patch
}
@{
cd a
q $G/import ../export1.patch
}
}
~ `{cd a && $G/$O.query HEAD} `{cd b && $G/$O.query HEAD} || die 'mismatched export'

68
sys/src/cmd/git/test/lca.rc Executable file
View file

@ -0,0 +1,68 @@
#!/bin/rc
. util.rc
rm -fr scratch
mkdir -p scratch
cd scratch
echo @@ test lca @@
@{
q $G/init a
cd a
echo 'first' > f
q $G/add f
q $G/commit -m base f
r=`{$G/$O.query HEAD}
echo 0 > f
q $G/commit -m a.0 .
a=`{$G/$O.query HEAD}
for(i in `{seq 10}){
echo $i > f
q $G/commit -m a.$i .
}
q $G/branch -nb $r merge
echo x > f
q $G/commit -m b.0 .
b=`{$G/$O.query HEAD}
qq $G/merge front
q $G/commit -m merge .
m=`{$G/$O.query HEAD}
~ `{$G/$O.query $a $m @} $a || die lca a-m
~ `{$G/$O.query $a $b @} $r || die lca a-b
~ `{$G/$O.query $a $r @} $r || die lca a-r
}
# a
# ↓
# b→c→d→e→f
#
# date order (oldest to newest): f d c b e a
echo @@ test lca rebase @@
@{
q $G/init b
cd b
touch f
fn commit {
$G/$O.save -n regress -e regress $* f
}
f=`{commit -m f -d 1}
e=`{commit -m e -d 5 -p $f}
d=`{commit -m d -d 2 -p $e}
c=`{commit -m c -d 3 -p $d}
b=`{commit -m b -d 4 -p $c}
a=`{commit -m a -d 6 -p $e}
~ `{$G/$O.query $a $b @} $e || die lca a-b
~ `{$G/$O.query $b $a @} $e || die lca b-a
}

92
sys/src/cmd/git/test/merge.rc Executable file
View file

@ -0,0 +1,92 @@
#!/bin/rc
. util.rc
rm -fr scratch
mkdir -p scratch
cd scratch
c='foo
bar
baz
'
# setup test repo
@{
rfork ne
q $G/init a
cd a
echo hello > a
echo goodbye > b
echo -n $c > c
chmod +x a
q $G/add a b c
q $G/commit -m v1 .
cd ..
pwd
q $G/clone `{pwd}^/a b
}
echo @@ merge different files @@
@{
rfork ne
@{
cd a
echo x > a
q $G/commit -m diverge1a a
}
@{
cd b
echo y > b
q $G/commit -m diverge1b b
}
@{
cd b
qq $G/pull
$G/merge origin/front || status=''
q $G/commit -m merged .
}
}
flag +x
~ `{cat b/a} x || die merge 1.a
~ `{cat b/b} y || die merge 1.b
~ `''{cat b/c} $c || die merge 1.c
test -x b/a || die merge preserve exec
! test -x b/b || die merge preserve nonexec b
! test -x b/c || die merge preserve nonexec c
echo @@ merge concurent edits @@
@{
rfork ne
@{
cd a
chmod -x a
chmod +x b
echo quux >>c
q $G/commit -m diverge2a a b c
}
@{
cd b
sed s/foo/FOO/ <c >c.new
mv c.new c
q $G/commit -m diverge2b c
qq $G/pull
qq $G/merge origin/front
q $G/commit -m merge c
}
}
c='FOO
bar
baz
quux
'
~ `{cat b/a} x || die # commit from a
~ `{cat b/b} y || die # commit from b
~ `''{cat b/c} $c || {diff -u b/c <{echo $c}; die merge 1.c}
! test -x b/a || die merge remove exec
test -x b/b || die merge add exec
! test -x b/c || die merge preserve nonexec c

View file

@ -0,0 +1,11 @@
</$objtype/mkfile
TEST=\
add\
basic\
export\
lca\
merge\
range
</sys/src/cmd/mktest

75
sys/src/cmd/git/test/range.rc Executable file
View file

@ -0,0 +1,75 @@
#!/bin/rc
. util.rc
rm -fr scratch
mkdir -p scratch
cd scratch
fn commit {
$G/$O.save -n regress -e regress $* f
}
# h→g→f
# ↓ ↓
# e→d→c→b→a
echo @@ test range @@
@{
q $G/init a
cd a
touch f
a=`{commit -m a}
b=`{commit -m b -p $a}
c=`{commit -m c -p $b}
d=`{commit -m d -p $c}
e=`{commit -m e -p $d}
f=`{commit -m f -p $c}
g=`{commit -m g -p $f}
h=`{commit -m h -p $e -p $g}
map='
s/^'$a'$/a/
s/^'$b'$/b/
s/^'$c'$/c/
s/^'$d'$/d/
s/^'$e'$/e/
s/^'$f'$/f/
s/^'$g'$/g/
s/^'$h'$/h/
'
diff -u <{echo d; echo e; echo g; echo h} \
<{$G/$O.query $f..$h | sed -e $map} || die range
}
# b
# ↙ ↖
# f←e←d a
# ↖ ↙
# c
echo @@ test range 2 @@
@{
q $G/init b
cd b
touch f
a=`{commit -m a}
b=`{commit -m b -p $a}
c=`{commit -m c -p $a}
d=`{commit -m d -p $b -p $c}
e=`{commit -m e -p $d}
f=`{commit -m f -p $e}
map='
s/^'$a'$/a/
s/^'$b'$/b/
s/^'$c'$/c/
s/^'$d'$/d/
s/^'$e'$/e/
s/^'$f'$/f/
'
diff -u <{echo c; echo d; echo e; echo f} \
<{$G/$O.query $b..$f | sed -e $map} || die range
diff -u <{echo b; echo d; echo e; echo f} \
<{$G/$O.query $c..$f | sed -e $map} || die range
}

17
sys/src/cmd/git/test/util.rc Executable file
View file

@ -0,0 +1,17 @@
fn q {
{$* > /tmp/out.$pid && rm /tmp/out.$pid} || cat /tmp/out
}
fn qq {
$* >/dev/null >[2]/dev/null
}
fn die {
st=$status
if(! ~ $st ''){
*=($* : $st)
echo $"*
exit $"*
}
}
G=`{cleanname `{pwd}^/..}

View file

@ -11,6 +11,3 @@ OFILES=\
$O.test: test.$O $O.test: test.$O
$LD $LDFLAGS -o $target $prereq $LD $LDFLAGS -o $target $prereq
test:V: $O.test $O.out
$O.test $O.out

View file

@ -72,3 +72,6 @@ clean:V: cleancmds clean.dirs
nuke:V: cleancmds nuke.dirs nuke:V: cleancmds nuke.dirs
rm -f *.acid rm -f *.acid
test:VQ: test.dirs
@{cd test && mk $MKFLAGS test}

View file

@ -46,3 +46,9 @@ clean:V:
update:V: update:V:
update $UPDATEFLAGS $UPDATE update $UPDATEFLAGS $UPDATE
test:VQ: $LIB
if(test -d ./test)
cd test && mk $MKFLAGS test
if not
status=()

View file

@ -79,3 +79,10 @@ clean:V:
cp $stem.man $MAN/$stem cp $stem.man $MAN/$stem
man:V: $MANFILES man:V: $MANFILES
test:VQ: $PROGS
if(test -d ./test)
cd test && mk $MKFLAGS test
if not
status=()

View file

@ -60,3 +60,12 @@ $MAN/%: %.man
cp $prereq $target cp $prereq $target
man:V: $MAN/$TARG man:V: $MAN/$TARG
test:QV: $O.out $TESTDEP
if(test -d ./test){
pwd
@{cd ./test && mk $MKFLAGS test}
}
if not
status=()

View file

@ -41,3 +41,9 @@ nuke:V:
update:V: update:V:
update $UPDATEFLAGS $UPDATE update $UPDATEFLAGS $UPDATE
test:VQ:
if(test -d ./test)
cd test && mk $MKFLAGS test
if not
status=()

41
sys/src/cmd/mktest Normal file
View file

@ -0,0 +1,41 @@
test:VQ:
echo $t
for(t in $TEST) @{
if(test -d $t)
@{cd $t && mk $MKFLAGS test}
if not
mk $t.test
}
all:VQ:
# nothing
%.test:V: $O.%
./$O.$stem
%.test:V: %.rc
./$stem.rc
%.$O: $HFILES # don't combine with following %.$O rules
%.$O: %.c
$CC $CFLAGS $stem.c
%.$O: %.s
$AS $AFLAGS $stem.s
$O.%:V: %.$O $OFILES $LIB
$LD $LDFLAGS -o $target $prereq
# [$OS].??* avoids file names like 9.h
nuke:V:
rm -f *.[$OS] y.tab.? lex.yy.c y.debug y.output [$OS].??* *.acid $TARG $CLEANFILES
clean:V:
for(t in $TEST)
if(test -d $t)
@{cd $t && mk $MKFLAGS clean}
rm -f *.[$OS] *.a[$OS] y.tab.? lex.yy.c y.debug y.output [$OS].??* $TARG $CLEANFILES
%.clean:V:
rm -f $stem.[$OS] [$OS].$stem $stem.acid $stem

View file

@ -36,3 +36,8 @@ update:V:
echo update $i echo update $i
cd $i && mk 'UPDATEFLAGS='$"UPDATEFLAGS update cd $i && mk 'UPDATEFLAGS='$"UPDATEFLAGS update
} }
test:
for(d in $DIRS) @{
cd $d && mk $MKFLAGS test
}

View file

@ -48,3 +48,6 @@ $TARGETS:V:
cd $i; cd $i;
mk $target mk $target
} }
test:VQ:
# nothing

View file

@ -39,8 +39,3 @@ nuke:V:
clean:V: clean:V:
rm -f *.[$OS] [$OS].out [$OS].pcode y.tab.? y.debug y.output $TARG rm -f *.[$OS] [$OS].out [$OS].pcode y.tab.? y.debug y.output $TARG
test:V: $O.out brspell
time ./$O.out -b -f brspell </dev/null >y
time ./$O.out -b -f brspell <x >z
cmp y z

91
sys/src/cmd/test/date.rc Executable file
View file

@ -0,0 +1,91 @@
#!/bin/rc
rfork en
cat /adm/timezone/GMT > /env/timezone
nl='
'
fn check {
r=`$nl{../$O.seconds $1}
if(! ~ $r $2){
echo "$"r"
echo "$"2"
echo $status
>[1=2] echo fail: $1: got $r expected $2
exit 'fail'
}
}
# examples from manpage, and shuffles
rfork ne
check '23 may 2011' 1306108800
check 'may 23 2011' 1306108800
check 'may 2011 23' 1306108800
check '23 2011 may' 1306108800
check '2011 may 23' 1306108800
check '2011 23 may' 1306108800
# now with timezones
check '23 may 2011 edt' 1306123200
check '23 may 2011 gmt' 1306108800
# If the tz is present, the results should stay
# the same if we change zones.
@{
rfork en
cat /adm/timezone/US_Pacific >/env/timezone
check '23 may 2011 edt' 1306123200
check '23 may 2011 gmt' 1306108800
}
# now with all variations on times.
check 'may 23 2011 0' 1306108800
check 'may 23 2011 0:1' 1306108860
check 'may 23 2011 0:1:2' 1306108862
# now with times and timezones
check '23 may 2011 edt' 1306123200
check '23 may 2011 gmt' 1306108800
# formats from ../$O.date(1)
check 'Sun, 14 Jun 2020 22:08:48 -0700' 1592197728
check 'Sun, 14 Jun 2020 -0700' 1592118000
check '2020-06-14' 1592092800
check '2020-06-14T22:14:17-07:00' 1592198057
# colloquial american format (eww)
check '06/14/2020' 1592092800
check '06/01/2020' 1590969600
# Arizona has no DST
@{
rfork en
cat /adm/timezone/US_Arizona >/env/timezone
check 'Mon, Jun 21 17:38:02 MST 2020' 1592786282
}
# CET is a timezone with no hard-coded
# timezone name -- it should round trip
@{
rfork en
cat /adm/timezone/CET >/env/timezone
tm=1592782682
ds=`{../$O.date $tm}
r=`{../$O.seconds $"ds}
if(! ~ $tm $r)
>[1=2] echo fail: CET: got $r expected $tm
}
# The other EST should also round trip.
@{
rfork en
cat /adm/timezone/Australia_ACT >/env/timezone
tm=1592782682
ds=`$nl{../$O.date $tm}
r=`$nl{../$O.seconds $ds}
if(! ~ $tm $r)
>[1=2] echo fail: Austraila_ACT: got $r expected $tm
}
exit ''

9
sys/src/cmd/test/mkfile Normal file
View file

@ -0,0 +1,9 @@
</$objtype/mkfile
TEST=\
date\
patch\
ramfs\
test\
</sys/src/cmd/mktest

View file

@ -0,0 +1,100 @@
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

View file

@ -0,0 +1,93 @@
3
4
5
6
7
8
9
10
11
12
13
14
13
12
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
88
89
90
91
92
93
94
95
96
97
98

View file

@ -0,0 +1,42 @@
--- basic.in
+++ basic.out
@@ -1,3 +1,5 @@
+1
+2
3
4
5
@@ -10,8 +12,8 @@
12
13
14
-13
-12
+15
+16
17
18
19
@@ -35,6 +37,8 @@
37
38
39
+40
+41
42
43
44
@@ -80,6 +84,7 @@
84
85
86
+87
88
89
90
@@ -91,3 +96,5 @@
96
97
98
+99
+100

View file

@ -0,0 +1,12 @@
1
2
3
4
5
6
7
8
9
10
11
12

View file

@ -0,0 +1,15 @@
--- /dev/null
+++ create.out
@@ -1,0 +1,12 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12

View file

@ -0,0 +1,10 @@
1
2
3
4
5
6
7
8
9
10

View file

@ -0,0 +1,15 @@
--- delete.out
+++ /dev/null
@@ -1,12 +1,0 @@
-1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12

View file

@ -0,0 +1,100 @@
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

View file

@ -0,0 +1,93 @@
3
4
5
6
7
8
9
10
11
12
13
14
13
12
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
88
89
90
91
92
93
94
95
96
97
98

View file

@ -0,0 +1,54 @@
diff should handle headers just fine, so
this file contains a few lines of header
and footer, with a couple of false starts,
consisting of lines starting with
--- some words
but no immediately following
+++ words
lines
--- header.in
+++ header.out
@@ -1,3 +1,5 @@
+1
+2
3
4
5
@@ -10,8 +12,8 @@
12
13
14
-13
-12
+15
+16
17
18
19
@@ -35,6 +37,8 @@
37
38
39
+40
+41
42
43
44
@@ -80,6 +84,7 @@
84
85
86
+87
88
89
90
@@ -91,3 +96,5 @@
96
97
98
+99
+100
-- signature footer: should not get picked up
and here is the footer that should
also be ignored.

View file

@ -0,0 +1,5 @@
</$objtype/mkfile
TEST=patch
</sys/src/cmd/mktest

View file

@ -0,0 +1,89 @@
--- multifile2.in
+++ multifile2.out
@@ -1,21 +1,19 @@
-77777
77778
77779
77780
77781
77782
-77783
-77784
-77785
-77786
-77787
-77788
77789
+77788
+77787
+77786
+77785
+77784
+77783
77790
77791
77792
77793
77794
-77795
77796
77797
of course, each patch can have its own comment
lines mixed in, so we should handle these.
--- multifile1.in
+++ multifile1.out
@@ -14,16 +14,6 @@
12
17
18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
29
30
31
@@ -32,20 +22,6 @@
34
35
36
-37
-38
-39
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
53
54
55
@@ -73,11 +49,11 @@
77
78
79
-80
-81
-82
-83
84
+83
+82
+81
+80
85
86
88

View file

@ -0,0 +1,69 @@
3
4
5
6
7
8
9
10
11
12
13
14
13
12
17
18
29
30
31
32
33
34
35
36
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
84
83
82
81
80
85
86
88
89
90
91
92
93
94
95
96
97
98

View file

@ -0,0 +1,93 @@
3
4
5
6
7
8
9
10
11
12
13
14
13
12
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
88
89
90
91
92
93
94
95
96
97
98

View file

@ -0,0 +1,19 @@
77778
77779
77780
77781
77782
77789
77788
77787
77786
77785
77784
77783
77790
77791
77792
77793
77794
77796
77797

View file

@ -0,0 +1,21 @@
77777
77778
77779
77780
77781
77782
77783
77784
77785
77786
77787
77788
77789
77790
77791
77792
77793
77794
77795
77796
77797

View file

@ -0,0 +1,10 @@
1
2
3
4
5
6
7
8
9
10

39
sys/src/cmd/test/patch/patch.rc Executable file
View file

@ -0,0 +1,39 @@
#!/bin/rc -e
fn check{
if(! cmp $1 $2){
>[2=1] echo fail: $1 $2
>[2=1] diff -u $1 $2
exit mismatch
}
status=()
}
fn checkpatch{
rm -f $1.out
../../$O.patch $1.patch
check $1.out $1.expected
}
checkpatch basic
checkpatch header
checkpatch create
seq 12 > delete.out
../../$O.patch delete.patch
test ! -f delete.out
rm -f multifile^(1 2)^.out
chmod 640 multifile1.in
chmod 400 multifile2.in
../../$O.patch multifile.patch
check multifile1.out multifile1.expected
check multifile2.out multifile2.expected
if(! ~ `{walk -ex multifile1.out} --rw-r-----)
exit misperm1
if(! ~ `{walk -ex multifile2.out} --rw-------)
exit misperm2
status=()

40
sys/src/cmd/test/ramfs.rc Executable file
View file

@ -0,0 +1,40 @@
#!/bin/rc
rfork e
attach='
Tversion 8192 9P2000
Rversion 8192 9P2000
Tattach 1 -1 '^$user^' ''''
Rattach {0,0,d}
Twalk 1 2
Rwalk
'
fn assert{
aux/9pcon -ac '../6.ramfs -i' >/dev/null || exit $status
}
# attach
assert <<.
$attach
.
# create/write/read
assert <<.
$attach
Tcreate 2 testfile 777 2
Rcreate {1,0,0} 0
Twrite 2 0 hello
Rwrite 5
Tclunk 2
Rclunk
Twalk 1 2 testfile
Rwalk {1,2,0}
Topen 2 0
Ropen {1,2,0} 0
Tread 2 0 5
Rread hello
Tclunk 2
Rclunk
.

135
sys/src/cmd/test/test.rc Executable file
View file

@ -0,0 +1,135 @@
#!/bin/rc
rfork e
ERROR=0
FAILED=0
fn t{
# $1 -> exit code
# $2 -> $test expression
expect=$1
shift
# check for syntax errors
syntax=`{../$O.test $* >[2=1]}
if(~ $"syntax ''){
switch($expect){
case 0
if(! ../$O.test $*) failed $expect $*
case 1
if(../$O.test $*) failed $expect $*
}
}
if not
error
}
fn error{
echo
echo ' '^$"syntax
ERROR=`{echo $ERROR 1 + p | dc}
}
fn failed{
echo -n $1^': test' $*(2-)^'^: failed'
echo ' failed'
FAILED=`{echo $FAILED 1 + p | dc}
}
t 0 b '=' b
t 1 b '!=' b
t 0 '(' b '=' b ')'
t 1 ! '(' b '=' b ')'
t 1 ! -f /bin/rc
t 0 -h '=' -h
t 0 -o '=' -o
#t 1 -f '=' h
t 1 -h '=' f
t 1 -o '=' f
t 1 f '=' -o
t 0 '(' -h '=' -h ')'
t 1 '(' a '=' -h ')'
#t 1 '(' -f '=' h ')'
t 0 -h '=' -h -o a
t 0 '(' -h '=' -h ')' -o 1
t 0 -h '=' -h -o -h '=' -h
t 0 '(' -h '=' -h ')' -o '(' -h '=' -h ')'
t 0 roedelheim '=' roedelheim
t 1 potsdam '=' berlin-dahlem
t 0 -d /
t 0 -d / -a a '!=' b
t 1 -z -z
t 0 -n -n
t 0 0
t 0 '(' 0 ')'
t 0 '-E'
t 0 -X -a -X
t 0 -XXX
t 0 '(' -E ')'
t 0 true -o X
t 0 true -o -X
t 0 '(' '(' '(' a '=' a ')' -o 1 ')' -a 1 ')'
#t 1 -h /
t 0 -r /
t 1 -w /dev/zero
t 0 -w /dev/null
t 1 -x /dev/null
t 0 -x /bin/rc
#t 0 -c /dev/null
#t 0 -b /dev/fd0a -o -b /dev/rfd0a -o true
t 0 -f /adm/users
t 0 -s /adm/users
t 1 ! '(' 700 -le 1000 -a -n 1 -a 20 '=' 20 ')'
t 0 100 -eq 100
t 0 100 -lt 200
t 1 1000 -lt 200
t 0 1000 -gt 200
t 0 1000 -ge 200
t 0 1000 -ge 1000
t 1 2 -ne 2
t 0 0 -eq 0
t 1 -5 -eq 5
t 0 '(' 0 -eq 0 ')'
t 1 1 -eq 0 -o a '=' a -a 1 -eq 0 -o a '=' aa
#t 0 '" +123 " -eq 123'
#t 1 '"-123 " -gt " -1"'
t 0 123 -gt -123
t 0 -0 -eq +0
t 1 +0 -gt 0
t 0 0 -eq 0
t 0 0000 -eq -0
t 0 -1 -gt -2
t 1 1 -gt 2
t 1 4294967296 -eq 0
t 0 12345678901234567890 -eq +12345678901234567890
t 1 '' -o ''
t 1 '' -a ''
t 1 a -a ''
t 0 a -a ! ''
t 1 ''
t 0 ! ''
t 0 1 -eq 1
t 1 ! 1 -eq 1
t 0 ! ! 1 -eq 1
t 1 ! ! ! 1 -eq 1
t 1 ! '(' XXX -o XXX ')'
t 0 ! '(' ! '(' XXX -o XXX ')' ')'
if(! ~ $ERROR 0 || ! ~ $FAILED 0){
echo
echo 'Syntax errors:' $ERROR 'Failed:' $FAILED
}
if(! ~ $ERROR 0 || ! ~ $FAILED 0)
exit 'failures'
exit ''

19
sys/src/cmd/test/zones.rc Executable file
View file

@ -0,0 +1,19 @@
#!/bin/rc
rfork en
msg=()
for(f in /adm/timezone/*){
if(! ~ $f /adm/timezone/README){
cat $f >/env/timezone
tm=`{../6.date -f'WW, DD MMM YYYY hh:mm:ss Z'}
x=`{../6.date -n}
y=`{../6.seconds $"tm}
if(! ~ $x $y){
echo $f $tm $x $y are not equal
msg=($msg $f)
}
}
}
exit $"msg

View file

@ -27,4 +27,7 @@ nuke:V:
$BIN/%: %.rc $BIN/%: %.rc
cp $stem.rc $BIN/$stem cp $stem.rc $BIN/$stem
test:VQ:
# nothing
<../mkupas <../mkupas

View file

@ -43,3 +43,14 @@ safeinstallall:V:
cd $i cd $i
mk safeinstallall mk safeinstallall
} }
test:V:
for (i in $LIBS) @{
cd $i
mk test
}
for (i in $PROGS) @{
cd $i
mk test
}

View file

@ -28,9 +28,3 @@ compat.$O: ../cc/compat
x:V: $O.out x:V: $O.out
$O.out -la -o/dev/null x.v $O.out -la -o/dev/null x.v
test:V: $O.out
rm -f xxx
mv $O.out xxx
./xxx $OFILES
cmp $O.out xxx

View file

@ -49,3 +49,6 @@ everything:V:
mk $MKFLAGS install mk $MKFLAGS install
} }
rm -f */*.[012456789kqvxz] rm -f */*.[012456789kqvxz]
test:V:
cd test && mk $MKFLAGS test

377
sys/src/libc/test/date.c Normal file
View file

@ -0,0 +1,377 @@
#include <u.h>
#include <libc.h>
int failed;
/*
* For debugging
*/
void
printtm(Tm *tm)
{
fprint(2, "sec=%d min=%d hour=%d mday=%d mon=%d"
" year=%d day=%d yday=%d zone=%s tzoff=%d\n",
tm->sec, /* seconds (range 0..59) */
tm->min, /* minutes (0..59) */
tm->hour, /* hours (0..23) */
tm->mday, /* day of the month (1..31) */
tm->mon, /* month of the year (0..11) */
tm->year, /* year A.D. - 1900 */
tm->wday, /* day of week (0..6, Sunday = 0) */
tm->yday, /* day of year (0..365) */
tm->zone, /* time zone name */
tm->tzoff); /* time zone delta from GMT */
}
void
fail(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprint(2, "failed: ");
vfprint(2, fmt, ap);
va_end(ap);
failed++;
}
void
testtm(char *s, int year, int mon, int mday, int hour, int min, int sec, int nsec, Tm *tm){
if(tm->year != year-1900) fail("%s wrong year expected=%d actual=%d\n", s, year, tm->year);
if(tm->mon != mon) fail("%s wrong month expected=%d actual=%d\n", s, mon, tm->mon);
if(tm->mday != mday) fail("%s wrong mday expected=%d actual=%d\n", s, mday, tm->mday);
if(tm->hour != hour) fail("%s wrong hour expected=%d actual=%d\n", s, hour, tm->hour);
if(tm->min != min) fail("%s wrong min expected=%d actual=%d\n", s, min, tm->min);
if(tm->sec != sec) fail("%s wrong sec expected=%d actual=%d\n", s, sec, tm->sec);
if(tm->nsec != nsec) fail("%s wrong nsec expected=%d actual=%d\n", s, nsec, tm->nsec);
}
void
rangechk(vlong sec, char *s, vlong val, vlong lo, vlong hi)
{
if(val < lo || val > hi){
fprint(2, "%lld: %s: expected %lld <= %lld <= %lld", sec, s, lo, val, hi);
failed++;
}
}
void
main(int, char **)
{
Tm tm, tt;
Tzone *gmt, *us_arizona, *us_eastern, *us_central;
Tm here, there;
Tzone *zl, *zp;
char buf[128], buf1[128];
int i, h;
long s;
tmfmtinstall();
if((gmt = tzload("GMT")) == nil)
sysfatal("nil gmt: %r\n");
if((us_arizona = tzload("US_Arizona")) == nil)
sysfatal("nil us_arizona: %r\n");
if((us_eastern = tzload("US_Eastern")) == nil)
sysfatal("nil us_eastern: %r\n");
if((us_central = tzload("US_Central")) == nil)
sysfatal("get zone: %r\n");
if((zl = tzload("local")) == nil)
sysfatal("load zone: %r\n");
if((zp = tzload("US_Pacific")) == nil)
sysfatal("load zone: %r\n");
if(tmnow(&here, zl) == nil)
sysfatal("get time: %r\n");
if(tmtime(&there, tmnorm(&here), zp) == nil)
sysfatal("shift time: %r\n");
for(i = 0; i < 1600826575; i += 3613){
tmtime(&tm, i, nil);
rangechk(i, "nsec", tm.nsec, 0, 1e9);
rangechk(i, "sec", tm.sec, 0, 59);
rangechk(i, "min", tm.min, 0, 59);
rangechk(i, "hour", tm.hour, 0, 23);
rangechk(i, "mday", tm.mday, 1, 31);
rangechk(i, "mon", tm.mon, 0, 11);
rangechk(i, "year", tm.year, 69 ,120);
rangechk(i, "wday", tm.wday, 0, 6);
rangechk(i, "yday", tm.yday, 0, 365);
}
tmtime(&tm, 1586574870, gmt);
testtm("tmtime-gmt", 2020, 3, 11, 3, 14, 30, 0, &tm);
tmtime(&tm, 1586574870, us_arizona);
testtm("tmtime-az", 2020, 3, 10, 20, 14, 30, 0, &tm);
tmtime(&tm, 0, gmt);
testtm("tmtime-0-gmt", 1970, 0, 1, 0, 0, 0, 0, &tm);
tmnorm(&tm);
testtm("tmnorm-0-gmt", 1970, 0, 1, 0, 0, 0, 0, &tm);
tmtime(&tm, 84061, gmt);
testtm("tmtime-near0-gmt", 1970, 0, 1, 23, 21, 1, 0, &tm);
tmnorm(&tm);
testtm("tmnorm-near0-gmt", 1970, 0, 1, 23, 21, 1, 0, &tm);
tmtime(&tm, 1586574870, us_arizona);
testtm("tmtime-recent-az", 2020, 3, 10, 20, 14, 30, 0, &tm);
tmnorm(&tm);
testtm("tmnorm-recent-az", 2020, 3, 10, 20, 14, 30, 0, &tm);
tmtime(&tm, 1586574870, us_eastern);
testtm("tmtime-recent-est", 2020, 3, 10, 23, 14, 30, 0, &tm);
tmnorm(&tm);
testtm("tmnorm-recent-est", 2020, 3, 10, 23, 14, 30, 0, &tm);
if(tmparse(&tm, "hhmm", "1600", gmt, nil) == nil)
sysfatal("failed parse: %r\n");
testtm("hhmm", 1970, 0, 1, 16, 0, 0, 0, &tm);
if(tmparse(&tm, "YYYY-MM-DD hh:mm:ss Z", "1969-12-31 16:00:00 -0800", nil, nil) == nil)
fail("parse failed: %r\n");
if(tmnorm(&tm) != 0)
fail("wrong result: %lld != 0\n", tmnorm(&tm));
if(tmparse(&tm, "YYYY MM DD", "1990,01,03", nil, nil) == nil)
fail("comma parse failed");
if(tmnorm(&tm) != 631324800)
fail("wrong result");
if(tmparse(&tm, "YYYY MM DD", "1990 ,\t01,03", nil, nil) == nil)
fail("comma parse failed");
if(tmnorm(&tm) != 631324800)
fail("wrong result");
if(tmparse(&tm, "YYYY MM DD hh:mm:ss", "1969 12 31 16:00:00", gmt, nil) == nil)
sysfatal("failed parse: %r\n");
testtm("parse-notz1", 1969, 11, 31, 16, 0, 0, 0, &tm);
if(tmparse(&tm, "YYYY MM DD hh:mm:ss", "1970 01 01 04:00:00", gmt, nil) == nil)
fail("failed parse: %r\n");
testtm("parse-notz2", 1970, 0, 1, 4, 0, 0, 0, &tm);
if(tmparse(&tm, "YYYY MM DD", "1970 01 01", gmt, nil) == nil)
fail("failed parse: %r\n");
testtm("parse-notz3", 1970, 0, 1, 0, 0, 0, 0, &tm);
if(tmparse(&tm, "YYYY MMMM DD WWW hh:mm:ss", "2020 April 10 Friday 16:04:00", gmt, nil) == nil)
sysfatal("failed parse: %r\n");
testtm("parse-notz4", 2020, 3, 10, 16, 4, 0, 0, &tm);
if(tmparse(&tm, "MM DD hh:mm:ss", "12 31 16:00:00", gmt, nil) == nil)
sysfatal("failed parse: %r\n");
testtm("parse-notz5", 1970, 11, 31, 16, 0, 0, 0, &tm);
if(tmparse(&tm, "MM DD h:mm:ss", "12 31 4:00:00", gmt, nil) == nil)
sysfatal("failed parse: %r\n");
testtm("parse-mmdd-hms", 1970, 11, 31, 4, 0, 0, 0, &tm);
if(tm.tzoff != 0) print("%d wrong tzoff expected=%d actual=%d\n", 6, 0, tm.tzoff);
if(tmparse(&tm, "YYYY MM DD hh:mm:ss", "2020 04 10 23:14:30", us_eastern, nil) == nil)
fail("failed parse: %r\n");
testtm("parse-est", 2020, 3, 10, 23, 14, 30, 0, &tm);
tmtime(&tm, tmnorm(&tm), nil);
if(tmparse(&tm, "YYYY MM DD hh:mm:ss", "2020 04 10 20:14:30", us_arizona, nil) == nil)
fail("failed parse: %r\n");
testtm("parse-az", 2020, 3, 10, 20, 14, 30, 0, &tm);
if(tmparse(&tm, "YYYY MM DD hh:mm:ss ZZZ", "2020 04 10 20:14:30 EST", us_arizona, nil) == nil)
fail("failed parse: %r\n");
testtm("parse-tz1", 2020, 3, 10, 17, 14, 30, 0, &tm);
if(tmparse(&tm, "YYYY MM DD hh:mm:ss Z", "2020 04 10 20:14:30 -0400", nil, nil) == nil)
fail("failed parse: %r\n");
testtm("parse-tz2", 2020, 3, 10, 20, 14, 30, 0, &tm);
snprint(buf, sizeof(buf), "", tmfmt(&tm, "YYYY MM DD hh:mm:ss Z"));
if(strcmp(buf, "2020 04 10 20:14:30 -0400") != 0)
fail("failed format: %s != 2020 04 10 20:14:30 -0400", buf);
if(tmparse(&tm, "YYYY MM DD hh:mm:ss.ttt", "2020 04 10 20:14:30.207", nil, nil) == nil)
fail("failed parse: %r\n");
testtm("parse-milliseconds", 2020, 3, 10, 20, 14, 30, 207*1000*1000, &tm);
if(tmparse(&tm, "YYYY MM DD hh:mm:ss.nnn", "2020 04 10 20:14:30.207", nil, nil) == nil)
fail("failed parse: %r\n");
testtm("parse-nanoseconds", 2020, 3, 10, 20, 14, 30, 207, &tm);
if(tmparse(&tm, "YYYY MM DD hh:mm:ss.nnn", "2020 04 10 20:14:30.999", nil, nil) == nil)
fail("failed parse: %r\n");
testtm("parse-nnn2", 2020, 3, 10, 20, 14, 30, 999, &tm);
snprint(buf, sizeof(buf), "", tmfmt(&tm, "YYYY MM DD hh:mm:ss.nnn"));
if(strcmp(buf, "2020 04 10 20:14:30.999") != 0)
fail("failed format: %s != 2020 04 10 20:14:30.999", buf);
if(tmparse(&tm, "YYYY MM DD hh:mm:ss.ttt", "2020 04 10 20:14:30.999", nil, nil) == nil)
fail("failed parse: %r\n");
testtm("parse-nnn2", 2020, 3, 10, 20, 14, 30, 999*1000*1000, &tm);
snprint(buf, sizeof(buf), "", tmfmt(&tm, "YYYY MM DD hh:mm:ss.ttt"));
if(strcmp(buf, "2020 04 10 20:14:30.999") != 0)
fail("failed format: %s != 2020 04 10 20:14:30.999", buf);
/* edge case: leap year feb 29 */
if(tmparse(&tm, "YYYY MM DD hh:mm:ss Z", "2020 02 29 20:14:30 -0400", nil, nil) == nil)
fail("failed leap year feb 29: %r\n");
testtm("parse-leapfeb", 2020, 1, 29, 20, 14, 30, 0, &tm);
if(tmparse(&tm, "YYYY MM DD hh:mm:ss Z", "2021 02 29 20:14:30 -0400", nil, nil) != nil)
fail("incorrectly accepted non-leap year feb 29\n");
/* stray spaces */
if(tmparse(&tm, "YYYY MM DD hh:mm:ss Z", " 2020 02 29 20:14:30 -0400 ", nil, nil) == nil)
fail("failed leap year feb 29: %r\n");
/* lots of round trips: Jan 1960 => Jun 2020, in almost-11 day increments */
for(i = -315619200; i < 1592179806; i += 23*3600 + 1732){
if(tmtime(&tm, i, nil) == nil)
fail("load time %d\n", i);
if(tmnorm(&tm) != i)
fail("wrong load time: %d\n", i);
if(snprint(buf, sizeof(buf), "", tmfmt(&tm, "WW MMM DD hh:mm:ss Z YYYY")) == -1)
fail("format: %r\n");
if(tmparse(&tt, "WW MMM DD hh:mm:ss Z YYYY", buf, nil, nil) == nil)
fail("parse: %r\n");
if(tmnorm(&tm) != tmnorm(&tt))
fail("parse: wrong time (%lld != %lld)\n", tmnorm(&tm), tmnorm(&tt));
}
/* lots of round trips: Jan 1960 => Jun 2020, in almost-dailyincrements, now with timezone */
for(i = -315619200; i < 1592179806; i += 23*3600 + 1732){
if(tmtime(&tm, i, us_eastern) == nil)
fail("load time %d\n", i);
if(tmnorm(&tm) != i)
fail("wrong load time: %d\n", i);
if(snprint(buf, sizeof(buf), "", tmfmt(&tm, "WW MMM DD hh:mm:ss Z YYYY")) == -1)
fail("format: %r\n");
if(tmparse(&tt, "WW MMM DD hh:mm:ss Z YYYY", buf, us_arizona, nil) == nil)
fail("parse: %r\n");
if(tmnorm(&tm) != tmnorm(&tt))
fail("parse: wrong time (%lld != %lld)\n", tmnorm(&tm), tmnorm(&tt));
tm = tt;
tmnorm(&tm);
testtm("norm-rt", tt.year + 1900, tt.mon, tt.mday, tt.hour, tt.min, tt.sec, 0, &tm);
}
if(tmtime(&tm, -624623143, nil) == nil)
fail("tmtime: %r");
if(snprint(buf, sizeof(buf), "", tmfmt(&tm, "WW, DD MMM YYYY hh:mm:ss Z")) == -1)
fail("format: %r");
if(strcmp(buf, "Fri, 17 Mar 1950 13:34:17 +0000") != 0)
fail("wrong output: %s\n", buf);
if(tmtime(&tm, -624623143, us_eastern) == nil)
fail("tmtime: %r");
if(snprint(buf, sizeof(buf), "", tmfmt(&tm, "WW, DD MMM YYYY hh:mm:ss Z")) == -1)
fail("format: %r");
if(strcmp(buf, "Fri, 17 Mar 1950 08:34:17 -0500") != 0)
fail("wrong output: %s\n", buf);
/* AM and PM parsing */
for(i = 0; i < 24; i++){
h = i % 12;
if(h == 0)
h = 12;
snprint(buf, sizeof(buf), "2021 02 01 %d:14:30 -0400", i);
snprint(buf1, sizeof(buf1), "2021 02 01 %d:14:30 -0400 %s", h, (i < 12) ? "AM" : "PM");
if(tmparse(&tm, "YYYY MM DD hh:mm:ss Z", buf, nil, nil) == nil)
fail("parse: %r\n");
if(tmparse(&tt, "YYYY MM DD hh:mm:ss Z A", buf1, nil, nil) == nil)
fail("parse: %r\n");
if(tmnorm(&tm) != tmnorm(&tt))
print("bad am/pm parsed: %s != %s (%lld != %lld)\n", buf, buf1, tmnorm(&tm), tmnorm(&tt));
}
/* Time zone boundaries: entering DST */
if(tmtime(&tm, 1520733600, us_eastern) == nil)
fail("tmtime: tz boundary");
if(snprint(buf, sizeof(buf), "", tmfmt(&tm, nil)) == -1)
fail("format: %r");
memset(&tm, 0, sizeof(tm));
if(tmparse(&tm, "WW MMM D hh:mm:ss ZZZ YYYY", buf, nil, nil) == nil)
fail("parse: %r\n");
if(tmnorm(&tm) != 1520733600)
fail("round trip timezone: %lld != 1520733600\n", tmnorm(&tm));
/* Time zone boundaries: leaving DST */
if(tmtime(&tm, 1541296800, us_eastern) == nil)
fail("tmtime: tz boundary");
if(snprint(buf, sizeof(buf), "", tmfmt(&tm, nil)) == -1)
fail("format: %r\n");
memset(&tm, 0, sizeof(tm));
if(tmparse(&tm, "WW MMM D hh:mm:ss ZZZ YYYY", buf, nil, nil) == nil)
fail("parse: %r");
if(tmnorm(&tm) != 1541296800)
fail("round trip timezone: %lld != 1541296800\n", tmnorm(&tm));
/* flexible date parsing */
if(tmparse(&tm, "?YYYY ?MM DD hh:mm:ss ?ZZZ", "89 04 10 20:14:30 -0400", nil, nil) == nil)
fail("failed parse: %r\n");
testtm("flexdates", 1989, 3, 10, 20, 14, 30, 0, &tm);
char **d, *flexdates[] = {
"1920 4 10 20:14:30 -0400",
"1920 04 10 20:14:30 -0400",
"1920 Apr 10 20:14:30 -0400",
"1920 Apr 10 20:14:30 -04:00",
"1920 Apr 10 20:14:30 -04:00",
"1920 Apr 10 20:14:30 -04:00",
"1920 April 10 20:14:30 EDT",
"20 April 10 20:14:30 EDT",
nil,
};
for(d = flexdates; *d; d++){
if(tmparse(&tm, "?YYYY ?MM DD hh:mm:ss ?ZZZ", *d, nil, nil) == nil)
fail("failed parse: %r\n");
testtm("flexdates", 1920, 3, 10, 20, 14, 30, 0, &tm);
}
/* Fuzzy zone */
if(tmparse(&tm, "?YYYY ?MM DD hh:mm:ss ?ZZZ", "2020 04 10 20:14:30 NOPE", nil, nil) == nil)
fail("failed parse: %r\n");
testtm("fuzzy-nonzone", 2020, 3, 10, 20, 14, 30, 0, &tm);
/* test tmnorm() offset */
memset(&tm, 0, sizeof(Tm));
tm.year = 120;
tm.sec=0;
tm.min=0;
tm.hour=0;
tm.mday=22;
tm.mon=5;
tm.tz=us_central;
tmnorm(&tm);
if(tmnorm(&tm) != 1592802000)
fail("tmnorm is not using the daylight savings time offset. %lld != 1592809200\n", tmnorm(&tm));
memset(&tm, 0, sizeof(Tm));
if(tmnow(&tm, us_central) == nil)
fail("tmnow(): %r");
tm.year = 120;
tm.sec=0;
tm.min=0;
tm.hour=0;
tm.mday=22;
tm.mon=5;
tm.tz=us_central;
s = tmnorm(&tm);
if(s != 1592802000)
fail("tmnorm is not using the daylight savings time offset. %lld != 1592809200\n", s);
tm.year = 120;
tm.sec=0;
tm.min=0;
tm.hour=0;
tm.mday=22;
tm.mon=0;
s = tmnorm(&tm);
if(s != 1579672800)
fail("tmnorm is not using the daylight savings time offset. %lld != 1579672800\n", s);
tm.tz=us_eastern;
s = tmnorm(&tm);
if(s != 1579669200)
fail("tmnorm converted to us_eastern. %lld != 1579669200\n", s);
tm.tz=us_central;
s = tmnorm(&tm);
if(s != 1579672800)
fail("tmnorm converted back to us_central. %lld != 1579672800\n", s);
if(failed)
exits("test failed");
exits(nil);
}

8
sys/src/libc/test/mkfile Normal file
View file

@ -0,0 +1,8 @@
</$objtype/mkfile
TEST=\
date\
pow\
strchr\
</sys/src/cmd/mktest

69
sys/src/libc/test/pow.c Normal file
View file

@ -0,0 +1,69 @@
#include <u.h>
#include <libc.h>
/* We try to match the results specified by posix */
void
main(void)
{
/*
* For any value of y (including NaN),
* if x is +1, 1.0 shall be returned.
*/
assert(pow(1.0, 132234.3) == 1.0);
assert(pow(1.0, NaN()) == 1.0);
/*
* For any value of x (including NaN),
* if y is ±0, 1.0 shall be returned.
*/
assert(pow(10213.7, 0.0) == 1.0);
assert(pow(NaN(), 0.0) == 1.0);
/*
* If x or y is a NaN, a NaN shall be returned (unless
* specified elsewhere in this description).
*/
assert(isNaN(pow(NaN(), NaN())));
assert(isNaN(pow(NaN(), 42.42)));
assert(isNaN(pow(42.42, NaN())));
/*
* For any odd integer value of y > 0,
* if x is ±0, ±0 shall be returned.
*/
assert(pow(0.0, 1.0) == 0.0);
assert(pow(0.0, 39.0) == 0.0);
assert(pow(-0.0, 1.0) == -0.0);
/*
* For y > 0 and not an odd integer,
* if x is ±0, +0 shall be returned.
*/
assert(pow(0.0, 2.0) == 0.0);
assert(pow(0.0, 34.0) == 0.0);
assert(pow(-0.0, 22.0) == 0.0);
/* If x is -1, and y is ±Inf, 1.0 shall be returned. */
assert(pow(-1.0, Inf(1)) == 1.0);
/* For |x| < 1, if y is -Inf, +Inf shall be returned. */
assert(isInf(pow(0.9, Inf(-1)), 1));
/* For |x| > 1, if y is -Inf, +0 shall be returned. */
assert(pow(1.1, Inf(-1)) == 0);
/* For |x| < 1, if y is +Inf, +0 shall be returned. */
assert(pow(0.9, Inf(1)) == 0.0);
/* For |x| > 1, if y is +Inf, +Inf shall be returned. */
assert(isInf(pow(1.1, Inf(1)), 1));
/* For y an odd integer < 0, if x is -Inf, -0 shall be returned. */
assert(pow(-7, Inf(-1)) == -0.0);
/* For y < 0 and not an odd integer, if x is -Inf, +0 shall be returned. */
assert(pow(Inf(-1), -0.3) == 0);
/* For y an odd integer > 0, if x is -Inf, -Inf shall be returned. */
assert(isInf(pow(Inf(-1), 7), -1));
/* For y > 0 and not an odd integer, if x is -Inf, +Inf shall be returned. */
assert(isInf(pow(Inf(-1), 19123.25324), 1));
/* For y < 0, if x is +Inf, +0 shall be returned. */
assert(pow(Inf(1), -1.3) == 0.0);
/* For y > 0, if x is +Inf, +Inf shall be returned. */
assert(isInf(pow(Inf(1), 1.7), 1));
exits(nil);
}

View file

@ -0,0 +1,47 @@
#include <u.h>
#include <libc.h>
void
chars(void)
{
char *z = "";
char *v = "foo bar ss";
char *e;
e = strchr(z, 0);
assert(e == z);
e = strchr(z, 'z');
assert(e == nil);
e = strchr(v, L'z');
assert(e == nil);
e = strchr(v, L'a');
assert(e == v+5);
e = strchr(v, 0);
assert(e == v+10);
}
void
runes(void)
{
Rune *z = L"";
Rune *c = L"foo βαρ ß";
Rune *e;
e = runestrchr(z, 0);
assert(e == z);
e = runestrchr(z, L'z');
assert(e == nil);
e = runestrchr(c, L'z');
assert(e == nil);
e = runestrchr(c, L'α');
assert(e == c+5);
e = runestrchr(c, 0);
assert(e == c+9);
}
void
main(void)
{
chars();
runes();
exits(nil);
}

View file

@ -33,6 +33,11 @@ everything:V:
} }
rm -f */*.[$OS] rm -f */*.[$OS]
test:VQ:
cd test && mk test
# really dev tools more than tests
test.$O: test.c /$objtype/include/u.h /sys/include/mp.h port/dat.h test.$O: test.c /$objtype/include/u.h /sys/include/mp.h port/dat.h
$CC -Iport test.c $CC -Iport test.c

View file

@ -50,4 +50,5 @@ main()
convtests(); convtests();
tests(); tests();
exits(nil);
} }

View file

@ -1,8 +1,9 @@
</$objtype/mkfile </$objtype/mkfile
TARG=test TEST=\
main
OFILES=\ OFILES=\
main.$O\
ld.$O\ ld.$O\
gen.tab.$O\ gen.tab.$O\
convtest.$O\ convtest.$O\
@ -11,7 +12,7 @@ HFILES=dat.h fns.h
CLEANFILES=gen.tab.c CLEANFILES=gen.tab.c
</sys/src/cmd/mkone </sys/src/cmd/mktest
gen.tab.c:D: testgen.rc gen.tab.c:D: testgen.rc
rc testgen.rc >gen.tab.c rc testgen.rc >gen.tab.c

View file

@ -39,3 +39,6 @@ everything:V:
mk $MKFLAGS install mk $MKFLAGS install
} }
rm -f */*.[$OS] rm -f */*.[$OS]
test:VQ:
# nothing

View file

@ -64,6 +64,3 @@ UPDATE=\
</sys/src/cmd/mksyslib </sys/src/cmd/mksyslib
# this code really can't handle any flow-analysis warnings # this code really can't handle any flow-analysis warnings
CFLAGS= CFLAGS=
test:V: $OFILES
ar vu libstdio.a $OFILES

View file

@ -50,7 +50,7 @@ SUBSYS=ape\
none:VQ: none:VQ:
echo mk all, install, clean, nuke, release, kernels, or libs echo mk all, install, clean, nuke, release, kernels, or libs
all install clean nuke:VQ: all install clean nuke test:VQ:
date date
for (i in $LIBS $SUBSYS $CMDS) @{ for (i in $LIBS $SUBSYS $CMDS) @{
cd $i cd $i