diff --git a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/DefaultPluginTestInstance.java b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/DefaultPluginTestInstance.java index 3ff41e3ffa31..75e914d48b1c 100644 --- a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/DefaultPluginTestInstance.java +++ b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/DefaultPluginTestInstance.java @@ -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; @@ -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; @@ -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 diff --git a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/junit5/launcher/SharedPluginForkedTestExecutionListener.java b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/junit5/launcher/SharedPluginForkedTestExecutionListener.java index c48518f41b36..577ce5c7dc3a 100644 --- a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/junit5/launcher/SharedPluginForkedTestExecutionListener.java +++ b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/junit5/launcher/SharedPluginForkedTestExecutionListener.java @@ -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 diff --git a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/junit5/launcher/SharedPluginForkedTestLauncher.java b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/junit5/launcher/SharedPluginForkedTestLauncher.java index ca3cd42a7bd1..c3314ec60cf6 100644 --- a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/junit5/launcher/SharedPluginForkedTestLauncher.java +++ b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/junit5/launcher/SharedPluginForkedTestLauncher.java @@ -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; @@ -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; @@ -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) { @@ -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 callable = new Callable() { + @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 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(); } + } diff --git a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/junit5/launcher/SharedPluginForkedTestLauncherListener.java b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/junit5/launcher/SharedPluginForkedTestLauncherListener.java index 9025556d032c..d56253677fcb 100644 --- a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/junit5/launcher/SharedPluginForkedTestLauncherListener.java +++ b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/junit5/launcher/SharedPluginForkedTestLauncherListener.java @@ -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 + "]"; } diff --git a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/shared/SharedTestExecutor.java b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/shared/SharedTestExecutor.java index 9314e1ab1457..493ba97bd673 100644 --- a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/shared/SharedTestExecutor.java +++ b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/shared/SharedTestExecutor.java @@ -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; @@ -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) { diff --git a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/shared/ThreadFactory.java b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/shared/TestThreadFactory.java similarity index 75% rename from agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/shared/ThreadFactory.java rename to agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/shared/TestThreadFactory.java index 968929ff99a8..f77349c07a81 100644 --- a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/shared/ThreadFactory.java +++ b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/shared/TestThreadFactory.java @@ -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"); } diff --git a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/util/URLUtils.java b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/util/URLUtils.java index 7b0149b452a1..e7c5f4b3cf75 100644 --- a/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/util/URLUtils.java +++ b/agent-module/plugins-test-module/plugins-test/src/main/java/com/navercorp/pinpoint/test/plugin/util/URLUtils.java @@ -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; @@ -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); + } + } }