[ 
https://issues.apache.org/jira/browse/SUREFIRE-2232?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17805725#comment-17805725
 ] 

ASF GitHub Bot commented on SUREFIRE-2232:
------------------------------------------

dr29bart commented on code in PR #716:
URL: https://github.com/apache/maven-surefire/pull/716#discussion_r1449170752


##########
maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java:
##########
@@ -451,7 +451,9 @@ private static void getTestProblems(
                     String type = delimiter == -1 ? stackTrace : 
stackTrace.substring(0, delimiter);
                     ppw.addAttribute("type", type);
                 } else {
-                    ppw.addAttribute("type", new 
StringTokenizer(stackTrace).nextToken());
+                    ppw.addAttribute(
+                            "type",
+                            isBlank(stackTrace) ? "UndefinedException" : new 
StringTokenizer(stackTrace).nextToken());

Review Comment:
   Do you mean `indexOf` approach or `to use value as is`?
   
   I didn't want to leave a chance for `type` to be null. What non-null value 
can be used here?
   
   The `stackTrace` StatelessXmlReporter#439 var may be null:
   ```
   public String getStackTrace(boolean trimStackTrace) {
           StackTraceWriter w = original.getStackTraceWriter();
           return w == null ? null : (trimStackTrace ? 
w.writeTrimmedTraceToString() : w.writeTraceToString());
       }
   ```
   At the same time surefire's XSD requires `type`
   <details>
    <summary>XSD</summary>
   
   ```xml
   <xs:element name="error" nillable="true" minOccurs="0" maxOccurs="1">
                                   <xs:complexType>
                                       <xs:simpleContent>
                                           <xs:extension base="xs:string">
                                               <xs:attribute name="message" 
type="xs:string"/>
                                               <xs:attribute name="type" 
type="xs:string" use="required"/>
                                           </xs:extension>
                                       </xs:simpleContent>
                                   </xs:complexType>
                               </xs:element>
   ```
   </details>
   
   The goal is to handle stack traces like:
   ```
   // has message
   junit.framework.ComparisonFailure: 
   Expected :fail at foo
   Actual   :faild at foo
   
   // does not have message
   java.lang.AssertionError
        at org.junit.Assert.fail(Assert.java:87)
        at org.junit.Assert.fail(Assert.java:96)
   
   // or stack trace is missing (empty String)
   
   ```
   
   Please, let me know if this alternative is more preferable:
   <details>
    <summary>Option A</summary>
   
   ```java
   if (report.getStackTraceWriter() != null) {
               //noinspection ThrowableResultOfMethodCallIgnored
               SafeThrowable t = report.getStackTraceWriter().getThrowable();
               if (t != null) {
                   int delimiter = StringUtils.indexOfAny(stackTrace, ":", 
"\t", "\n", "\r", "\f");
                   String type = delimiter == -1 ? stackTrace : 
stackTrace.substring(0, delimiter);
                   ppw.addAttribute("type", Objects.toString(type, 
"UndefinedException"));
               }
           }
   ```
   </details>
   <details>
    <summary>Option B</summary>
   
   ```java
   SafeThrowable t = report.getStackTraceWriter().getThrowable();
               if (t != null) {
                   if (t.getMessage() != null) {
                       int delimiter = stackTrace.indexOf(":");
                       String type = delimiter == -1 ? stackTrace : 
stackTrace.substring(0, delimiter);
                       ppw.addAttribute("type", type);
                   } else {
                       ppw.addAttribute(
                               "type",
                               isBlank(stackTrace) ? stackTrace : new 
StringTokenizer(stackTrace).nextToken());
                   }
               }
   ```
   </details>
   <details>
    <summary>Option C</summary>
   
   ```java
   SafeThrowable t = report.getStackTraceWriter().getThrowable();
               if (t != null) {
                   if (t.getMessage() != null) {
                       int delimiter = stackTrace.indexOf(":");
                       String type = delimiter == -1 ? stackTrace : 
stackTrace.substring(0, delimiter);
                       ppw.addAttribute("type", type);
                   } else {
                       int delimiter = StringUtils.indexOfAny(stackTrace, "\t", 
"\n", "\r", "\f");
                       String type = delimiter == -1 ? stackTrace : 
stackTrace.substring(0, delimiter);
                       ppw.addAttribute("type", type);
                   }
               }
   </details>
   
   
   





> StatelessXmlReporter fails to process failed result without a throwable
> -----------------------------------------------------------------------
>
>                 Key: SUREFIRE-2232
>                 URL: https://issues.apache.org/jira/browse/SUREFIRE-2232
>             Project: Maven Surefire
>          Issue Type: Bug
>          Components: Maven Surefire Plugin
>    Affects Versions: 3.0.0-M6, 3.2.3
>            Reporter: Artem Yak
>            Priority: Minor
>             Fix For: waiting-for-feedback
>
>
>  
> A regression bug appeared in 3.0.0-M6:
> A testNG test class has a listener which updates results from SUCCESS to 
> FAILURE:
>  
> {noformat}
> @Override
> public void onTestSuccess(ITestResult result) {
>     result.setStatus(ITestResult.FAILURE);
>     result.getTestContext().getPassedTests().removeResult(result);
>     result.getTestContext().getFailedTests().addResult(result);
> }{noformat}
>  
> Surefire fails to process a failed test result without a throwable and 
> reports 0 total tests. 
> {code:java}
> ForkStarter IOException: java.util.NoSuchElementException.
> org.apache.maven.plugin.surefire.booterclient.output.MultipleFailureException:
>  java.util.NoSuchElementException
>       at 
> org.apache.maven.plugin.surefire.booterclient.output.ThreadedStreamConsumer$Pumper.<init>(ThreadedStreamConsumer.java:59)
>       at 
> org.apache.maven.plugin.surefire.booterclient.output.ThreadedStreamConsumer.<init>(ThreadedStreamConsumer.java:107)
>       at 
> org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:546)
>       at 
> org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:285)
>       at 
> org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:250)
>  {code}
>  
> Reproducible unit test.
> {code:java}
> package org.apache.maven.plugin.surefire.report;
> import java.io.File;
> import java.util.HashMap;
> import java.util.concurrent.atomic.AtomicInteger;
> import junit.framework.TestCase;
> import 
> org.apache.maven.plugin.surefire.booterclient.output.DeserializedStacktraceWriter;
> import org.apache.maven.surefire.api.report.SimpleReportEntry;
> import org.apache.maven.surefire.api.report.StackTraceWriter;
> import static org.apache.maven.plugin.surefire.report.ReportEntryType.ERROR;
> import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
> @SuppressWarnings({"ResultOfMethodCallIgnored", "checkstyle:magicnumber"})
> public class StatelessXmlReporter2Test extends TestCase {
>     private static final String XSD =
>         
> "https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report-3.0.xsd";;
>     private static final AtomicInteger FOLDER_POSTFIX = new AtomicInteger();
>     private File reportDir;
>     @Override
>     protected void setUp() throws Exception {
>         File basedir = new File(".");
>         File target = new File(basedir.getCanonicalFile(), "target");
>         target.mkdir();
>         String reportRelDir = getClass().getSimpleName() + "-" + 
> FOLDER_POSTFIX.incrementAndGet();
>         reportDir = new File(target, reportRelDir);
>         reportDir.mkdir();
>     }
>     @Override
>     protected void tearDown() {
>     }
>     public void testOutputFailedTestWithoutThrowable() {
>         StackTraceWriter stackTraceWriterOne = new 
> DeserializedStacktraceWriter(null, null, "");
>         WrappedReportEntry testReport = new WrappedReportEntry(
>             new SimpleReportEntry(
>                 NORMAL_RUN, 1L, getClass().getName(), null, "a test name", 
> null, stackTraceWriterOne, 5),
>             ERROR,
>             5,
>             null,
>             null);
>         TestSetStats testSetStats = new TestSetStats(false, false);
>         testSetStats.testError(testReport);
>         StatelessXmlReporter reporter = new StatelessXmlReporter(
>             reportDir, null, false, 1, new HashMap<>(), XSD, "3.0", false, 
> false, false, false);
>         reporter.testSetCompleted(testReport, testSetStats);
>     }
> }  {code}
>  
>  
>  
> {code:java}
> java.util.NoSuchElementException
>     at java.base/java.util.StringTokenizer.nextToken(StringTokenizer.java:349)
>     at 
> org.apache.maven.plugin.surefire.report.StatelessXmlReporter.getTestProblems(StatelessXmlReporter.java:454)
>     at 
> org.apache.maven.plugin.surefire.report.StatelessXmlReporter.serializeTestClassWithRerun(StatelessXmlReporter.java:256)
>     at 
> org.apache.maven.plugin.surefire.report.StatelessXmlReporter.serializeTestClass(StatelessXmlReporter.java:207)
>     at 
> org.apache.maven.plugin.surefire.report.StatelessXmlReporter.testSetCompleted(StatelessXmlReporter.java:161)
>     at 
> org.apache.maven.plugin.surefire.report.StatelessXmlReporter2Test.testOutputFailedTestWithoutThrowable(StatelessXmlReporter2Test.java:72){code}
>  
>  
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to