Skip to content

Commit

Permalink
Feat: Allow ignoring the classname attribute when calling `resolveF…
Browse files Browse the repository at this point in the history
…ileAndLine`. Fixes line number parsing for rust nextest junit output.
  • Loading branch information
ptsd committed Dec 3, 2024
1 parent 992d97d commit 46ab900
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 11 deletions.
46 changes: 46 additions & 0 deletions __tests__/testParser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,52 @@ describe('parseFile', () => {
])
})

it('should ignore classname when requested', async () => {
const testResult = await parseFile(
'test_results/nextest/basic.xml',
'',
false,
false,
false,
undefined,
undefined,
'/',
'',
undefined,
false,
-1,
true,
false,
undefined,
true)
expect(testResult).toBeDefined()
const {totalCount, skippedCount, globalAnnotations} = testResult!!
const filtered = globalAnnotations.filter(annotation => annotation.annotation_level !== 'notice')

expect(totalCount).toBe(3)
expect(skippedCount).toBe(0)
expect(filtered).toStrictEqual([
{
annotation_level: 'failure',
end_column: 0,
end_line: 154,
message: 'thread \'test_failure\' panicked at tests/parry3d.rs:154:5:\n' +
' assertion `left == right` failed: 0 must equal 1',
path: 'tests/parry3d.rs',
raw_details: 'thread \'test_failure\' panicked at tests/parry3d.rs:154:5:\n' +
' assertion `left == right` failed: 0 must equal 1\n' +
' left: 0\n' +
' right: 1\n' +
' note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace',
start_column: 0,
start_line: 154,
retries: 0,
status: 'failure',
title: 'oxidized_navigation::parry3d.test_failure'
}
])
})

