ww: print final status for explicit test failures
This commit is contained in:
@@ -372,6 +372,17 @@ fn pkgputln(fd: i32, s: str) void = {
|
||||
pkgput(fd, "\n");
|
||||
};
|
||||
|
||||
// Go's final test-status action is command-owned: after an explicit ordinary
|
||||
// package request records a setup, build, or run failure, it prints one final
|
||||
// FAIL after the ordered package results. Implicit current-directory testing
|
||||
// and compile-only testing deliberately do not use this action.
|
||||
fn pkgteststatusfail(explicitstatus: bool, compileonly: bool) int = {
|
||||
if (explicitstatus && !compileonly) {
|
||||
pkgputln(os.STDOUT_FILENO, "FAIL");
|
||||
};
|
||||
return 1;
|
||||
};
|
||||
|
||||
fn pkgputhexbyte(fd: i32, value: u8) void = {
|
||||
let digits: str = "0123456789abcdef";
|
||||
let encoded: [2]u8;
|
||||
@@ -1704,7 +1715,8 @@ fn pkgemitinstall(g: *pkggroup) bool = {
|
||||
return true;
|
||||
};
|
||||
|
||||
fn pkgemitgroup(g: *pkggroup, compileonly: bool) bool = {
|
||||
fn pkgemitgroup(g: *pkggroup, compileonly: bool,
|
||||
statusfailed: *bool) bool = {
|
||||
if (g.notests) {
|
||||
pkgput(os.STDOUT_FILENO, "? ");
|
||||
pkgput(os.STDOUT_FILENO, g.dir);
|
||||
@@ -1728,6 +1740,7 @@ fn pkgemitgroup(g: *pkggroup, compileonly: bool) bool = {
|
||||
pkgput(os.STDOUT_FILENO, "\n");
|
||||
};
|
||||
if (!pkgrunok(g)) {
|
||||
*statusfailed = true;
|
||||
pkgreportcommand(os.STDOUT_FILENO, "test", g, &g.runres);
|
||||
return false;
|
||||
};
|
||||
@@ -1740,7 +1753,7 @@ fn pkgemitgroup(g: *pkggroup, compileonly: bool) bool = {
|
||||
// A directory build capture is emitted once, followed by its independently
|
||||
// executed products in their existing byte-sorted group order.
|
||||
fn pkgemitplan(p: *pkgplan, groups: []pkggroup,
|
||||
compileonly: bool, buildonly: bool) i32 = {
|
||||
compileonly: bool, buildonly: bool, statusfailed: *bool) i32 = {
|
||||
let buildcaptures: bool = pkgemitfile(p.buildout, os.STDOUT_FILENO);
|
||||
buildcaptures = pkgemitfile(p.builderr, os.STDERR_FILENO) && buildcaptures;
|
||||
if (!buildcaptures) {
|
||||
@@ -1755,11 +1768,14 @@ fn pkgemitplan(p: *pkgplan, groups: []pkggroup,
|
||||
pkgreportcommand(os.STDERR_FILENO, "build", &groups[i],
|
||||
&p.buildres);
|
||||
};
|
||||
if (!buildonly && !compileonly) { *statusfailed = true; };
|
||||
failed += 1;
|
||||
} else if (buildonly) {
|
||||
void;
|
||||
} else {
|
||||
if (!pkgemitgroup(&groups[i], compileonly)) { failed += 1; };
|
||||
if (!pkgemitgroup(&groups[i], compileonly, statusfailed)) {
|
||||
failed += 1;
|
||||
};
|
||||
if (!compileonly && !pkgemitinstall(&groups[i])) { failed += 1; };
|
||||
};
|
||||
i += 1;
|
||||
@@ -1774,6 +1790,7 @@ export fn packagecommand(args: []str) int = {
|
||||
let jobs: i32 = 1;
|
||||
let afterdash: bool = false;
|
||||
let buildrootseen: bool = false;
|
||||
let explicitstatus: bool = false;
|
||||
if (args.len == PKG_COUNT_MAX) {
|
||||
pkgputln(os.STDERR_FILENO,
|
||||
"wwtest package: package graph is too large");
|
||||
@@ -1943,6 +1960,12 @@ export fn packagecommand(args: []str) int = {
|
||||
i += 2;
|
||||
continue;
|
||||
};
|
||||
if (strings.compare(a, "--ww-explicit-test-target") == 0) {
|
||||
if (explicitstatus || buildonly) { pkgusage(); return 2; };
|
||||
explicitstatus = true;
|
||||
i += 1;
|
||||
continue;
|
||||
};
|
||||
if (strings.compare(a, "--ww-operation") == 0) {
|
||||
if (i + 1 >= args.len || strings.compare(args[i + 1], "build") != 0
|
||||
|| buildonly) {
|
||||
@@ -2052,7 +2075,10 @@ export fn packagecommand(args: []str) int = {
|
||||
};
|
||||
i += 1;
|
||||
};
|
||||
if (ds.errors != 0) { return 1; };
|
||||
if (ds.errors != 0) {
|
||||
if (ds.fatal) { return 1; };
|
||||
return pkgteststatusfail(explicitstatus, compileonly);
|
||||
};
|
||||
pkgsortstrings(directroots.paths);
|
||||
directroots.paths = pkgdedup(directroots.paths);
|
||||
i = 0;
|
||||
@@ -2063,7 +2089,7 @@ export fn packagecommand(args: []str) int = {
|
||||
&canonicaloom)) {
|
||||
if (canonicaloom) { return 1; };
|
||||
pkgfailpath(ds.paths[i], "cannot canonicalize package directory");
|
||||
return 1;
|
||||
return pkgteststatusfail(explicitstatus, compileonly);
|
||||
};
|
||||
let canonicalsource: str;
|
||||
if (!pkgstring(&canonicalsource, canonicaldir, "/",
|
||||
@@ -2115,7 +2141,7 @@ export fn packagecommand(args: []str) int = {
|
||||
let pn: str;
|
||||
if (!pkgread(ds.paths[i], &body) || !pkgclause(body, &pn)) {
|
||||
pkgfailpath(ds.paths[i], "invalid or missing package clause");
|
||||
return 1;
|
||||
return pkgteststatusfail(explicitstatus, compileonly);
|
||||
};
|
||||
if (!pkgstring(&s.pkg, pn)) { return 1; };
|
||||
append(srcs, s);
|
||||
@@ -2221,7 +2247,8 @@ export fn packagecommand(args: []str) int = {
|
||||
} else {
|
||||
pkgfailpath(srcs[j].path,
|
||||
"test package must match production package or <package>_test");
|
||||
return 1;
|
||||
return pkgteststatusfail(explicitstatus,
|
||||
compileonly);
|
||||
};
|
||||
};
|
||||
j += 1;
|
||||
@@ -2242,7 +2269,8 @@ export fn packagecommand(args: []str) int = {
|
||||
&& strings.compare(srcs[j].pkg, secondpkg) != 0) {
|
||||
pkgfailpath(srcs[j].path,
|
||||
"test package must match production package or <package>_test");
|
||||
return 1;
|
||||
return pkgteststatusfail(explicitstatus,
|
||||
compileonly);
|
||||
};
|
||||
};
|
||||
j += 1;
|
||||
@@ -2253,7 +2281,8 @@ export fn packagecommand(args: []str) int = {
|
||||
if (family.len == 0) {
|
||||
pkgfailpath(f.path,
|
||||
"external test package has empty base name");
|
||||
return 1;
|
||||
return pkgteststatusfail(explicitstatus,
|
||||
compileonly);
|
||||
};
|
||||
hasexternal = true;
|
||||
externalpkg = firstpkg;
|
||||
@@ -2284,7 +2313,7 @@ export fn packagecommand(args: []str) int = {
|
||||
} else {
|
||||
pkgfailpath(f.path,
|
||||
"test package must match production package or <package>_test");
|
||||
return 1;
|
||||
return pkgteststatusfail(explicitstatus, compileonly);
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -2511,6 +2540,7 @@ export fn packagecommand(args: []str) int = {
|
||||
let planout: str = outname;
|
||||
if (buildnull) { planout = ""; };
|
||||
let failed: i32 = 0;
|
||||
let statusfailed: bool = false;
|
||||
i = 0;
|
||||
for (i < plans.len) {
|
||||
if (!pkgsetplanpaths(&plans[i], groups, tmproot, i,
|
||||
@@ -2675,7 +2705,8 @@ export fn packagecommand(args: []str) int = {
|
||||
|
||||
i = 0;
|
||||
for (i < plans.len) {
|
||||
failed += pkgemitplan(&plans[i], groups, compileonly, buildonly);
|
||||
failed += pkgemitplan(&plans[i], groups, compileonly, buildonly,
|
||||
&statusfailed);
|
||||
i += 1;
|
||||
};
|
||||
if (!pkgremoveall(tmproot)) {
|
||||
@@ -2683,6 +2714,9 @@ export fn packagecommand(args: []str) int = {
|
||||
pkgputln(os.STDERR_FILENO, tmproot);
|
||||
failed += 1;
|
||||
};
|
||||
if (statusfailed && explicitstatus && !compileonly) {
|
||||
pkgputln(os.STDOUT_FILENO, "FAIL");
|
||||
};
|
||||
if (failed != 0) { return 1; };
|
||||
return 0;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user