summaryrefslogtreecommitdiff
path: root/mbld/test.myr
blob: 4d4b2edafd63b8427c3be1bd140b2668056393e6 (plain)
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use std

use "build"
use "opts"
use "types"
use "util"
use "subtest"

use "config"

pkg bld =
	const test	: (b : build#, targs : byte[:][:] -> bool)
	const bench	: (b : build#, targs : byte[:][:] -> bool)
;;

const test = {b, targs
	-> go(b, targs, "test", false)
}

const bench = {b, targs
	-> go(b, targs, "bench", true)
}

const go = {b, targs, kind, isbench
	var failed, ok
	var tests

	if !buildtarg(b, kind)
		std.exit(1)
	;;
	if targs.len == 0
		tests = std.htgetv(b.deps.targs, kind, [][:])
	else
		tests = [][:]
		for t : targs
			match std.htget(b.deps.targs, t)
			| `std.Some tl:	std.sljoin(&tests, tl)
			| `std.None:	std.fatal("unknown test {}\n", t)
			;;
		;;
	;;
	ok = true
	failed = [][:]
	for t : tests
		if !runtest(b, t, isbench, &failed)
			ok = false
		;;
	;;
	std.chdir(b.basedir)

	if tests.len == 0
		-> true
	;;

	printfailed(failed)
	if ok
		mbldput("TESTS PASSED\n")
	else
		mbldput("TESTS FAILED\n")
	;;
	std.slfree(failed)
	-> ok
}

const printfailed = {failed
	if failed.len > 0
		mbldput("FAILURES: {}\n", failed.len)
		for t : failed
			mbldput("\t{}\n", t)
		;;
	;;
}

const runtest = {b, n, isbench, failed
	var dir, res, log, logfd
	var sub

	mbldput("run {}: ", n.lbl)
	dir = std.pathcat(b.basedir, n.wdir)
	std.chdir(dir)
	std.slfree(dir)
	match std.spork(n.cmd)
	| `std.Err m:
		std.fatal("\nunable to run test: {}\n", m)
	| `std.Ok (pid, infd, outfd):
		log = std.strcat(std.basename(n.lbl), ".log")
		logfd = std.try(std.openmode(log, std.Owrite | std.Ocreat, 0o644))
		sub = showsub(b, n.lbl, outfd, logfd, failed)
		std.slfree(log)
		std.close(infd)
		std.close(outfd)

		res = false
		match std.wait(pid)
		| `std.Waiterror:	mbldput("FUCK pid {}\n", pid)
		| `std.Wfailure:	mbldput("FAIL\n")
		| `std.Wsignalled:	mbldput("CRASH\n")
		| `std.Wsuccess:
			res = true
			/* if we have subtests, we've already printed the output */
			match sub
			| `std.Some r:	res = r
			| `std.None:
				if isbench
					mbldput("MISSING TIMING\n")
					res = false
				else
					mbldput("PASS\n")
				;;
			;;
		;;
		if !res
			std.slpush(failed, std.fmt("{j= }", n.cmd))
		;;
	;;
	-> res
}