From: ori@eigenstate.org
To: 9front@9front.org
Subject: [9front] rfc: mk test
Date: Sun, 19 Feb 2023 16:32:21 -0500 [thread overview]
Message-ID: <08BC12625F8EB0CBF53E94B91F3AA31A@eigenstate.org> (raw)
we have gits://git.9front.org/plan9front/regress,
but I think it would be good to ship the tests
with the system, and have a single 'mk test' to
run them all.
this patch tweaks the system mkfiles to add the
ability to add a test/ directory, and a new mkfile
prototype to run them, as well as some initial
uses of it, pulled from regress/
in the process, it removes a few non-working and
outdated test targets from mkfiles.
thoughts?
diff c88417d972a9d952d66eb0d1bf471b96081402fd uncommitted
--- a//acme/mkfile
+++ b//acme/mkfile
@@ -1,9 +1,9 @@
</$objtype/mkfile
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 news/src; mk $target}
@{cd wiki/src; mk $target}
--- a//sys/src/ape/mkfile
+++ b//sys/src/ape/mkfile
@@ -27,3 +27,6 @@
9src.%:V:
cd 9src
mk $stem
+
+test:VQ:
+ # nothing
--- a//sys/src/cmd/audio/flacdec/mkfile
+++ b//sys/src/cmd/audio/flacdec/mkfile
@@ -4,7 +4,7 @@
TARGET=flacdec
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
$CC $CFLAGS -c $stem.c
@@ -19,3 +19,6 @@
install:V: $O.$TARGET
cp $O.$TARGET $BIN/$TARGET
+
+test:VQ:
+ # nothing
--- a//sys/src/cmd/audio/flacenc/mkfile
+++ b//sys/src/cmd/audio/flacenc/mkfile
@@ -19,3 +19,6 @@
install:V: $O.$TARGET
cp $O.$TARGET $BIN/$TARGET
+
+test:VQ:
+ # nothing
--- a//sys/src/cmd/audio/mkfile
+++ b//sys/src/cmd/audio/mkfile
@@ -60,3 +60,9 @@
cd $i
mk clean
}
+
+test:V:
+ for (i in $DIRS) @{
+ cd $i
+ mk test
+ }
--- a//sys/src/cmd/audio/mp3enc/mkfile
+++ b//sys/src/cmd/audio/mp3enc/mkfile
@@ -59,7 +59,3 @@
testcase.new.mp3: testcase.wav $O.out
$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
--- a//sys/src/cmd/audio/oggdec/mkfile
+++ b//sys/src/cmd/audio/oggdec/mkfile
@@ -19,3 +19,6 @@
install:V: $O.$TARGET
cp $O.$TARGET $BIN/$TARGET
+
+test:VQ:
+ # nothing
--- a//sys/src/cmd/audio/oggenc/mkfile
+++ b//sys/src/cmd/audio/oggenc/mkfile
@@ -19,3 +19,6 @@
install:V: $O.$TARGET
cp $O.$TARGET $BIN/$TARGET
+
+test:VQ:
+ # nothing
--- a//sys/src/cmd/bzip2/mkfile
+++ b//sys/src/cmd/bzip2/mkfile
@@ -18,7 +18,7 @@
CFLAGS=$CFLAGS -p -DPLAN9 -Ilib
-test:V: $O.bzip2 $O.bunzip2
+test_BUSTED: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
--- a//sys/src/cmd/cwfs/mkfile
+++ b//sys/src/cmd/cwfs/mkfile
@@ -13,3 +13,6 @@
cd cwfs64x && mk $stem
cleanall:V: clean emelie.clean fs64.clean cwfs64.clean cwfs64x.clean
+
+test:VQ:
+ # nothing
--- a//sys/src/cmd/ktrans/mkfile
+++ b//sys/src/cmd/ktrans/mkfile
@@ -11,6 +11,3 @@
$O.test: test.$O
$LD $LDFLAGS -o $target $prereq
-
-test:V: $O.test $O.out
- $O.test $O.out
--- a//sys/src/cmd/ktrans/test.c
+++ /dev/null
@@ -1,111 +1,0 @@
-#include <u.h>
-#include <libc.h>
-
-struct {
- char *input;
- Rune *expect;
-} set[] = {
- "n", L"ん",
- "\fno", L"の",
- "\fnno", L"んの",
- "\fneko\x1c", L"猫",
- "\fneko\x1c\x1c", L"ねこ",
- "\fwatashi\x1c", L"私",
- "\ftanoShi\x1c", L"楽し",
- "\foreNO\x1c", L"俺の",
-
- "\fwatashiHA\x1cmainichi\x1c35\ffun\x1cijou\x1caruIte,\x1csaraNI\x1c10\ffun\x1cdenshaNI\x1cnoTte\x1cgakkouNI\x1ckayoImasu.\x1c\nkenkouNO\x1cijiNImo\x1cyakuDAtteimasuga,\x1c\x1cnakanakatanoshiImonodesu.\n",
- L"私は毎日35分以上歩いて、更に10分電車に乗って学校に通います。\n健康の維持にも役だっていますが、なかなかたのしいものです。\n",
-};
-
-char*
-makemsg(char *s)
-{
- char *out, *d;
- int i, n;
-
- n = strlen(s) + 1;
- out = mallocz(n * 3, 1);
- for(d = out, i = 0; i < n; i++){
- *d++ = 'c';
- if(i == n - 1)
- *d++ = 1;
- else
- *d++ = s[i];
- *d++ = '\0';
- }
- return out;
-}
-
-void
-main(int argc, char **argv)
-{
- int io1[2], io2[2];
- int i;
- int n;
- char *p, *e;
- static char buf[256];
- Rune r;
- char *to;
- char *bin;
- static Rune stack[256];
- static int nstack;
-
- if(argc < 2)
- sysfatal("usage: %s binary", argv[0]);
-
- bin = argv[1];
- pipe(io1);
- pipe(io2);
- if(fork() == 0){
- dup(io1[0], 0);
- dup(io2[0], 1);
- close(io1[1]); close(io2[1]);
- execl(bin, "ktrans", "-l", "jp", "-G", nil);
- sysfatal("exec: %r");
- }
- close(io1[0]); close(io2[0]);
- for(i = 0; i < nelem(set); i++){
- nstack = 0;
- stack[nstack] = 0;
- to = makemsg(set[i].input);
- for(;;){
- write(io1[1], to, strlen(to) + 1);
- if(to[1] == 1)
- break;
- to += strlen(to)+1;
- }
- for(;;) {
- n = read(io2[1], buf, sizeof buf);
- if(n <= 0)
- break;
- e = buf + n;
- for(p = buf; p < e; p += (strlen(p)+1)){
- assert(*p == 'c');
- chartorune(&r, p+1);
- switch(r){
- case 1:
- goto Verify;
- case 8:
- if(nstack == 0)
- sysfatal("buffer underrun");
- nstack--;
- stack[nstack] = 0;
- break;
- default:
- stack[nstack++] = r;
- stack[nstack] = 0;
- break;
- }
- }
- }
- Verify:
- if(runestrcmp(set[i].expect, stack) != 0){
- fprint(2, "%S != %S\n", stack, set[i].expect);
- exits("fail");
- }
- }
- close(io1[1]); close(io2[1]);
- waitpid();
- exits(nil);
-}
--- /dev/null
+++ b//sys/src/cmd/ktrans/test/ktrans.c
@@ -1,0 +1,110 @@
+#include <u.h>
+#include <libc.h>
+
+struct {
+ char *input;
+ Rune *expect;
+} set[] = {
+ "n", L"ん",
+ "\fno", L"の",
+ "\fnno", L"んの",
+ "\fneko\x1c", L"猫",
+ "\fneko\x1c\x1c", L"ねこ",
+ "\fwatashi\x1c", L"私",
+ "\ftanoShi\x1c", L"楽し",
+ "\foreNO\x1c", L"俺の",
+
+ "\fwatashiHA\x1cmainichi\x1c35\ffun\x1cijou\x1caruIte,\x1csaraNI\x1c10\ffun\x1cdenshaNI\x1cnoTte\x1cgakkouNI\x1ckayoImasu.\x1c\nkenkouNO\x1cijiNImo\x1cyakuDAtteimasuga,\x1c\x1cnakanakatanoshiImonodesu.\n",
+ L"私は毎日35分以上歩いて、更に10分電車に乗って学校に通います。\n健康の維持にも役だっていますが、なかなかたのしいものです。\n",
+};
+
+char*
+makemsg(char *s)
+{
+ char *out, *d;
+ int i, n;
+
+ n = strlen(s) + 1;
+ out = mallocz(n * 3, 1);
+ for(d = out, i = 0; i < n; i++){
+ *d++ = 'c';
+ if(i == n - 1)
+ *d++ = 1;
+ else
+ *d++ = s[i];
+ *d++ = '\0';
+ }
+ return out;
+}
+
+void
+main(int argc, char **argv)
+{
+ int io1[2], io2[2];
+ int i;
+ int n;
+ char *p, *e;
+ static char buf[256];
+ Rune r;
+ char *to;
+ char *bin;
+ static Rune stack[256];
+ static int nstack;
+
+ bin = "../6.out";
+ if(argc >= 2)
+ bin = argv[1];
+ pipe(io1);
+ pipe(io2);
+ if(fork() == 0){
+ dup(io1[0], 0);
+ dup(io2[0], 1);
+ close(io1[1]); close(io2[1]);
+ execl(bin, "ktrans", "-l", "jp", "-G", nil);
+ sysfatal("exec: %r");
+ }
+ close(io1[0]); close(io2[0]);
+ for(i = 0; i < nelem(set); i++){
+ nstack = 0;
+ stack[nstack] = 0;
+ to = makemsg(set[i].input);
+ for(;;){
+ write(io1[1], to, strlen(to) + 1);
+ if(to[1] == 1)
+ break;
+ to += strlen(to)+1;
+ }
+ for(;;) {
+ n = read(io2[1], buf, sizeof buf);
+ if(n <= 0)
+ break;
+ e = buf + n;
+ for(p = buf; p < e; p += (strlen(p)+1)){
+ assert(*p == 'c');
+ chartorune(&r, p+1);
+ switch(r){
+ case 1:
+ goto Verify;
+ case 8:
+ if(nstack == 0)
+ sysfatal("buffer underrun");
+ nstack--;
+ stack[nstack] = 0;
+ break;
+ default:
+ stack[nstack++] = r;
+ stack[nstack] = 0;
+ break;
+ }
+ }
+ }
+ Verify:
+ if(runestrcmp(set[i].expect, stack) != 0){
+ fprint(2, "%S != %S\n", stack, set[i].expect);
+ exits("fail");
+ }
+ }
+ close(io1[1]); close(io2[1]);
+ waitpid();
+ exits(nil);
+}
--- /dev/null
+++ b//sys/src/cmd/ktrans/test/mkfile
@@ -1,0 +1,6 @@
+</$objtype/mkfile
+
+TEST=\
+ ktrans
+
+</sys/src/cmd/mktest
--- a//sys/src/cmd/mkfile
+++ b//sys/src/cmd/mkfile
@@ -72,3 +72,6 @@
nuke:V: cleancmds nuke.dirs
rm -f *.acid
+
+test:VQ: test.dirs
+ @{cd test && mk $MKFLAGS test}
--- a//sys/src/cmd/mklib
+++ b//sys/src/cmd/mklib
@@ -46,3 +46,9 @@
update:V:
update $UPDATEFLAGS $UPDATE
+
+test:VQ: $LIB
+ if(test -d ./test)
+ cd test && mk $MKFLAGS test
+ if not
+ status=()
--- a//sys/src/cmd/mkmany
+++ b//sys/src/cmd/mkmany
@@ -79,3 +79,10 @@
cp $stem.man $MAN/$stem
man:V: $MANFILES
+
+test:VQ: $PROGS
+ if(test -d ./test)
+ cd test && mk $MKFLAGS test
+ if not
+ status=()
+
--- a//sys/src/cmd/mkone
+++ b//sys/src/cmd/mkone
@@ -60,3 +60,12 @@
cp $prereq $target
man:V: $MAN/$TARG
+
+test:QV: $O.out $TESTDEP
+ if(test -d ./test){
+ pwd
+ @{cd ./test && mk $MKFLAGS test}
+ }
+ if not
+ status=()
+
--- a//sys/src/cmd/mksyslib
+++ b//sys/src/cmd/mksyslib
@@ -41,3 +41,9 @@
update:V:
update $UPDATEFLAGS $UPDATE
+
+test:VQ:
+ if(test -d ./test)
+ cd test && mk $MKFLAGS test
+ if not
+ status=()
--- a//sys/src/cmd/nusb/mkfile
+++ b//sys/src/cmd/nusb/mkfile
@@ -36,3 +36,8 @@
echo update $i
cd $i && mk 'UPDATEFLAGS='$"UPDATEFLAGS update
}
+
+test:
+ for(d in $DIRS) @{
+ cd $d && mk $MKFLAGS test
+ }
--- a//sys/src/cmd/postscript/mkfile
+++ b//sys/src/cmd/postscript/mkfile
@@ -48,3 +48,6 @@
cd $i;
mk $target
}
+
+test:VQ:
+ # nothing
--- a//sys/src/cmd/spell/mkfile
+++ b//sys/src/cmd/spell/mkfile
@@ -39,8 +39,3 @@
clean:V:
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
--- a//sys/src/cmd/upas/binscripts/mkfile
+++ b//sys/src/cmd/upas/binscripts/mkfile
@@ -27,4 +27,7 @@
$BIN/%: %.rc
cp $stem.rc $BIN/$stem
+test:VQ:
+ # nothing
+
<../mkupas
--- a//sys/src/cmd/upas/mkfile
+++ b//sys/src/cmd/upas/mkfile
@@ -43,3 +43,14 @@
cd $i
mk safeinstallall
}
+
+test:V:
+ for (i in $LIBS) @{
+ cd $i
+ mk test
+ }
+ for (i in $PROGS) @{
+ cd $i
+ mk test
+ }
+
--- a//sys/src/cmd/vl/mkfile
+++ b//sys/src/cmd/vl/mkfile
@@ -28,9 +28,3 @@
x:V: $O.out
$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
--- a//sys/src/libc/mkfile
+++ b//sys/src/libc/mkfile
@@ -49,3 +49,6 @@
mk $MKFLAGS install
}
rm -f */*.[012456789kqvxz]
+
+test:V:
+ cd test && mk $MKFLAGS test
--- /dev/null
+++ b//sys/src/libc/test/date.c
@@ -1,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);
+}
--- /dev/null
+++ b//sys/src/libc/test/mkfile
@@ -1,0 +1,9 @@
+</$objtype/mkfile
+
+TEST=\
+ date\
+ pow\
+ strchr\
+ zones\
+
+</sys/src/cmd/mktest
--- /dev/null
+++ b//sys/src/libc/test/pow.c
@@ -1,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);
+}
--- /dev/null
+++ b//sys/src/libc/test/strchr.c
@@ -1,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);
+}
--- /dev/null
+++ b//sys/src/libc/test/zones.rc
@@ -1,0 +1,19 @@
+#!/bin/rc
+
+rfork en
+
+msg=()
+for(f in /adm/timezone/*){
+ if(! ~ $f /adm/timezone/README){
+ cat $f >/env/timezone
+ tm=`{date -f'WW, DD MMM YYYY hh:mm:ss Z'}
+ x=`{date -n}
+ y=`{seconds $"tm}
+ if(! ~ $x $y){
+ echo $f $tm $x $y are not equal
+ msg=($msg $f)
+ }
+ }
+}
+
+exit $"msg
--- a//sys/src/libsec/mkfile
+++ b//sys/src/libsec/mkfile
@@ -39,3 +39,6 @@
mk $MKFLAGS install
}
rm -f */*.[$OS]
+
+test:VQ:
+ # nothing
--- a//sys/src/libstdio/mkfile
+++ b//sys/src/libstdio/mkfile
@@ -64,6 +64,3 @@
</sys/src/cmd/mksyslib
# this code really can't handle any flow-analysis warnings
CFLAGS=
-
-test:V: $OFILES
- ar vu libstdio.a $OFILES
--- a//sys/src/mkfile
+++ b//sys/src/mkfile
@@ -50,7 +50,7 @@
none:VQ:
echo mk all, install, clean, nuke, release, kernels, or libs
-all install clean nuke:VQ:
+all install clean nuke test:VQ:
date
for (i in $LIBS $SUBSYS $CMDS) @{
cd $i
reply other threads:[~2023-02-19 21:33 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=08BC12625F8EB0CBF53E94B91F3AA31A@eigenstate.org \
--to=ori@eigenstate.org \
--cc=9front@9front.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).