diff options
author | Vikas Chandra | 2017-08-23 17:43:29 +0000 |
---|---|---|
committer | Vikas Chandra | 2017-08-24 07:09:55 +0000 |
commit | fd80edd98fb8eba70a02a375372cc12530a23ddc (patch) | |
tree | d718a2684be5c91adee4c42f01b3899bbb305f3c | |
parent | 75ff251d4ac1f8a43f9753d28022bd17024e7750 (diff) | |
download | eclipse.pde.ui-fd80edd98fb8eba70a02a375372cc12530a23ddc.tar.gz eclipse.pde.ui-fd80edd98fb8eba70a02a375372cc12530a23ddc.tar.xz eclipse.pde.ui-fd80edd98fb8eba70a02a375372cc12530a23ddc.zip |
Bug 520811 - [JUnit 5] Running junit5 test in plugin project gives testU20170901-0900U20170831-0400U20170830-0850U20170828-0235U20170826-0930U20170826-0300U20170824-1210U20170824-0830U20170824-0400
loader org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader not
found:
Change-Id: I5555cec1ad750f84fc1a7f5fa54acc80091c01be
Signed-off-by: Vikas Chandra <Vikas.Chandra@in.ibm.com>
-rw-r--r-- | ui/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java | 193 |
1 files changed, 187 insertions, 6 deletions
diff --git a/ui/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java b/ui/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java index f6d8f33676..1c9b525f60 100644 --- a/ui/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java +++ b/ui/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2015 IBM Corporation and others. + * Copyright (c) 2003, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,13 +11,17 @@ *******************************************************************************/ package org.eclipse.pde.internal.junit.runtime; +import java.io.File; import java.io.IOException; +import java.net.URI; import java.net.URL; -import java.util.Enumeration; -import java.util.Locale; +import java.util.*; import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.internal.junit.runner.RemoteTestRunner; +import org.eclipse.osgi.internal.framework.EquinoxBundle; import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.wiring.BundleWiring; /** * Runs JUnit tests contained inside a plugin. @@ -51,6 +55,111 @@ public class RemotePluginTestRunner extends RemoteTestRunner { } } + static class TestBundleClassLoader extends ClassLoader { + protected Bundle bundle; + + public TestBundleClassLoader(Bundle target) { + this.bundle = target; + } + + @Override + protected Class<?> findClass(String name) throws ClassNotFoundException { + return bundle.loadClass(name); + } + + @Override + protected URL findResource(String name) { + return bundle.getResource(name); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + @Override + protected Enumeration findResources(String name) throws IOException { + return bundle.getResources(name); + } + + @Override + public Enumeration<URL> getResources(String res) throws IOException { + List<URL> resources = new ArrayList<>(6); + String location = null; + URL url = null; + if (bundle instanceof EquinoxBundle) { + location = ((EquinoxBundle) bundle).getLocation(); + } + if (location != null && location.startsWith("reference:")) { //$NON-NLS-1$ + location = location.substring(10, location.length()); + URI uri = URI.create(location); + String newPath = uri.getPath() + "bin" + '/' + res; //$NON-NLS-1$ + URI newUri = uri.resolve(newPath); + url = newUri.normalize().toURL(); + } + if (url != null) { + File f = new File(url.getFile()); + if (f.exists()) + resources.add(url); + } + else + return Collections.emptyEnumeration(); + + return Collections.enumeration(resources); + } + } + + class MultiBundleClassLoader extends ClassLoader { + private List<Bundle> bundleList; + + public MultiBundleClassLoader(List<Bundle> platformEngineBundles) { + this.bundleList = platformEngineBundles; + + } + @Override + protected Class<?> findClass(String name) throws ClassNotFoundException { + Class<?> c = null; + for (Bundle temp : bundleList) { + try { + c = temp.loadClass(name); + if (c != null) + return c; + } catch (ClassNotFoundException e) { + } + } + return c; + } + + @Override + protected URL findResource(String name) { + URL url = null; + for (Bundle temp : bundleList) { + url = temp.getResource(name); + if (url != null) + return url; + } + return url; + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + @Override + protected Enumeration findResources(String name) throws IOException { + Enumeration enumFinal = null; + for (int i = 0; i < bundleList.size(); i++) { + if (i == 0) { + enumFinal = bundleList.get(i).getResources(name); + continue; + } + Enumeration e2 = bundleList.get(i).getResources(name); + Vector temp = new Vector(); + while (enumFinal != null && enumFinal.hasMoreElements()) { + temp.add(enumFinal.nextElement()); + } + while (e2 != null && e2.hasMoreElements()) { + temp.add(e2.nextElement()); + } + enumFinal = temp.elements(); + } + return enumFinal; + } + } + /** * The main entry point. Supported arguments in addition * to the ones supported by RemoteTestRunner: @@ -63,7 +172,24 @@ public class RemotePluginTestRunner extends RemoteTestRunner { public static void main(String[] args) { RemotePluginTestRunner testRunner = new RemotePluginTestRunner(); testRunner.init(args); + ClassLoader currentTCCL = Thread.currentThread().getContextClassLoader(); + if (isJUnit5(args)) { + //change the classloader so that the test classes in testplugin are discoverable + //by junit5 framework see bug 520811 + Thread.currentThread().setContextClassLoader(getPluginClassLoader(testRunner.getfTestPluginName())); + } testRunner.run(); + if (isJUnit5(args)) { + Thread.currentThread().setContextClassLoader(currentTCCL); + } + } + + private static ClassLoader getPluginClassLoader(String getfTestPluginName) { + Bundle bundle = Platform.getBundle(getfTestPluginName); + if (bundle == null) { + throw new IllegalArgumentException("Bundle \"" + getfTestPluginName + "\" not found. Possible causes include missing dependencies, too restrictive version ranges, or a non-matching required execution environment."); //$NON-NLS-1$ //$NON-NLS-2$ + } + return new TestBundleClassLoader(bundle); } /** @@ -72,7 +198,7 @@ public class RemotePluginTestRunner extends RemoteTestRunner { */ @Override protected ClassLoader getTestClassLoader() { - final String pluginId = fTestPluginName; + final String pluginId = getfTestPluginName(); return getClassLoader(pluginId); } @@ -87,19 +213,66 @@ public class RemotePluginTestRunner extends RemoteTestRunner { @Override public void init(String[] args) { readPluginArgs(args); + boolean isJUnit5 = isJUnit5(args); + if (isJUnit5) { + // changing the classloader to get the testengines for junit5 + // during initialization - see bug 520811 + ClassLoader currentTCCL = Thread.currentThread().getContextClassLoader(); + try { + // Get all bundles with junit5 test engine + List<String> platformEngines = new ArrayList<String>(); + Bundle bundle = FrameworkUtil.getBundle(getClass()); + Bundle[] bundles = bundle.getBundleContext().getBundles(); + for (Bundle iBundle : bundles) { + try { + BundleWiring bundleWiring = Platform.getBundle(iBundle.getSymbolicName()).adapt(BundleWiring.class); + Collection<String> listResources = bundleWiring.listResources("META-INF/services", "org.junit.platform.engine.TestEngine", BundleWiring.LISTRESOURCES_LOCAL); //$NON-NLS-1$//$NON-NLS-2$ + if (!listResources.isEmpty()) + platformEngines.add(iBundle.getSymbolicName()); + } catch (Exception e) { + // check the next bundle + } + } + + Thread.currentThread().setContextClassLoader(getJUnit5Classloader(platformEngines)); + defaultInit(args); + } finally { + Thread.currentThread().setContextClassLoader(currentTCCL); + } + RemoteTestRunner.fgTestRunServer = this; + return; + } defaultInit(args); } + private ClassLoader getJUnit5Classloader(List<String> platformEngine) { + List<Bundle> platformEngineBundles = new ArrayList<Bundle>(); + for (Iterator<String> iterator = platformEngine.iterator(); iterator.hasNext();) { + String string = iterator.next(); + Bundle bundle = Platform.getBundle(string); + platformEngineBundles.add(bundle); + } + return new MultiBundleClassLoader(platformEngineBundles); + } + + private static boolean isJUnit5(String[] args) { + for (int i = 0; i < args.length; i++) { + if (args[i].equals("org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader")) //$NON-NLS-1$ + return true; + } + return false; + } + public void readPluginArgs(String[] args) { for (int i = 0; i < args.length; i++) { if (isFlag(args, i, "-testpluginname")) //$NON-NLS-1$ - fTestPluginName = args[i + 1]; + setfTestPluginName(args[i + 1]); if (isFlag(args, i, "-loaderpluginname")) //$NON-NLS-1$ fLoaderClassLoader = getClassLoader(args[i + 1]); } - if (fTestPluginName == null) + if (getfTestPluginName() == null) throw new IllegalArgumentException("Parameter -testpluginnname not specified."); //$NON-NLS-1$ if (fLoaderClassLoader == null) @@ -115,4 +288,12 @@ public class RemotePluginTestRunner extends RemoteTestRunner { String lowerCase = args[i].toLowerCase(Locale.ENGLISH); return lowerCase.equals(wantedFlag) && i < args.length - 1; } + + public String getfTestPluginName() { + return fTestPluginName; + } + + public void setfTestPluginName(String fTestPluginName) { + this.fTestPluginName = fTestPluginName; + } } |