Skip to content

Commit

Permalink
Fixes #17 - IllegalStateException thrown when running in parallel (#18)
Browse files Browse the repository at this point in the history
* Create SurefireClassLoaderModifier
* Update version on pom.xml and readme
  • Loading branch information
fabriciorby authored Jul 10, 2022
1 parent 1dedec7 commit 2e1948f
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 53 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Configure your POM like the following
<dependency>
<groupId>me.fabriciorby</groupId>
<artifactId>maven-surefire-junit5-tree-reporter</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</dependency>
</dependencies>
<configuration>
Expand All @@ -57,7 +57,7 @@ Configure your POM like the following
<dependency>
<groupId>me.fabriciorby</groupId>
<artifactId>maven-surefire-junit5-tree-reporter</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</dependency>
</dependencies>
<configuration>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>me.fabriciorby</groupId>
<artifactId>maven-surefire-junit5-tree-reporter</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<packaging>jar</packaging>

<name>maven-surefire-junit5-tree-reporter</name>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.apache.maven.plugin.surefire.extensions.junit5;

import org.apache.maven.plugin.surefire.loader.SurefireClassLoaderModifier;

/**
* Extension of {@link JUnit5StatelessTestsetInfoReporter file and console reporter of test-set} for JUnit5.
*
* @author <a href="mailto:[email protected]">Fabrício Yamamoto (fabriciorby)</a>
*/
public abstract class JUnit5StatelessTestsetInfoReporterBase extends JUnit5StatelessTestsetInfoReporter {

@Override
public Object clone(ClassLoader target) {
try {
new SurefireClassLoaderModifier(target).addThisToSurefireClassLoader();
return super.clone(target);
} catch (ReflectiveOperationException e) {
throw new IllegalStateException(e.getLocalizedMessage());
}
}

@Override
public String toString() {
return this.getClass().getSimpleName() + "{"
+ "disable=" + isDisable()
+ ", usePhrasedFileName=" + isUsePhrasedFileName()
+ ", usePhrasedClassNameInRunning=" + isUsePhrasedClassNameInRunning()
+ ", usePhrasedClassNameInTestCaseSummary=" + isUsePhrasedClassNameInTestCaseSummary()
+ "}";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,13 @@
*
* @author <a href="mailto:[email protected]">Fabrício Yamamoto (fabriciorby)</a>
*/
public class JUnit5StatelessTestsetInfoTreeReporter extends JUnit5StatelessTestsetInfoReporter
{
public class JUnit5StatelessTestsetInfoTreeReporter extends JUnit5StatelessTestsetInfoReporterBase {

@Override
public StatelessTestsetInfoConsoleReportEventListener<WrappedReportEntry, TestSetStats> createListener(
ConsoleLogger logger )
{
return new ConsoleTreeReporter( logger, isUsePhrasedClassNameInRunning(),
isUsePhrasedClassNameInTestCaseSummary() );
ConsoleLogger logger) {
return new ConsoleTreeReporter(logger, isUsePhrasedClassNameInRunning(),
isUsePhrasedClassNameInTestCaseSummary());
}

@Override
public String toString()
{
return "JUnit5StatelessTestsetInfoTreeReporter{"
+ "disable=" + isDisable()
+ ", usePhrasedFileName=" + isUsePhrasedFileName()
+ ", usePhrasedClassNameInRunning=" + isUsePhrasedClassNameInRunning()
+ ", usePhrasedClassNameInTestCaseSummary=" + isUsePhrasedClassNameInTestCaseSummary()
+ "}";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,23 @@
*/

import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.plugin.surefire.report.*;
import org.apache.maven.plugin.surefire.report.ConsoleTreeReporterUnicode;
import org.apache.maven.plugin.surefire.report.TestSetStats;
import org.apache.maven.plugin.surefire.report.WrappedReportEntry;
import org.apache.maven.surefire.extensions.StatelessTestsetInfoConsoleReportEventListener;

/**
* Extension of {@link JUnit5StatelessTestsetInfoReporter file and console reporter of test-set} for JUnit5.
*
* @author <a href="mailto:[email protected]">Fabrício Yamamoto (fabriciorby)</a>
*/
public class JUnit5StatelessTestsetInfoTreeReporterUnicode extends JUnit5StatelessTestsetInfoTreeReporter
{
public class JUnit5StatelessTestsetInfoTreeReporterUnicode extends JUnit5StatelessTestsetInfoReporterBase {

@Override
public StatelessTestsetInfoConsoleReportEventListener<WrappedReportEntry, TestSetStats> createListener(
ConsoleLogger logger )
{
return new ConsoleTreeReporterUnicode( logger, isUsePhrasedClassNameInRunning(),
isUsePhrasedClassNameInTestCaseSummary() );
ConsoleLogger logger) {
return new ConsoleTreeReporterUnicode(logger, isUsePhrasedClassNameInRunning(),
isUsePhrasedClassNameInTestCaseSummary());
}

@Override
public String toString()
{
return "JUnit5StatelessTestsetInfoTreeReporterUnicode{"
+ "disable=" + isDisable()
+ ", usePhrasedFileName=" + isUsePhrasedFileName()
+ ", usePhrasedClassNameInRunning=" + isUsePhrasedClassNameInRunning()
+ ", usePhrasedClassNameInTestCaseSummary=" + isUsePhrasedClassNameInTestCaseSummary()
+ "}";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.apache.maven.plugin.surefire.loader;

import org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoReporterBase;

import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.stream.Stream;

/*
* 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.
*/

/**
* Class created to modify the Surefire ClassLoader during Runtime.
* Needed for {@link JUnit5StatelessTestsetInfoReporterBase#clone()} method,
* which is used when the unit tests are running using multiple threads.
*
* @author <a href="mailto:[email protected]">Fabrício Yamamoto (fabriciorby)</a>
*/
public class SurefireClassLoaderModifier {

private final ClassLoader surefireClassLoader;
private final Method addUrlMethod;

public static final String MAVEN_SUREFIRE_JUNIT_5_TREE_REPORTER = "maven-surefire-junit5-tree-reporter";
public static final String ADD_URL_METHOD = "addURL";

public SurefireClassLoaderModifier(ClassLoader surefireClassLoader) throws NoSuchMethodException {
this.surefireClassLoader = surefireClassLoader;
this.addUrlMethod = surefireClassLoader.getClass().getDeclaredMethod(ADD_URL_METHOD, URL.class);
this.addUrlMethod.setAccessible(true);
}

public void addThisToSurefireClassLoader() throws ReflectiveOperationException {
this.addUrlMethod.invoke(surefireClassLoader, getJarUrl());
}

private URL getJarUrl() throws ReflectiveOperationException {
return getThreadContextClassLoaderURLs()
.filter(this::isMavenSurefireTreeReporterJar)
.findFirst()
.orElseThrow(ReflectiveOperationException::new);
}

private Stream<URL> getThreadContextClassLoaderURLs() {
return Stream.of(((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURLs());
}

private boolean isMavenSurefireTreeReporterJar(URL url) {
return url.getFile().contains(MAVEN_SUREFIRE_JUNIT_5_TREE_REPORTER);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.surefire.api.report.TestSetReportEntry;

import java.util.*;
import java.util.List;

/**
* Tree view class for console reporters.
Expand All @@ -31,8 +31,8 @@
*/
public class ConsoleTreeReporter extends ConsoleReporter {

public ConsoleTreeReporter(ConsoleLogger logger,
boolean usePhrasedClassNameInRunning, boolean usePhrasedClassNameInTestCaseSummary) {
public ConsoleTreeReporter(ConsoleLogger logger, boolean usePhrasedClassNameInRunning,
boolean usePhrasedClassNameInTestCaseSummary) {
super(logger, usePhrasedClassNameInRunning, usePhrasedClassNameInTestCaseSummary);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
*/

import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.surefire.api.report.TestSetReportEntry;

import java.util.List;

Expand All @@ -31,8 +30,8 @@
*/
public class ConsoleTreeReporterUnicode extends ConsoleTreeReporter {

public ConsoleTreeReporterUnicode(ConsoleLogger logger,
boolean usePhrasedClassNameInRunning, boolean usePhrasedClassNameInTestCaseSummary) {
public ConsoleTreeReporterUnicode(ConsoleLogger logger, boolean usePhrasedClassNameInRunning,
boolean usePhrasedClassNameInTestCaseSummary) {
super(logger, usePhrasedClassNameInRunning, usePhrasedClassNameInTestCaseSummary);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,30 @@
import static org.apache.maven.surefire.shared.lang3.StringUtils.abbreviate;
import static org.apache.maven.surefire.shared.lang3.StringUtils.normalizeSpace;

/*
* 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.
*/

/**
* Text formatter to use when print to the console is needed.
*
* @author <a href="mailto:[email protected]">Fabrício Yamamoto</a>
*/
public class TextFormatter {

public static final int MAX_WIDTH = 180;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
import java.nio.charset.StandardCharsets;

/**
* Tree view printer.
* @see <a href="https://github.com/junit-team/junit5/blob/main/junit-platform-console/src/main/java/org/junit/platform/console/options/Theme.java">Used reference</a>
* Theme to use when printing using the TreePrinter.
*
* @author <a href="mailto:[email protected]">Fabrício Yamamoto</a>
* @see <a href="https://github.com/junit-team/junit5/blob/main/junit-platform-console/src/main/java/org/junit/platform/console/options/Theme.java">Used reference</a>
*/
public enum Theme {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
*/

import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.surefire.shared.lang3.StringUtils;
import org.apache.maven.surefire.shared.utils.logging.MessageBuilder;

import java.util.List;
Expand All @@ -31,8 +30,6 @@
import static java.util.stream.Collectors.toSet;
import static org.apache.maven.plugin.surefire.report.TestSetStats.concatenateWithTestGroup;
import static org.apache.maven.plugin.surefire.report.TextFormatter.abbreviateName;
import static org.apache.maven.surefire.shared.lang3.StringUtils.abbreviate;
import static org.apache.maven.surefire.shared.lang3.StringUtils.normalizeSpace;
import static org.apache.maven.surefire.shared.utils.StringUtils.isBlank;
import static org.apache.maven.surefire.shared.utils.logging.MessageUtils.buffer;

Expand Down Expand Up @@ -82,9 +79,9 @@ public void printTests() {
.map(TestPrinter::new)
.forEach(TestPrinter::printTest);
}

private class TestPrinter {

private final WrappedReportEntry testResult;
private final long treeLength;

Expand Down Expand Up @@ -137,7 +134,7 @@ private void printFailure() {
}

private void printClass() {
if(!distinctSourceName.contains(testResult.getSourceName())) return;
if (!distinctSourceName.contains(testResult.getSourceName())) return;
distinctSourceName.remove(testResult.getSourceName());

MessageBuilder builder = buffer();
Expand Down Expand Up @@ -198,7 +195,7 @@ private void println(MessageBuilder builder) {
private void println(String message) {
consoleLogger.info(message);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.mockito.Mockito.mock;

@ExtendWith(MockitoExtension.class)
class ConsoleTreeReporterTest {

Expand Down

0 comments on commit 2e1948f

Please sign in to comment.