From 25425c379dd2a77001f17a71dce1eec04975a15e Mon Sep 17 00:00:00 2001 From: tibordigana Date: Tue, 29 Mar 2022 23:18:55 +0200 Subject: [PATCH] [SUREFIRE-2052] Handles internal exceptions do not have suppressed exceptions in ThreadedStreamConsumer --- .../output/MultipleFailureException.java | 30 ++++------ .../output/MultipleFailureExceptionTest.java | 59 +++++++++++++++++++ 2 files changed, 70 insertions(+), 19 deletions(-) create mode 100644 maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/MultipleFailureExceptionTest.java diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/MultipleFailureException.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/MultipleFailureException.java index 81c7dd5d64..ac621d3bdc 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/MultipleFailureException.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/MultipleFailureException.java @@ -20,51 +20,43 @@ */ import java.io.IOException; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.function.Function; final class MultipleFailureException extends IOException { - private final Queue exceptions = new ConcurrentLinkedQueue<>(); - void addException( Throwable exception ) { - exceptions.add( exception ); + addSuppressed( exception ); } boolean hasNestedExceptions() { - return !exceptions.isEmpty(); + return getSuppressed().length != 0; } @Override public String getLocalizedMessage() { - StringBuilder messages = new StringBuilder(); - for ( Throwable exception : exceptions ) - { - if ( messages.length() != 0 ) - { - messages.append( '\n' ); - } - String message = exception.getLocalizedMessage(); - messages.append( message == null ? exception.toString() : message ); - } - return messages.toString(); + return toMessage( Throwable::getLocalizedMessage ); } @Override public String getMessage() + { + return toMessage( Throwable::getMessage ); + } + + private String toMessage( Function msg ) { StringBuilder messages = new StringBuilder(); - for ( Throwable exception : exceptions ) + for ( Throwable exception : getSuppressed() ) { if ( messages.length() != 0 ) { messages.append( '\n' ); } - String message = exception.getMessage(); + String message = msg.apply( exception ); messages.append( message == null ? exception.toString() : message ); } return messages.toString(); diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/MultipleFailureExceptionTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/MultipleFailureExceptionTest.java new file mode 100644 index 0000000000..82c2f83666 --- /dev/null +++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/MultipleFailureExceptionTest.java @@ -0,0 +1,59 @@ +package org.apache.maven.plugin.surefire.booterclient.output; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.IOException; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@code MultipleFailureException}. + */ +public class MultipleFailureExceptionTest +{ + @Test + public void test() + { + MultipleFailureException e = new MultipleFailureException(); + NullPointerException suppressed1 = new NullPointerException( "field is null" ); + IOException suppressed2 = new IOException( "read error" ); + e.addException( suppressed1 ); + e.addException( suppressed2 ); + + assertThat( e.getMessage() ) + .contains( "field is null" ) + .contains( "read error" ); + + assertThat( e.getLocalizedMessage() ) + .contains( "field is null" ) + .contains( "read error" ); + + assertThat( e.getSuppressed() ) + .hasSize( 2 ); + + assertThat( e.getSuppressed() ) + .contains( suppressed1, suppressed2 ); + + assertThat( e.hasNestedExceptions() ) + .isTrue(); + } +}