From d71eea30591e7ae46509ef40429a21bdec98d2e0 Mon Sep 17 00:00:00 2001 From: Ats Uiboupin Date: Fri, 18 Nov 2022 17:47:49 +0200 Subject: [PATCH 1/6] add .nvmrc --- .nvmrc | 1 + 1 file changed, 1 insertion(+) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..79bdb1b --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v18.7.0 From b41f73092267c3cdcef4f2429da4bc16ba75d51e Mon Sep 17 00:00:00 2001 From: Ats Uiboupin Date: Fri, 18 Nov 2022 17:50:14 +0200 Subject: [PATCH 2/6] ignore IntelliJ Idea IDE folder --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 639696a..f43ecf7 100644 --- a/.gitignore +++ b/.gitignore @@ -100,3 +100,5 @@ lib/**/* # Project specific __tests__/__results__ + +.idea From e5edb614dd907808b3ca9fb02002c097c9f12e8b Mon Sep 17 00:00:00 2001 From: Ats Uiboupin Date: Fri, 18 Nov 2022 20:27:44 +0200 Subject: [PATCH 3/6] refactor: extract parsing java StackTraceElement to allow improving --- .../java-stack-trace-element-parser.test.ts | 40 +++++++++++++++++++ src/parsers/java-junit/java-junit-parser.ts | 8 ++-- .../java-stack-trace-element-parser.ts | 22 ++++++++++ 3 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 __tests__/java-stack-trace-element-parser.test.ts create mode 100644 src/parsers/java-junit/java-stack-trace-element-parser.ts diff --git a/__tests__/java-stack-trace-element-parser.test.ts b/__tests__/java-stack-trace-element-parser.test.ts new file mode 100644 index 0000000..48a6be5 --- /dev/null +++ b/__tests__/java-stack-trace-element-parser.test.ts @@ -0,0 +1,40 @@ +import {parseStackTraceElement} from '../src/parsers/java-junit/java-stack-trace-element-parser' + +describe('parseStackTraceLine tests', () => { + it('empty line is not parsed', async () => { + const line = '' + expect(parseStackTraceElement(line)).toBe(undefined) + }) + + describe('java class', () => { + it('simple', async () => { + const line = + 'at org.apache.pulsar.AddMissingPatchVersionTest.testVersionStrings(AddMissingPatchVersionTest.java:29)' + expect(parseStackTraceElement(line)).toEqual({ + tracePath: 'org.apache.pulsar.AddMissingPatchVersionTest.testVersionStrings', + fileName: 'AddMissingPatchVersionTest.java', + lineStr: '29' + }) + }) + + it('inner class', async () => { + const line = 'at com.foo.Main$Inner.run(Main.java:29)' + expect(parseStackTraceElement(line)).toEqual({ + tracePath: 'com.foo.Main$Inner.run', + fileName: 'Main.java', + lineStr: '29' + }) + }) + }) + + describe('Kotlin class', () => { + it('method name containing whitespaces', async () => { + const line = 'at com.foo.Main.method with whitespaces(Main.kt:18)' + expect(parseStackTraceElement(line)).toEqual({ + tracePath: 'com.foo.Main.method with whitespaces', + fileName: 'Main.kt', + lineStr: '18' + }) + }) + }) +}) diff --git a/src/parsers/java-junit/java-junit-parser.ts b/src/parsers/java-junit/java-junit-parser.ts index a4df6a3..51a0b7f 100644 --- a/src/parsers/java-junit/java-junit-parser.ts +++ b/src/parsers/java-junit/java-junit-parser.ts @@ -3,6 +3,7 @@ import {ParseOptions, TestParser} from '../../test-parser' import {parseStringPromise} from 'xml2js' import {JunitReport, SingleSuiteReport, TestCase, TestSuite} from './java-junit-types' +import {parseStackTraceElement} from './java-stack-trace-element-parser' import {normalizeFilePath} from '../../utils/path-utils' import { @@ -144,12 +145,11 @@ export class JavaJunitParser implements TestParser { private exceptionThrowSource(stackTrace: string): {filePath: string; line: number} | undefined { const lines = stackTrace.split(/\r?\n/) - const re = /^at (.*)\((.*):(\d+)\)$/ for (const str of lines) { - const match = str.match(re) - if (match !== null) { - const [_, tracePath, fileName, lineStr] = match + const stackTraceElement = parseStackTraceElement(str) + if (stackTraceElement) { + const {tracePath, fileName, lineStr} = stackTraceElement const filePath = this.getFilePath(tracePath, fileName) if (filePath !== undefined) { const line = parseInt(lineStr) diff --git a/src/parsers/java-junit/java-stack-trace-element-parser.ts b/src/parsers/java-junit/java-stack-trace-element-parser.ts new file mode 100644 index 0000000..3694993 --- /dev/null +++ b/src/parsers/java-junit/java-stack-trace-element-parser.ts @@ -0,0 +1,22 @@ +export interface StackTraceElement { + tracePath: string + fileName: string + lineStr: string +} + +// simple format: +// at (:) +const re = /^at (.*)\((.*):(\d+)\)$/ + +export function parseStackTraceElement(stackTraceLine: string): StackTraceElement | undefined { + const match = stackTraceLine.match(re) + if (match !== null) { + const [_, tracePath, fileName, lineStr] = match + return { + tracePath, + fileName, + lineStr + } + } + return undefined +} From 3a48f6e045f032fd644b85e24cda3d066a0cb6db Mon Sep 17 00:00:00 2001 From: Ats Uiboupin Date: Sat, 19 Nov 2022 19:53:14 +0200 Subject: [PATCH 4/6] fix(java-junit): stack trace line can start with whitespaces Fixes #208 --- __tests__/java-stack-trace-element-parser.test.ts | 9 +++++++++ .../java-junit/java-stack-trace-element-parser.ts | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/__tests__/java-stack-trace-element-parser.test.ts b/__tests__/java-stack-trace-element-parser.test.ts index 48a6be5..6b0582c 100644 --- a/__tests__/java-stack-trace-element-parser.test.ts +++ b/__tests__/java-stack-trace-element-parser.test.ts @@ -25,6 +25,15 @@ describe('parseStackTraceLine tests', () => { lineStr: '29' }) }) + + it('starts with whitespaces', async () => { + const line = " \tat org.apache.pulsar.AddMissingPatchVersionTest.testVersionStrings(AddMissingPatchVersionTest.java:29)" + expect(parseStackTraceElement(line)).toEqual({ + tracePath: "org.apache.pulsar.AddMissingPatchVersionTest.testVersionStrings", + fileName: "AddMissingPatchVersionTest.java", + lineStr: "29" + }) + }) }) describe('Kotlin class', () => { diff --git a/src/parsers/java-junit/java-stack-trace-element-parser.ts b/src/parsers/java-junit/java-stack-trace-element-parser.ts index 3694993..81b9de6 100644 --- a/src/parsers/java-junit/java-stack-trace-element-parser.ts +++ b/src/parsers/java-junit/java-stack-trace-element-parser.ts @@ -6,7 +6,7 @@ export interface StackTraceElement { // simple format: // at (:) -const re = /^at (.*)\((.*):(\d+)\)$/ +const re = /^\s*at (.*)\((.*):(\d+)\)$/ export function parseStackTraceElement(stackTraceLine: string): StackTraceElement | undefined { const match = stackTraceLine.match(re) From aebbb4d7c4ec38d046918bf812bbcbff3d7fef78 Mon Sep 17 00:00:00 2001 From: Ats Uiboupin Date: Sat, 19 Nov 2022 21:00:04 +0200 Subject: [PATCH 5/6] fix(java-junit): parse StackTraceElement with custom classloader Fixes #208 --- .../java-stack-trace-element-parser.test.ts | 34 ++++++++++++++++--- .../java-stack-trace-element-parser.ts | 30 +++++++++++++--- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/__tests__/java-stack-trace-element-parser.test.ts b/__tests__/java-stack-trace-element-parser.test.ts index 6b0582c..6fe1ac2 100644 --- a/__tests__/java-stack-trace-element-parser.test.ts +++ b/__tests__/java-stack-trace-element-parser.test.ts @@ -27,11 +27,37 @@ describe('parseStackTraceLine tests', () => { }) it('starts with whitespaces', async () => { - const line = " \tat org.apache.pulsar.AddMissingPatchVersionTest.testVersionStrings(AddMissingPatchVersionTest.java:29)" + const line = + ' \tat org.apache.pulsar.AddMissingPatchVersionTest.testVersionStrings(AddMissingPatchVersionTest.java:29)' expect(parseStackTraceElement(line)).toEqual({ - tracePath: "org.apache.pulsar.AddMissingPatchVersionTest.testVersionStrings", - fileName: "AddMissingPatchVersionTest.java", - lineStr: "29" + tracePath: 'org.apache.pulsar.AddMissingPatchVersionTest.testVersionStrings', + fileName: 'AddMissingPatchVersionTest.java', + lineStr: '29' + }) + }) + + describe('since Java 9', () => { + it('with classloader and module', async () => { + // Based on Java 9 StackTraceElement.toString() Doc: https://docs.oracle.com/javase/9/docs/api/java/lang/StackTraceElement.html#toString-- + const line = 'at com.foo.loader/foo@9.0/com.foo.Main.run(Main.java:101)' + expect(parseStackTraceElement(line)).toEqual({ + classLoader: 'com.foo.loader', + moduleNameAndVersion: 'foo@9.0', + tracePath: 'com.foo.Main.run', + fileName: 'Main.java', + lineStr: '101' + }) + }) + + it('with classloader', async () => { + const line = 'at com.foo.loader//com.foo.Main.run(Main.java:101)' + expect(parseStackTraceElement(line)).toEqual({ + classLoader: 'com.foo.loader', + moduleNameAndVersion: undefined, + tracePath: 'com.foo.Main.run', + fileName: 'Main.java', + lineStr: '101' + }) }) }) }) diff --git a/src/parsers/java-junit/java-stack-trace-element-parser.ts b/src/parsers/java-junit/java-stack-trace-element-parser.ts index 81b9de6..894dd42 100644 --- a/src/parsers/java-junit/java-stack-trace-element-parser.ts +++ b/src/parsers/java-junit/java-stack-trace-element-parser.ts @@ -1,18 +1,24 @@ export interface StackTraceElement { + classLoader: string | undefined + moduleNameAndVersion: string | undefined tracePath: string fileName: string lineStr: string } -// simple format: -// at (:) -const re = /^\s*at (.*)\((.*):(\d+)\)$/ +// classloader and module name are optional: +// at //(:) +// https://github.com/eclipse-openj9/openj9/issues/11452#issuecomment-754946992 +const re = /^\s*at (\S+\/\S*\/)?(.*)\((.*):(\d+)\)$/ export function parseStackTraceElement(stackTraceLine: string): StackTraceElement | undefined { const match = stackTraceLine.match(re) if (match !== null) { - const [_, tracePath, fileName, lineStr] = match + const [_, maybeClassLoaderAndModuleNameAndVersion, tracePath, fileName, lineStr] = match + const {classLoader, moduleNameAndVersion} = parseClassLoaderAndModule(maybeClassLoaderAndModuleNameAndVersion) return { + classLoader, + moduleNameAndVersion, tracePath, fileName, lineStr @@ -20,3 +26,19 @@ export function parseStackTraceElement(stackTraceLine: string): StackTraceElemen } return undefined } + +function parseClassLoaderAndModule(maybeClassLoaderAndModuleNameAndVersion?: string): { + classLoader?: string + moduleNameAndVersion?: string +} { + if (maybeClassLoaderAndModuleNameAndVersion) { + const res = maybeClassLoaderAndModuleNameAndVersion.split('/') + const classLoader = res[0] + let moduleNameAndVersion: string | undefined = res[1] + if (moduleNameAndVersion === '') { + moduleNameAndVersion = undefined + } + return {classLoader, moduleNameAndVersion} + } + return {classLoader: undefined, moduleNameAndVersion: undefined} +} From 578b47fbd33e8575802b9e52648b9391f4eafd1d Mon Sep 17 00:00:00 2001 From: Ats Uiboupin Date: Sat, 19 Nov 2022 22:20:44 +0200 Subject: [PATCH 6/6] update generated files Closes #208 --- dist/index.js | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/dist/index.js b/dist/index.js index f9222d3..fe11bfe 100644 --- a/dist/index.js +++ b/dist/index.js @@ -926,6 +926,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.JavaJunitParser = void 0; const path = __importStar(__nccwpck_require__(1017)); const xml2js_1 = __nccwpck_require__(6189); +const java_stack_trace_element_parser_1 = __nccwpck_require__(5775); const path_utils_1 = __nccwpck_require__(4070); const test_results_1 = __nccwpck_require__(2768); class JavaJunitParser { @@ -1051,11 +1052,10 @@ class JavaJunitParser { } exceptionThrowSource(stackTrace) { const lines = stackTrace.split(/\r?\n/); - const re = /^at (.*)\((.*):(\d+)\)$/; for (const str of lines) { - const match = str.match(re); - if (match !== null) { - const [_, tracePath, fileName, lineStr] = match; + const stackTraceElement = (0, java_stack_trace_element_parser_1.parseStackTraceElement)(str); + if (stackTraceElement) { + const { tracePath, fileName, lineStr } = stackTraceElement; const filePath = this.getFilePath(tracePath, fileName); if (filePath !== undefined) { const line = parseInt(lineStr); @@ -1108,6 +1108,49 @@ class JavaJunitParser { exports.JavaJunitParser = JavaJunitParser; +/***/ }), + +/***/ 5775: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.parseStackTraceElement = void 0; +// classloader and module name are optional: +// at //(:) +// https://github.com/eclipse-openj9/openj9/issues/11452#issuecomment-754946992 +const re = /^\s*at (\S+\/\S*\/)?(.*)\((.*):(\d+)\)$/; +function parseStackTraceElement(stackTraceLine) { + const match = stackTraceLine.match(re); + if (match !== null) { + const [_, maybeClassLoaderAndModuleNameAndVersion, tracePath, fileName, lineStr] = match; + const { classLoader, moduleNameAndVersion } = parseClassLoaderAndModule(maybeClassLoaderAndModuleNameAndVersion); + return { + classLoader, + moduleNameAndVersion, + tracePath, + fileName, + lineStr + }; + } + return undefined; +} +exports.parseStackTraceElement = parseStackTraceElement; +function parseClassLoaderAndModule(maybeClassLoaderAndModuleNameAndVersion) { + if (maybeClassLoaderAndModuleNameAndVersion) { + const res = maybeClassLoaderAndModuleNameAndVersion.split('/'); + const classLoader = res[0]; + let moduleNameAndVersion = res[1]; + if (moduleNameAndVersion === '') { + moduleNameAndVersion = undefined; + } + return { classLoader, moduleNameAndVersion }; + } + return { classLoader: undefined, moduleNameAndVersion: undefined }; +} + + /***/ }), /***/ 1113: