ww: run directory tests from package source
This commit is contained in:
@@ -210,7 +210,7 @@ fn pkgappenddiscovered(st: *pkgdiscover, path: str) bool = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Preserve the caller's toolchain environment while pinning the locale and
|
// Preserve the caller's toolchain environment while pinning the locale and
|
||||||
// temporary directory used by the current build plan or test product.
|
// temporary directory used by the current build plan.
|
||||||
fn toolenv(tmpdir: str, out: *[]str) bool = {
|
fn toolenv(tmpdir: str, out: *[]str) bool = {
|
||||||
let inherited: []str = os.getenvs();
|
let inherited: []str = os.getenvs();
|
||||||
if (inherited.len > PKG_COUNT_MAX - 2) {
|
if (inherited.len > PKG_COUNT_MAX - 2) {
|
||||||
@@ -243,6 +243,73 @@ fn toolenv(tmpdir: str, out: *[]str) bool = {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn pkgfreeownedstr(value: str) void = {
|
||||||
|
if (value.ptr != nil && value.len != 0) {
|
||||||
|
os.free(value.ptr: *void, value.len: u64);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fn pkgfreestrs(values: []str) void = {
|
||||||
|
if (values.ptr != nil && values.cap != 0) {
|
||||||
|
os.free(values.ptr: *void,
|
||||||
|
(values.cap: u64) * (size(str): u64));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Go's AppendPWD appends, then os/exec keeps the last duplicate value. WW's
|
||||||
|
// executor preserves duplicates, so discard earlier exact PWD entries here.
|
||||||
|
fn runenv(tmpdir: str, pwd: str, out: *[]str, tmpowned: *str,
|
||||||
|
pwdowned: *str) bool = {
|
||||||
|
let inherited: []str = os.getenvs();
|
||||||
|
if (inherited.len > PKG_COUNT_MAX - 3) {
|
||||||
|
pkgputln(os.STDERR_FILENO,
|
||||||
|
"wwtest package: package graph is too large");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let allocation: ([]str | nomem) = pkgallocstrs(inherited.len + 3);
|
||||||
|
let env: []str;
|
||||||
|
match (allocation) {
|
||||||
|
case let value: []str => env = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
let i: i32 = 0;
|
||||||
|
for (i < inherited.len) {
|
||||||
|
if (!strings.hasprefix(inherited[i], "TMPDIR=")
|
||||||
|
&& !strings.hasprefix(inherited[i], "LC_ALL=")
|
||||||
|
&& !strings.hasprefix(inherited[i], "PWD=")) {
|
||||||
|
append(env, inherited[i]);
|
||||||
|
};
|
||||||
|
i += 1;
|
||||||
|
};
|
||||||
|
append(env, "LC_ALL=C");
|
||||||
|
let tmpenv: str;
|
||||||
|
if (!pkgstring(&tmpenv, "TMPDIR=", tmpdir)) {
|
||||||
|
pkgfreestrs(env);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let pwdenv: str;
|
||||||
|
if (!pkgstring(&pwdenv, "PWD=", pwd)) {
|
||||||
|
pkgfreeownedstr(tmpenv);
|
||||||
|
pkgfreestrs(env);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
append(env, tmpenv);
|
||||||
|
append(env, pwdenv);
|
||||||
|
*out = env;
|
||||||
|
*tmpowned = tmpenv;
|
||||||
|
*pwdowned = pwdenv;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn freerunenv(env: []str, tmpowned: str, pwdowned: str) void = {
|
||||||
|
pkgfreeownedstr(tmpowned);
|
||||||
|
pkgfreeownedstr(pwdowned);
|
||||||
|
pkgfreestrs(env);
|
||||||
|
};
|
||||||
|
|
||||||
fn pkgwrite(fd: i32, s: str) bool = {
|
fn pkgwrite(fd: i32, s: str) bool = {
|
||||||
let r: (i64 | os.oserror) = os.writeall(fd, s.ptr, s.len: u64);
|
let r: (i64 | os.oserror) = os.writeall(fd, s.ptr, s.len: u64);
|
||||||
match (r) {
|
match (r) {
|
||||||
@@ -1453,25 +1520,37 @@ fn pkgstartrun(g: *pkggroup, filters: []str, timeoutarg: str,
|
|||||||
};
|
};
|
||||||
append(ra, g.bin);
|
append(ra, g.bin);
|
||||||
let packagearg: str;
|
let packagearg: str;
|
||||||
if (!pkgstring(&packagearg, "-package=", g.pkg)) { return false; };
|
if (!pkgstring(&packagearg, "-package=", g.pkg)) {
|
||||||
|
pkgfreestrs(ra);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
append(ra, packagearg);
|
append(ra, packagearg);
|
||||||
if (list) { append(ra, "-list"); };
|
if (list) { append(ra, "-list"); };
|
||||||
if (timeoutarg.len != 0) { append(ra, timeoutarg); };
|
if (timeoutarg.len != 0) { append(ra, timeoutarg); };
|
||||||
let i: i32 = 0;
|
let i: i32 = 0;
|
||||||
for (i < filters.len) { append(ra, filters[i]); i += 1; };
|
for (i < filters.len) { append(ra, filters[i]); i += 1; };
|
||||||
let env: []str;
|
let env: []str;
|
||||||
if (!toolenv(g.root, &env)) { return false; };
|
let tmpowned: str;
|
||||||
|
let pwdowned: str;
|
||||||
|
if (!runenv(g.root, g.dir, &env, &tmpowned, &pwdowned)) {
|
||||||
|
pkgfreeownedstr(packagearg);
|
||||||
|
pkgfreestrs(ra);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
let rcmd: exec.command;
|
let rcmd: exec.command;
|
||||||
rcmd.path = g.bin;
|
rcmd.path = g.bin;
|
||||||
rcmd.argv = ra;
|
rcmd.argv = ra;
|
||||||
rcmd.env = env;
|
rcmd.env = env;
|
||||||
rcmd.dir = "";
|
rcmd.dir = g.dir;
|
||||||
rcmd.stdoutpath = g.runout;
|
rcmd.stdoutpath = g.runout;
|
||||||
rcmd.stderrpath = g.runerr;
|
rcmd.stderrpath = g.runerr;
|
||||||
rcmd.deadline.sec = 0i64;
|
rcmd.deadline.sec = 0i64;
|
||||||
rcmd.deadline.nsec = 0i64;
|
rcmd.deadline.nsec = 0i64;
|
||||||
rcmd.grace = 0i64: time.duration;
|
rcmd.grace = 0i64: time.duration;
|
||||||
exec.start(h, &rcmd);
|
exec.start(h, &rcmd);
|
||||||
|
freerunenv(env, tmpowned, pwdowned);
|
||||||
|
pkgfreeownedstr(packagearg);
|
||||||
|
pkgfreestrs(ra);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1758,8 +1837,7 @@ export fn packagecommand(args: []str) int = {
|
|||||||
pkgusage();
|
pkgusage();
|
||||||
return 2;
|
return 2;
|
||||||
};
|
};
|
||||||
// -o names the -c artifact; a plain run always executes from the
|
// A non-compile run leaves no caller-owned artifact for -o to name.
|
||||||
// temp root, so a caller-owned name has nothing to name.
|
|
||||||
if (outname.len != 0 && !compileonly) {
|
if (outname.len != 0 && !compileonly) {
|
||||||
pkgputln(os.STDERR_FILENO, "wwtest package: -o needs -c");
|
pkgputln(os.STDERR_FILENO, "wwtest package: -o needs -c");
|
||||||
return 2;
|
return 2;
|
||||||
|
|||||||
Reference in New Issue
Block a user