9front - general discussion about 9front
 help / color / mirror / Atom feed
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).