it('should parse correctly fileName and line for a Java file with invalid chars', async () => {
const {fileName, line} = await resolveFileAndLine(
null,
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ inputs:
description: 'Truncate stack traces from test output to 2 lines in annotations'
required: false
default: 'true'
resolve_ignore_classname:
description: 'Force ignore classname in resolveFileAndLine (Fixes nextest annotations)'
required: false
default: 'false'
outputs:
total:
description: 'The total count of all checks'
Expand Down
4 changes: 3 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export async function run(): Promise<void> {
const annotationsLimit = Number(core.getInput('annotations_limit') || -1)
const skipAnnotations = core.getInput('skip_annotations') === 'true'
const truncateStackTraces = core.getBooleanInput('truncate_stack_traces')
const resolveIgnoreClassname = core.getBooleanInput('resolve_ignore_classname')

if (excludeSources.length === 0) {
excludeSources = ['/build/', '/__pycache__/']
Expand Down Expand Up @@ -91,7 +92,8 @@ export async function run(): Promise<void> {
followSymlink,
annotationsLimit,
truncateStackTraces,
failOnParseError
failOnParseError,
resolveIgnoreClassname
)
mergedResult.totalCount += testResult.totalCount
mergedResult.skipped += testResult.skipped
Expand Down
37 changes: 27 additions & 10 deletions src/testParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ export async function parseFile(
annotationsLimit = -1,
truncateStackTraces = true,
failOnParseError = false,
globalAnnotations: Annotation[] = []
globalAnnotations: Annotation[] = [],
resolveIgnoreClassname = false
): Promise<ActualTestResult | undefined> {
core.debug(`Parsing file ${file}`)

Expand Down Expand Up @@ -236,7 +237,8 @@ export async function parseFile(
followSymlink,
annotationsLimit,
truncateStackTraces,
globalAnnotations
globalAnnotations,
resolveIgnoreClassname
)
}

Expand All @@ -260,7 +262,8 @@ async function parseSuite(
followSymlink: boolean,
annotationsLimit: number,
truncateStackTraces: boolean,
globalAnnotations: Annotation[]
globalAnnotations: Annotation[],
resolveIgnoreClassname = false
): Promise<ActualTestResult | undefined> {
if (!suite) {
// not a valid suite, return fast
Expand Down Expand Up @@ -298,7 +301,8 @@ async function parseSuite(
transformer,
followSymlink,
truncateStackTraces,
limit
limit,
resolveIgnoreClassname
)

// expand global annotations array
Expand Down Expand Up @@ -348,7 +352,8 @@ async function parseSuite(
followSymlink,
annotationsLimit,
truncateStackTraces,
globalAnnotations
globalAnnotations,
resolveIgnoreClassname
)

if (childSuiteResult) {
Expand Down Expand Up @@ -398,7 +403,8 @@ async function parseTestCases(
transformer: Transformer[],
followSymlink: boolean,
truncateStackTraces: boolean,
limit = -1
limit = -1,
resolveIgnoreClassname = false
): Promise<TestCasesResult> {
const annotations: Annotation[] = []
let totalCount = 0
Expand Down Expand Up @@ -488,10 +494,15 @@ async function parseTestCases(
testcase._attributes.name
).trim()

let resolveClassname = testcase._attributes.name
if (!resolveIgnoreClassname && testcase._attributes.classname) {
resolveClassname = testcase._attributes.classname
}

const pos = await resolveFileAndLine(
testcase._attributes.file || failure?._attributes?.file || suiteFile,
testcase._attributes.line || failure?._attributes?.line || suiteLine,
testcase._attributes.classname ? testcase._attributes.classname : testcase._attributes.name,
resolveClassname,
stackTrace
)

Expand Down Expand Up @@ -530,7 +541,11 @@ async function parseTestCases(
.replace(templateVar('TEST_NAME'), testcase._attributes.name)
.replace(templateVar('CLASS_NAME'), className)
} else if (pos.fileName !== testcase._attributes.name) {
title = `${pos.fileName}.${testcase._attributes.name}`
if (resolveIgnoreClassname && testcase._attributes.classname) {
title = `${testcase._attributes.classname}.${testcase._attributes.name}`
} else {
title = `${pos.fileName}.${testcase._attributes.name}`
}
} else {
title = `${testcase._attributes.name}`
}
Expand Down Expand Up @@ -591,7 +606,8 @@ export async function parseTestReports(
followSymlink = false,
annotationsLimit = -1,
truncateStackTraces = true,
failOnParseError = false
failOnParseError = false,
resolveIgnoreClassname = false
): Promise<TestResult> {
core.debug(`Process test report for: ${reportPaths} (${checkName})`)
const globber = await glob.create(reportPaths, {followSymbolicLinks: followSymlink})
Expand Down Expand Up @@ -620,7 +636,8 @@ export async function parseTestReports(
annotationsLimit,
truncateStackTraces,
failOnParseError,
globalAnnotations
globalAnnotations,
resolveIgnoreClassname
)

if (!testResult) continue
Expand Down
50 changes: 50 additions & 0 deletions test_results/nextest/basic.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="nextest-run" tests="3" failures="1" errors="0" uuid="437f8a75-ec69-48cf-9bda-e3f5045c2c28" timestamp="2024-12-02T20:06:10.512+00:00" time="0.946">
<testsuite name="oxidized_navigation::parry3d" tests="3" disabled="0" errors="0" failures="1">
<testcase name="test_failure" classname="oxidized_navigation::parry3d" timestamp="2024-12-02T20:06:10.513+00:00" time="0.774">
<failure type="test failure">thread &apos;test_failure&apos; panicked at tests/parry3d.rs:154:5:
assertion `left == right` failed: 0 must equal 1
left: 0
right: 1
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace</failure>
<system-out>
running 1 test
test test_failure ... FAILED

failures:

failures:
test_failure

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.66s

</system-out>
<system-err>thread &apos;test_failure&apos; panicked at tests/parry3d.rs:154:5:
assertion `left == right` failed: 0 must equal 1
left: 0
right: 1
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
</system-err>
</testcase>
<testcase name="test_simple_navigation" classname="oxidized_navigation::parry3d" timestamp="2024-12-02T20:06:10.514+00:00" time="0.944">
<system-out>
running 1 test
test test_simple_navigation ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.70s

</system-out>
<system-err></system-err>
</testcase>
<testcase name="test_annotations" classname="oxidized_navigation::parry3d" timestamp="2024-12-02T20:06:10.512+00:00" time="0.945">
<system-out>
running 1 test
test test_annotations ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.74s

</system-out>
<system-err></system-err>
</testcase>
</testsuite>
</testsuites>

0 comments on commit 46ab900

Please sign in to comment.