fix: handle empty junit failure lists
This commit is contained in:
parent
def3b5d9ce
commit
a6ddbcbe2a
@ -19,6 +19,7 @@
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed `crabbox run --junit` so all-passing JUnit files record results instead of leaving the coordinator run stuck when the failure list is empty.
|
||||
- Fixed native Windows `--shell` runs so multi-statement PowerShell scripts keep their quotes instead of being re-parsed by a nested PowerShell process.
|
||||
- Removed the static macOS managed-login path so static host VNC cannot be mistaken for a Crabbox-created external instance.
|
||||
- Excluded macOS AppleDouble `._*` sidecar files from default sync manifests so native Windows archives do not transfer invalid TypeScript/package sidecars.
|
||||
|
||||
@ -49,7 +49,11 @@ func parseJUnitResults(files map[string]string) (*TestResultSummary, error) {
|
||||
if len(files) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
summary := &TestResultSummary{Format: "junit", Files: make([]string, 0, len(files))}
|
||||
summary := &TestResultSummary{
|
||||
Format: "junit",
|
||||
Files: make([]string, 0, len(files)),
|
||||
Failed: []TestFailure{},
|
||||
}
|
||||
for name, data := range files {
|
||||
trimmed := strings.TrimSpace(data)
|
||||
if trimmed == "" {
|
||||
|
||||
@ -18,6 +18,24 @@ func TestParseJUnitResults(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseJUnitResultsInitializesEmptyFailureList(t *testing.T) {
|
||||
results, err := parseJUnitResults(map[string]string{"junit.xml": `<testsuite name="pkg" tests="1" failures="0" errors="0" skipped="0" time="0.1">
|
||||
<testcase classname="pkg.TestThing" name="passes"/>
|
||||
</testsuite>`})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if results == nil {
|
||||
t.Fatal("results nil")
|
||||
}
|
||||
if results.Failed == nil {
|
||||
t.Fatalf("failed slice is nil: %#v", results)
|
||||
}
|
||||
if len(results.Failed) != 0 {
|
||||
t.Fatalf("failed=%#v", results.Failed)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseMarkedFiles(t *testing.T) {
|
||||
files := parseMarkedFiles("\n__CRABBOX_RESULT_FILE__:a.xml\n<a/>\n__CRABBOX_RESULT_FILE__:b.xml\n<b/>\n")
|
||||
if files["a.xml"] != "<a/>" || files["b.xml"] != "<b/>" {
|
||||
|
||||
@ -1527,12 +1527,14 @@ function phaseForRunEvent(event: RunEventRecord): string {
|
||||
}
|
||||
|
||||
function boundedTestResults(results: TestResultSummary): TestResultSummary {
|
||||
const files = Array.isArray(results.files) ? results.files : [];
|
||||
const failed = Array.isArray(results.failed) ? results.failed : [];
|
||||
return {
|
||||
...results,
|
||||
files: results.files
|
||||
files: files
|
||||
.slice(0, MAX_RESULT_FILES)
|
||||
.map((file) => truncateString(file, MAX_RESULT_STRING_BYTES)),
|
||||
failed: results.failed.slice(0, MAX_RESULT_FAILURES).map(boundedTestFailure),
|
||||
failed: failed.slice(0, MAX_RESULT_FAILURES).map(boundedTestFailure),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -825,6 +825,49 @@ describe("fleet run history", () => {
|
||||
expect(await logs.text()).toBe("ok\n");
|
||||
});
|
||||
|
||||
it("accepts Go nil slices in passing test results", async () => {
|
||||
const fleet = testFleet();
|
||||
const create = await fleet.fetch(
|
||||
request("POST", "/v1/runs", {
|
||||
body: {
|
||||
leaseID: "cbx_000000000001",
|
||||
provider: "aws",
|
||||
class: "beast",
|
||||
serverType: "c7a.48xlarge",
|
||||
command: ["go", "test", "./..."],
|
||||
},
|
||||
}),
|
||||
);
|
||||
expect(create.status).toBe(201);
|
||||
const { run } = (await create.json()) as { run: { id: string } };
|
||||
|
||||
const finish = await fleet.fetch(
|
||||
request("POST", `/v1/runs/${run.id}/finish`, {
|
||||
body: {
|
||||
exitCode: 0,
|
||||
log: "ok\n",
|
||||
results: {
|
||||
format: "junit",
|
||||
files: null,
|
||||
suites: 1,
|
||||
tests: 1,
|
||||
failures: 0,
|
||||
errors: 0,
|
||||
skipped: 0,
|
||||
timeSeconds: 0.001,
|
||||
failed: null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
expect(finish.status).toBe(200);
|
||||
const finished = (await finish.json()) as {
|
||||
run: { results?: { files: string[]; failed: unknown[] } };
|
||||
};
|
||||
expect(finished.run.results?.files).toEqual([]);
|
||||
expect(finished.run.results?.failed).toEqual([]);
|
||||
});
|
||||
|
||||
it("records chunked run logs so failures do not disappear from long output", async () => {
|
||||
const storage = new MemoryStorage();
|
||||
const fleet = testFleet(storage);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user