ref: 5932f72977cd3eec1d0e575d10bbae9709608278
dir: /mbld/test.myr/
use std
use "build.use"
use "clean.use"
use "deps.use"
use "opts.use"
use "parse.use"
use "types.use"
use "util.use"
use "config.use"
pkg bld =
const test : (b : build# -> void)
;;
const test = {b
var ok
var tests : (byte[:], byte[:])[:]
/* no implicit tests to run */
tests = [][:]
if std.fexists("test")
for tn in b.all
match gettarg(b.targs, tn)
| `Bin bt:
tests = std.sljoin(tests, buildtests(b, bt))
| `Lib lt:
tests = std.sljoin(tests, buildtests(b, lt))
| _:
/* nothing */
;;
;;
;;
for tn in b.all
match gettarg(b.targs, tn)
| `Test t:
if t.incpath.len == 0 || !std.sleq(t.incpath[0], ".")
t.incpath = std.slput(t.incpath, 0, std.sldup("."))
;;
buildbin(b, t, false)
tests = std.slpush(tests, (std.strcat("./", t.name), std.sldup(t.dir)))
| _:
/* skip */
;;
;;
ok = true
for (bin, dir) in tests
setdir(b, dir)
if !runtest(bin)
ok = false
;;
;;
for (bin, dir) in tests
std.slfree(bin)
std.slfree(dir)
;;
std.slfree(tests)
if tests.len == 0
->
;;
if ok
std.put("TESTS PASSED\n")
else
std.put("TESTS FAILED\n")
;;
}
const buildtests = {b, targ
var tt, bin ,path, tests
tests = [][:]
setdir(b, targ.dir)
for s in targ.inputs
path = std.pathcat("./test", s)
if std.fexists(path)
bin = srcswapsuffix(path, "")
tt = [
.name = bin,
.dir = targ.dir,
.inputs = [path][:],
.install = false,
.libdeps = std.sldup(targ.libdeps),
.incpath = std.slput(std.sldup(targ.incpath), 0, "."),
]
cleantest(b, path)
buildbin(b, &tt, true)
tests = std.slpush(tests, (std.strcat("./", bin), std.sldup(targ.dir)))
std.slfree(tt.libdeps)
std.slfree(tt.incpath)
;;
std.slfree(path)
;;
-> tests
}
const cleantest = {b, src
var obj, bin, log, usef
obj = srcswapsuffix(src, config.Objsuffix)
log = srcswapsuffix(src, ".log")
usef = srcswapsuffix(src, ".use")
bin = srcswapsuffix(src, "")
std.remove(obj)
std.remove(usef)
std.remove(log)
std.remove(bin)
std.slfree(obj)
std.slfree(usef)
std.slfree(log)
std.slfree(bin)
}
const runtest = {bin
var r, log
std.put("run {}:\t", bin)
log = std.strcat(bin, ".log")
match std.spork([bin][:])
| `std.Fail m:
std.fatal("unable to run test: {}\n", m)
| `std.Ok (pid, infd, outfd):
match std.fslurp(outfd)
| `std.Ok "": /* empty output; nothing to log */
| `std.Ok buf:
std.blat(log, buf, 0o644)
| `std.Fail m:
;;
std.slfree(log)
r = false
match std.wait(pid)
| `std.Wfailure: std.put("FAIL\n")
| `std.Wsignalled: std.put("CRASH\n")
| `std.Wsuccess:
std.put("PASS\n")
r = true
| _: std.put("???\n")
;;
;;
-> r
}