Skip to content

Commit

Permalink
[#noissue] Fix missing LauncherSession.close
Browse files Browse the repository at this point in the history
  • Loading branch information
emeroad committed Jan 2, 2025
1 parent a3eaff3 commit eeb6751
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package com.navercorp.pinpoint.test.plugin;

import com.navercorp.pinpoint.test.plugin.classloader.PluginTestClassLoader;
import com.navercorp.pinpoint.test.plugin.shared.ThreadFactory;
import com.navercorp.pinpoint.test.plugin.shared.TestThreadFactory;
import com.navercorp.pinpoint.test.plugin.util.CallExecutable;
import com.navercorp.pinpoint.test.plugin.util.RunExecutable;
import org.junit.platform.commons.JUnitException;
Expand All @@ -27,6 +27,7 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

Expand All @@ -47,8 +48,8 @@ public DefaultPluginTestInstance(String id, PluginTestClassLoader classLoader, C
this.callback = callback;

final String threadName = id + "-Thread";
final ThreadFactory threadFactory = new ThreadFactory(threadName, this.classLoader);
this.executorService = Executors.newSingleThreadExecutor(threadFactory);
final ThreadFactory testThreadFactory = new TestThreadFactory(threadName, this.classLoader);
this.executorService = Executors.newSingleThreadExecutor(testThreadFactory);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,22 @@
package com.navercorp.pinpoint.test.plugin.junit5.launcher;

import com.navercorp.pinpoint.test.plugin.ExceptionWriter;
import com.navercorp.pinpoint.test.plugin.util.URLUtils;
import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestIdentifier;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import static com.navercorp.pinpoint.test.plugin.PluginTestConstants.JUNIT_OUTPUT_DELIMITER;
import static com.navercorp.pinpoint.test.plugin.PluginTestConstants.UTF_8_NAME;

public class SharedPluginForkedTestExecutionListener implements TestExecutionListener {
private static final String ENGINE_ID = "[engine:junit-jupiter]";
private static final String SEGEMENT_ID = "dependency:";

private final ExceptionWriter writer = new ExceptionWriter();
private String testId;
private final String testId;

public SharedPluginForkedTestExecutionListener(String testId) throws UnsupportedEncodingException {
this.testId = URLEncoder.encode(testId, UTF_8_NAME);
public SharedPluginForkedTestExecutionListener(String testId) {
this.testId = URLUtils.encode(testId);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import com.navercorp.pinpoint.test.plugin.shared.TestInfo;
import com.navercorp.pinpoint.test.plugin.shared.TestParameter;
import com.navercorp.pinpoint.test.plugin.shared.TestParameterParser;
import com.navercorp.pinpoint.test.plugin.shared.ThreadFactory;
import com.navercorp.pinpoint.test.plugin.shared.TestThreadFactory;
import com.navercorp.pinpoint.test.plugin.util.ArrayUtils;
import com.navercorp.pinpoint.test.plugin.util.ChildFirstClassLoader;
import com.navercorp.pinpoint.test.plugin.util.CollectionUtils;
Expand All @@ -38,8 +38,11 @@
import org.junit.jupiter.engine.JupiterTestEngine;
import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.engine.discovery.DiscoverySelectors;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.LauncherSession;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.core.LauncherConfig;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
Expand All @@ -55,12 +58,19 @@
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class SharedPluginForkedTestLauncher {

private static final TaggedLogger logger = TestLogger.getLogger();

private static final String TEST_RESULT_SUCCESS = "SUCCESS";

public static void main(String[] args) throws Exception {
final String mavenDependencyResolverClassPaths = System.getProperty(SharedPluginTestConstants.MAVEN_DEPENDENCY_RESOLVER_CLASS_PATHS);
if (mavenDependencyResolverClassPaths == null) {
Expand Down Expand Up @@ -271,74 +281,89 @@ private ClassLoader createTestClassLoader(TestInfo testInfo) {
}

private void execute(final TestInfo testInfo, SharedTestLifeCycleWrapper sharedTestLifeCycleWrapper) {
try {
final ClassLoader testClassLoader = createTestClassLoader(testInfo);
final SharedPluginForkedTestLauncherListener listener = new SharedPluginForkedTestLauncherListener(testInfo.getTestId());
Runnable runnable = new Runnable() {
@Override
public void run() {
final Class<?> testClazz = loadClass();
boolean manageTraceObject = !testClazz.isAnnotationPresent(TraceObjectManagable.class);
SharedTestBeforeAllInvoker invoker = new SharedTestBeforeAllInvoker(testClazz);
try {
if (sharedTestLifeCycleWrapper != null) {
invoker.invoke(sharedTestLifeCycleWrapper.getLifeCycleResult());
}
} catch (Throwable th) {
logger.error(th, "invoker setter method failed. testClazz:{} testId:{}", testClazzName, testInfo.getTestId());
}
try {
listener.executionStarted();
LauncherConfig launcherConfig = LauncherConfig.builder()
.enableTestEngineAutoRegistration(false)
.enableLauncherSessionListenerAutoRegistration(false)
.enableLauncherDiscoveryListenerAutoRegistration(false)
.enablePostDiscoveryFilterAutoRegistration(false)
.enableTestExecutionListenerAutoRegistration(false)
.addTestEngines(new JupiterTestEngine())
.addTestExecutionListeners(new SharedPluginForkedTestExecutionListener(testInfo.getTestId()))
.addTestExecutionListeners(new SharedPluginForkedTestVerifierExecutionListener(manageTraceObject))
.build();

LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(DiscoverySelectors.selectClass(testClazz))
.build();
LauncherSession session = LauncherFactory.openSession(launcherConfig);
session.getLauncher().execute(request);
listener.executionFinished(TestExecutionResult.successful());
} catch (Throwable t) {
t.printStackTrace();
listener.executionFinished(TestExecutionResult.failed(t));
}
}
final ClassLoader testClassLoader = createTestClassLoader(testInfo);

private Class<?> loadClass() {
try {
return testClassLoader.loadClass(testClazzName);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
Callable<String> callable = new Callable<String>() {
@Override
public String call() {
final Class<?> testClazz = loadClass();
boolean manageTraceObject = !testClazz.isAnnotationPresent(TraceObjectManagable.class);
SharedTestBeforeAllInvoker invoker = new SharedTestBeforeAllInvoker(testClazz);
try {
if (sharedTestLifeCycleWrapper != null) {
invoker.invoke(sharedTestLifeCycleWrapper.getLifeCycleResult());
}
} catch (Throwable th) {
logger.error(th, "invoker setter method failed. testClazz:{} testId:{}", testClazzName, testInfo.getTestId());
return th.getMessage();
}
};
String threadName = testClazzName + " " + testInfo.getTestId() + " Thread";

ThreadFactory threadFactory = new ThreadFactory(threadName, testClassLoader);
Thread testThread = threadFactory.newThread(runnable);
testThread.start();
LauncherConfig launcherConfig = getLauncherConfig(testInfo.getTestId(), manageTraceObject);

LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(DiscoverySelectors.selectClass(testClazz))
.build();
try (LauncherSession session = LauncherFactory.openSession(launcherConfig)) {
Launcher launcher = session.getLauncher();
SharedPluginForkedTestLauncherListener listener = new SharedPluginForkedTestLauncherListener(testInfo.getTestId());
launcher.execute(request, new TestExecutionListener() {
@Override
public void executionStarted(TestIdentifier testIdentifier) {
listener.executionStarted(testIdentifier);
}

testThread.join(TimeUnit.MINUTES.toMillis(5));
checkTerminatedState(testThread, testClazzName + " " + testInfo.getTestId());
} catch (Exception e) {
e.printStackTrace();
@Override
public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) {
listener.executionFinished(testIdentifier, testExecutionResult);
}
});
}
return TEST_RESULT_SUCCESS;
}

private Class<?> loadClass() {
try {
return testClassLoader.loadClass(testClazzName);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
};
ExecutorService executorService = newExecutorService(testInfo, testClassLoader);
Future<String> submit = executorService.submit(callable);
try {
String result = submit.get(5, TimeUnit.MINUTES);
if (!TEST_RESULT_SUCCESS.equals(result)) {
logger.error("test failed. testClazz:{} testId:{} result:{}", testClazzName, testInfo.getTestId(), result);
}
} catch (TimeoutException ex) {
submit.cancel(true);
ex.printStackTrace();
} catch (Throwable ex) {
ex.printStackTrace();
} finally {
ReflectPluginTestVerifier.getInstance().cleanUp(true);
executorService.shutdown();
}
}

private ExecutorService newExecutorService(TestInfo testInfo, ClassLoader testClassLoader) {
String threadName = testClazzName + " " + testInfo.getTestId() + " Thread";
ThreadFactory testThreadFactory = new TestThreadFactory(threadName, testClassLoader);
return Executors.newSingleThreadExecutor(testThreadFactory);
}

private void checkTerminatedState(Thread testThread, String testInfo) {
if (testThread.isAlive()) {
throw new IllegalStateException(testInfo + " not finished");
}
private LauncherConfig getLauncherConfig(String testId, boolean manageTraceObject) {
return LauncherConfig.builder()
.enableTestEngineAutoRegistration(false)
.enableLauncherSessionListenerAutoRegistration(false)
.enableLauncherDiscoveryListenerAutoRegistration(false)
.enablePostDiscoveryFilterAutoRegistration(false)
.enableTestExecutionListenerAutoRegistration(false)
.addTestEngines(new JupiterTestEngine())
.addTestExecutionListeners(new SharedPluginForkedTestExecutionListener(testId))
.addTestExecutionListeners(new SharedPluginForkedTestVerifierExecutionListener(manageTraceObject))
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,32 @@
package com.navercorp.pinpoint.test.plugin.junit5.launcher;

import com.navercorp.pinpoint.test.plugin.ExceptionWriter;
import com.navercorp.pinpoint.test.plugin.util.URLUtils;
import org.junit.platform.engine.TestExecutionResult;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.junit.platform.launcher.TestIdentifier;

import static com.navercorp.pinpoint.test.plugin.PluginTestConstants.JUNIT_OUTPUT_DELIMITER;
import static com.navercorp.pinpoint.test.plugin.PluginTestConstants.UTF_8_NAME;

public class SharedPluginForkedTestLauncherListener {
private static final String ENGINE_ID = "[engine:junit-jupiter]";
private static final String SEGEMENT_ID = "dependency:";

private final ExceptionWriter writer = new ExceptionWriter();
private String testId;
private final String testId;

public SharedPluginForkedTestLauncherListener(String testId) throws UnsupportedEncodingException {
this.testId = URLEncoder.encode(testId, UTF_8_NAME);
public SharedPluginForkedTestLauncherListener(String testId) {
this.testId = URLUtils.encode(testId);
}

public void executionStarted() {
System.out.println(JUNIT_OUTPUT_DELIMITER + "executionStarted" + JUNIT_OUTPUT_DELIMITER + toReportId());
public void executionStarted(TestIdentifier testIdentifier) {
System.out.println(JUNIT_OUTPUT_DELIMITER + "executionStarted" + JUNIT_OUTPUT_DELIMITER + toReportId(testIdentifier));
}

public void executionFinished(TestExecutionResult testExecutionResult) {
System.out.println(JUNIT_OUTPUT_DELIMITER + "executionFinished" + JUNIT_OUTPUT_DELIMITER + toReportId() + JUNIT_OUTPUT_DELIMITER + toResult(testExecutionResult));
public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) {
System.out.println(JUNIT_OUTPUT_DELIMITER + "executionFinished" + JUNIT_OUTPUT_DELIMITER + toReportId(testIdentifier) + JUNIT_OUTPUT_DELIMITER + toResult(testExecutionResult));
}

String toReportId() {
String toReportId(TestIdentifier testIdentifier) {
return "[" + SEGEMENT_ID + testId + "]";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

Expand All @@ -47,8 +48,8 @@ public SharedTestExecutor(String testClazzName, ClassLoader testClassLoader) {
this.testClazzName = Objects.requireNonNull(testClazzName, "testClazzName");
this.testClassLoader = Objects.requireNonNull(testClassLoader, "testClassLoader");

ThreadFactory threadFactory = new ThreadFactory(testClazzName + "-Shared-Executor", testClassLoader);
this.executor = Executors.newSingleThreadExecutor(threadFactory);
ThreadFactory testThreadFactory = new TestThreadFactory(testClazzName + "-Shared-Executor", testClassLoader);
this.executor = Executors.newSingleThreadExecutor(testThreadFactory);
}

public void startBefore(long timeout, TimeUnit unit) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.navercorp.pinpoint.test.plugin.shared;

import java.util.Objects;
import java.util.concurrent.ThreadFactory;

public class ThreadFactory implements java.util.concurrent.ThreadFactory {
public class TestThreadFactory implements ThreadFactory {
private final String threadName;
private final ClassLoader cl;

public ThreadFactory(String threadName, ClassLoader cl) {
public TestThreadFactory(String threadName, ClassLoader cl) {
this.threadName = Objects.requireNonNull(threadName, "threadName");
this.cl = Objects.requireNonNull(cl, "cl");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.navercorp.pinpoint.test.plugin.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -40,5 +42,12 @@ private static URL toURL(Path jar) {
}
}

public static String encode(String str) {
try {
return java.net.URLEncoder.encode(str, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}

}

0 comments on commit eeb6751

Please # to comment.