ww: put selected toolchain first in test PATH
This commit is contained in:
@@ -1632,6 +1632,88 @@ fn sepallocptrs(cap: i32) ([]*u8 | nomem) = {
|
||||
return value;
|
||||
};
|
||||
|
||||
type septestenv = struct {
|
||||
values: []str,
|
||||
path: str,
|
||||
};
|
||||
|
||||
// Pinned cmd/go gives each test binary PATH=$GOROOT/bin:$PATH. The selected
|
||||
// WW driver's sibling directory is the local toolchain-bin analogue. Remove
|
||||
// normal inherited PATH duplicates because lib/os/exec deliberately preserves
|
||||
// the concrete environment array while Go's os/exec keeps the appended value.
|
||||
fn sepmaketestenv(toolbin: str, out: *septestenv) bool = {
|
||||
let inherited: []str = os.getenvs();
|
||||
if (inherited.len == SEP_COUNT_MAX) {
|
||||
cerr("ww: cannot prepare test environment\n");
|
||||
return false;
|
||||
};
|
||||
let oldpath: str = "";
|
||||
match (os.getenv("PATH")) {
|
||||
case let value: str => oldpath = value;
|
||||
case void => void;
|
||||
};
|
||||
let total: i64 = 5i64 + (toolbin.len: i64);
|
||||
if (oldpath.len != 0) { total += 1i64 + (oldpath.len: i64); };
|
||||
if (total > SEP_COUNT_MAX: i64) {
|
||||
cerr("ww: cannot prepare test environment\n");
|
||||
return false;
|
||||
};
|
||||
let pathallocation: ([]u8 | nomem) = sepallocbytes(total: i32);
|
||||
let pathbytes: []u8;
|
||||
match (pathallocation) {
|
||||
case let value: []u8 => pathbytes = value;
|
||||
case nomem => {
|
||||
cerr("ww: cannot prepare test environment\n");
|
||||
return false;
|
||||
};
|
||||
};
|
||||
let prefix: str = "PATH=";
|
||||
let i: i32 = 0;
|
||||
for (i < prefix.len) { append(pathbytes, prefix[i]); i += 1; };
|
||||
i = 0;
|
||||
for (i < toolbin.len) { append(pathbytes, toolbin[i]); i += 1; };
|
||||
if (oldpath.len != 0) {
|
||||
append(pathbytes, ':');
|
||||
i = 0;
|
||||
for (i < oldpath.len) { append(pathbytes, oldpath[i]); i += 1; };
|
||||
};
|
||||
let pathenv: str = strings.frombytes(pathbytes);
|
||||
let envallocation: ([]str | nomem) = sepallocstrs(inherited.len + 1);
|
||||
let env: []str;
|
||||
match (envallocation) {
|
||||
case let value: []str => env = value;
|
||||
case nomem => {
|
||||
os.free(pathenv.ptr: *void, pathenv.len: u64);
|
||||
cerr("ww: cannot prepare test environment\n");
|
||||
return false;
|
||||
};
|
||||
};
|
||||
i = 0;
|
||||
let inserted: bool = false;
|
||||
for (i < inherited.len) {
|
||||
if (strings.hasprefix(inherited[i], "PATH=")) {
|
||||
if (!inserted) { append(env, pathenv); inserted = true; };
|
||||
} else {
|
||||
append(env, inherited[i]);
|
||||
};
|
||||
i += 1;
|
||||
};
|
||||
if (!inserted) { append(env, pathenv); };
|
||||
out.values = env;
|
||||
out.path = pathenv;
|
||||
return true;
|
||||
};
|
||||
|
||||
fn sepfreetestenv(env: *septestenv) void = {
|
||||
if (env.path.ptr != nil && env.path.len != 0) {
|
||||
os.free(env.path.ptr: *void, env.path.len: u64);
|
||||
};
|
||||
if (env.values.ptr != nil && env.values.cap != 0) {
|
||||
os.free(env.values.ptr: *void,
|
||||
(env.values.cap: u64) * (size(str): u64));
|
||||
};
|
||||
};
|
||||
|
||||
fn sepallocgraph(pkg: []seppkg, context: []sepcontext) (*sepgraph | nomem) = {
|
||||
let emptyfolds: []sepfoldentry;
|
||||
let value: *sepgraph = alloc(sepgraph{
|
||||
@@ -9186,21 +9268,30 @@ fn runsingletest(selfdir: *u8, src: *u8, incs: *u8, compileonly: i32,
|
||||
if (pattern != nil) {
|
||||
append(execargv, pathstr(pattern));
|
||||
};
|
||||
let env: []str = os.getenvs();
|
||||
let result: exec.result;
|
||||
exec.runstdio(pathstr(outp), execargv, env, &result);
|
||||
let rc: i32 = 1;
|
||||
if (result.termination == exec.termination.EXIT) {
|
||||
rc = result.code;
|
||||
} else { if (result.termination == exec.termination.ERROR) {
|
||||
if (result.code == 127) {
|
||||
cerr("ww: execve failed\n");
|
||||
rc = 127;
|
||||
} else {
|
||||
cerr("ww: process launch/wait failed\n");
|
||||
rc = -1;
|
||||
};
|
||||
let env: septestenv;
|
||||
let toolbin: *u8 = canonicaldir(pathstr(selfdir));
|
||||
if (toolbin == nil) {
|
||||
cerr("ww: cannot prepare test environment\n");
|
||||
} else { if (sepmaketestenv(pathstr(toolbin), &env)) {
|
||||
exec.runstdio(pathstr(outp), execargv, env.values, &result);
|
||||
sepfreetestenv(&env);
|
||||
if (result.termination == exec.termination.EXIT) {
|
||||
rc = result.code;
|
||||
} else { if (result.termination == exec.termination.ERROR) {
|
||||
if (result.code == 127) {
|
||||
cerr("ww: execve failed\n");
|
||||
rc = 127;
|
||||
} else {
|
||||
cerr("ww: process launch/wait failed\n");
|
||||
rc = -1;
|
||||
};
|
||||
}; };
|
||||
}; };
|
||||
if (toolbin != nil) {
|
||||
os.free(toolbin: *void, cstrlen(toolbin) + 1u64);
|
||||
};
|
||||
if (rc == 0 && deferredinstall
|
||||
&& sepinstalltestoutput(outp, outstem) != 0) { rc = 1; };
|
||||
if (owntmp) {
|
||||
|
||||
Reference in New Issue
Block a user