ref: ee4d18f009f056f9079395f073799933bb80689c
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, bin, hastest
/* no implicit tests to run */
ok = true
hastest = false
if std.fexists("test")
hastest = true
for tn in b.all
match gettarg(b.targs, tn)
| `Bin bt:
if !dotest(b, bt)
ok = false
;;
| `Lib lt:
if !dotest(b, lt)
ok = false
;;
| _: /* ignore */
;;
;;
;;
for tn in b.all
match gettarg(b.targs, tn)
| `Test t:
hastest = true
if t.incpath.len == 0 || !std.sleq(t.incpath[0], ".")
t.incpath = std.slput(t.incpath, 0, std.sldup("."))
;;
buildbin(b, t, false)
| _:
/* skip */
;;
;;
for tn in b.all
match gettarg(b.targs, tn)
| `Test t:
setdir(b, t.dir)
bin = std.strcat("./", t.name)
if !runtest(bin)
ok = false
;;
std.slfree(bin)
| _:
/* skip */
;;
;;
if hastest
if ok
std.put("TESTS PASSED\n")
else
std.put("TESTS FAILED\n")
std.exit(1)
;;
;;
}
const dotest = {b, targ
var tt, bin ,path, tests, ok
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 = targ.libdeps,
.incpath = targ.incpath,
]
cleantest(b, path)
buildbin(b, &tt, true)
tests = std.slpush(tests, bin)
;;
std.slfree(path)
;;
ok = true
for t in tests
if !runtest(t)
ok = false
;;
std.slfree(t)
;;
std.slfree(tests)
std.put("test {}: {}\n", targ.name, ok)
-> ok
}
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
}