@@ -106,7 +106,7 @@ private static void reportJTRegResult(TestResult testResult) {
106106 if (status .isFailed () || status .isError ()) {
107107 tcTestFailed ("jtreg" , status .getReason ());
108108 } else if (status .isNotRun ()) {
109- tcTestIgnored ("jtreg" );
109+ tcTestIgnored ("jtreg" , status . getReason () );
110110 }
111111
112112 String duration = null ;
@@ -157,7 +157,7 @@ private static void reportTestMethod(JUnitResults.TestMethod test, String classN
157157 tcTestStdErr (test .name (), test .stderrLines ());
158158 switch (test .result ()) {
159159 case FAILED -> tcTestFailed (test .name (), "" );
160- case SKIPPED -> tcTestIgnored (test .name ());
160+ case SKIPPED -> tcTestIgnored (test .name (), test . skipReason () );
161161 }
162162 tcTestFinished (test .name (), test .duration ());
163163 }
@@ -218,8 +218,9 @@ private static void tcTestFailed(String testName, String message) {
218218 "message='" + escapeName (message ) + "' ]" );
219219 }
220220
221- private static void tcTestIgnored (String testName ) {
222- System .out .println ("##teamcity[testIgnored name='" + escapeName (testName ) + "']" );
221+ private static void tcTestIgnored (String testName , String reason ) {
222+ System .out .println ("##teamcity[testIgnored name='" + escapeName (testName ) + "' "
223+ + "message='" + escapeName (reason ) + "']" );
223224 }
224225
225226 private static void tcTestFinished (String testName , String duration ) {
@@ -244,11 +245,11 @@ private static String escapeName(String str) {
244245
245246 private static class JUnitResults {
246247 private record TestMethod (String name , String methodName , Iteration iteration , Result result ,
247- List <String > stderrLines , String duration ) {
248+ List <String > stderrLines , String duration , String skipReason ) {
248249 enum Result {SUCCESSFUL , SKIPPED , FAILED }
249250
250251 private record Iteration (int num , String name ) {
251- private static final Pattern PATTERN = Pattern .compile ("' \\ [(?<num>\\ d+)] (?<name>.*)' " );
252+ private static final Pattern PATTERN = Pattern .compile ("\\ [(?<num>\\ d+)] (?<name>.*)" );
252253
253254 private static Iteration parse (String iteration ) {
254255 Matcher m = PATTERN .matcher (iteration );
@@ -269,7 +270,10 @@ public TestClass(String name, String simpleName) {
269270 }
270271
271272 private static final Pattern JUNIT_TEST_START = Pattern .compile (
272- "STARTED\\ s+(?<class>[A-Za-z0-9._$]+)::(?<method>[A-Za-z0-9._$]+)\\ s+(?<rest>.*)" );
273+ "(?<kind>STARTED|SKIPPED)\\ s+(?<class>[A-Za-z0-9._$]+)::(?<method>[A-Za-z0-9._$]+)\\ s+'(?<name>[^']+)'(?: (?<reason>.*))?" );
274+
275+ private static final Pattern JUNIT_TEST_END = Pattern .compile (
276+ "(?<status>SUCCESSFUL|ABORTED|FAILED)\\ s+\\ S+ '[^']+' \\ [(?<milis>\\ d+)ms]" );
273277
274278 private static Collection <TestClass > parse (Iterator <String > itt ) {
275279 Map <String , TestClass > classesByName = new HashMap <>();
@@ -285,33 +289,41 @@ private static Collection<TestClass> parse(Iterator<String> itt) {
285289 stdErr .add (line );
286290 String className = m .group ("class" );
287291 String methodName = m .group ("method" );
288- TestMethod .Iteration iteration = TestMethod .Iteration .parse (m .group ("rest " ));
292+ TestMethod .Iteration iteration = TestMethod .Iteration .parse (m .group ("name " ));
289293 String displayTestName = methodName + (iteration != null ? " [" + iteration .name () + "]" : "" );
290294
291- do {
292- line = itt .next ();
293- if (line .startsWith ("JT Harness has limited the test output" )) {
294- // jtharness truncated the output. Discard this result
295- // and look for the next one.
296- continue outer ;
295+ TestMethod .Result result ;
296+ String duration = null ;
297+ String skipReason = null ;
298+ String kind = m .group ("kind" );
299+ if (kind .equals ("STARTED" )) {
300+ Matcher endMatcher ;
301+ do {
302+ line = itt .next ();
303+ if (line .startsWith ("JT Harness has limited the test output" )) {
304+ // jtharness truncated the output. Discard this result
305+ // and look for the next one.
306+ continue outer ;
307+ }
308+ stdErr .add (line );
309+ endMatcher = JUNIT_TEST_END .matcher (line );
310+ } while (!endMatcher .find ());
311+
312+ String status = endMatcher .group ("status" );
313+ if (status .contains ("FAILED" ) || status .contains ("ABORTED" )) {
314+ result = TestMethod .Result .FAILED ;
315+ } else {
316+ result = TestMethod .Result .SUCCESSFUL ;
297317 }
298- stdErr .add (line );
299- } while (!line .startsWith ("SUCCESSFUL" ) && !line .startsWith ("ABORTED" )
300- && !line .startsWith ("SKIPPED" ) && !line .startsWith ("FAILED" ));
301318
302- TestMethod .Result result ;
303- if (line .startsWith ("SKIPPED" )) {
304- result = TestMethod .Result .SKIPPED ;
305- } else if (line .startsWith ("FAILED" ) || line .startsWith ("ABORTED" )) {
306- result = TestMethod .Result .FAILED ;
319+ duration = endMatcher .group ("milis" ); // may be null for 'SKIPPED'
307320 } else {
308- result = TestMethod .Result .SUCCESSFUL ;
321+ result = TestMethod .Result .SKIPPED ;
322+ skipReason = m .group ("reason" );
309323 }
310- String [] lineParts = line .split (" " );
311- String duration = lineParts [lineParts .length -1 ]; // e.g. '[64ms]'
312- duration = duration .substring (1 , duration .length () - 3 ); // drop '[' and 'ms]'
313324
314- TestMethod test = new TestMethod (displayTestName , methodName , iteration , result , stdErr , duration );
325+ TestMethod test = new TestMethod (displayTestName , methodName ,
326+ iteration , result , stdErr , duration , skipReason );
315327 String [] nestedClasses = dropPackage (className ).split ("\\ $" );
316328 String classNameForLookup = className .replace ('$' , '.' );
317329 TestClass current = classesByName .computeIfAbsent (nestedClasses [0 ],
0 commit comments