Skip to content

Commit

Permalink
ci: add NeonBeeTestExecutionListener to check for stale threads
Browse files Browse the repository at this point in the history
  • Loading branch information
kristian committed Oct 4, 2021
1 parent 28f0386 commit cf17fa4
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ dependencies {

// Required for Eclipse to run Unit tests.
testImplementation group: 'org.junit.platform', name: 'junit-platform-commons', version: '1.7.0'
testImplementation group: 'org.junit.platform', name: 'junit-platform-launcher', version: '1.7.0'

// Gradle plugin dependencies
errorprone group: 'com.google.errorprone', name: 'error_prone_core', version: '2.5.1'
Expand Down
51 changes: 51 additions & 0 deletions src/test/java/io/neonbee/NeonBeeTestExecutionListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.neonbee;

import java.util.Optional;

import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The {@link NeonBeeTestExecutionListener} checks for any stale Vert.x threads after test execution. Generally after a
* test finishes to execute it must clean up all Vert.x resources. If not this listener will print an error to the logs.
*/
public class NeonBeeTestExecutionListener implements TestExecutionListener {
private static final Logger LOGGER = LoggerFactory.getLogger(TestExecutionListener.class);

private boolean parallelExecution;

@Override
public void testPlanExecutionStarted(TestPlan testPlan) {
parallelExecution = "true".equalsIgnoreCase(System.getProperty("junit.jupiter.execution.parallel.enabled"));
if (parallelExecution) {
LOGGER.warn("Cannot check for stale threads when running JUnit in parallel execution mode");
}
}

@Override
public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) {
if (!parallelExecution) {
checkForStaleThreads("Vert.x", "vert.x-");
checkForStaleThreads("Hazelcast", "hz.");
checkForStaleThreads("WatchService", "FileSystemWatch");
}
}

private static void checkForStaleThreads(String title, String namePrefix) {
LOGGER.info("Checking for stale {} threads with '{}' prefix", title, namePrefix);
Optional<Thread> staleThread = findStaleThread(namePrefix);
if (staleThread.isPresent() && LOGGER.isErrorEnabled()) {
LOGGER.error("Stale {} thread(s) detected!! Not closing the thread {} "
+ "could result in the test runner not signaling completion", title, staleThread.get());
}
}

private static Optional<Thread> findStaleThread(String namePrefix) {
return Thread.getAllStackTraces().keySet().stream().filter(thread -> thread.getName().startsWith(namePrefix))
.findAny();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.neonbee.NeonBeeTestExecutionListener

0 comments on commit cf17fa4

Please sign in to comment.