diff --git a/build.gradle b/build.gradle index 55e2c7d94..8e728a867 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ import org.gradle.internal.os.OperatingSystem import java.util.regex.* plugins { - id 'com.gradle.build-scan' version '1.8' + id 'com.gradle.build-scan' version '2.4.2' } buildScan { diff --git a/buildSrc/src/main/groovy/eclipsebuild/TestBundlePlugin.groovy b/buildSrc/src/main/groovy/eclipsebuild/TestBundlePlugin.groovy index 289b788b5..79dd9fa32 100644 --- a/buildSrc/src/main/groovy/eclipsebuild/TestBundlePlugin.groovy +++ b/buildSrc/src/main/groovy/eclipsebuild/TestBundlePlugin.groovy @@ -11,19 +11,13 @@ package eclipsebuild -import org.gradle.api.Task -import eclipsebuild.testing.EclipseTestTask -import javax.inject.Inject - -import eclipsebuild.testing.EclipseTestExecuter -import eclipsebuild.testing.EclipseTestExtension +import eclipsebuild.testing.EclipseTestTask import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.api.Task import org.gradle.api.artifacts.ProjectDependency -import org.gradle.api.internal.file.FileResolver import org.gradle.api.tasks.testing.Test -import org.gradle.internal.operations.BuildOperationExecutor /** * Gradle plug-in to build Eclipse test bundles and launch tests. @@ -54,30 +48,18 @@ import org.gradle.internal.operations.BuildOperationExecutor */ class TestBundlePlugin implements Plugin { - // name of the root node in the DSL - static String DSL_EXTENSION_NAME = "eclipseTest" - // task names static final TASK_NAME_ECLIPSE_TEST = 'eclipseTest' static final TASK_NAME_CROSS_VERSION_ECLIPSE_TEST = 'crossVersionEclipseTest' - public final FileResolver fileResolver - - @Inject - public TestBundlePlugin(FileResolver fileResolver) { - this.fileResolver = fileResolver - } - @Override public void apply(Project project) { configureProject(project) - validateDslBeforeBuildStarts(project) addTaskCreateEclipseTest(project) } static void configureProject(Project project) { - project.extensions.create(DSL_EXTENSION_NAME, EclipseTestExtension) project.getPlugins().apply(eclipsebuild.BundlePlugin) // append the sources of each first-level dependency and its transitive dependencies of @@ -96,13 +78,6 @@ class TestBundlePlugin implements Plugin { dep.children.each { childDep -> addSourcesRecursively(project, childDep) } } - static void validateDslBeforeBuildStarts(Project project) { - project.gradle.taskGraph.whenReady { - // the eclipse application must be defined - assert project.eclipseTest.applicationName != null - } - } - static void addTaskCreateEclipseTest(Project project) { Config config = Config.on(project) @@ -120,7 +95,6 @@ class TestBundlePlugin implements Plugin { description = taskDescription // configure the test runner to execute all classes from the project - testExecuter = new EclipseTestExecuter(project, config, services.get(BuildOperationExecutor.class)) testClassesDirs = project.sourceSets.main.output.classesDirs classpath = project.sourceSets.main.output + project.sourceSets.test.output reports.html.destination = new File("${project.reporting.baseDir}/eclipseTest") @@ -146,6 +120,9 @@ class TestBundlePlugin implements Plugin { } } + maxParallelForks = 1 + forkEvery = 0 + doFirst { beforeEclipseTest(project, config, testDistributionDir, additionalPluginsDir) } } diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipsePluginTestClassScanner.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipsePluginTestClassScanner.java deleted file mode 100644 index d611a47bf..000000000 --- a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipsePluginTestClassScanner.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2015 the original author or authors. - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Donát Csikós (Gradle Inc.) - initial API and implementation and initial documentation - */ - -package eclipsebuild.testing; - -import java.io.File; - -import org.apache.bcel.classfile.ClassParser; -import org.apache.bcel.classfile.JavaClass; -import org.gradle.api.file.EmptyFileVisitor; -import org.gradle.api.file.FileTree; -import org.gradle.api.file.FileVisitDetails; -import org.gradle.api.internal.tasks.testing.DefaultTestClassRunInfo; -import org.gradle.api.internal.tasks.testing.TestClassProcessor; -import org.gradle.api.internal.tasks.testing.TestClassRunInfo; - -public final class EclipsePluginTestClassScanner implements Runnable { - - private final FileTree candidateClassFiles; - private final TestClassProcessor testClassProcessor; - - public EclipsePluginTestClassScanner(FileTree candidateClassFiles, TestClassProcessor testClassProcessor) { - this.candidateClassFiles = candidateClassFiles; - this.testClassProcessor = testClassProcessor; - } - - @Override - public void run() { - this.candidateClassFiles.visit(new ClassFileVisitor() { - - @Override - public void visitClassFile(FileVisitDetails fileDetails) { - String className = fileDetails.getRelativePath().getPathString().replaceAll("\\.class", "").replace('/', '.'); - TestClassRunInfo testClass = new DefaultTestClassRunInfo(className); - EclipsePluginTestClassScanner.this.testClassProcessor.processTestClass(testClass); - } - }); - } - - private abstract class ClassFileVisitor extends EmptyFileVisitor { - - @Override - public void visitFile(FileVisitDetails fileDetails) { - final File file = fileDetails.getFile(); - if (isValidTestClassFile(file)) { - visitClassFile(fileDetails); - } - } - - private boolean isValidTestClassFile(final File file) { - try { - return isTopLevelClass(file) && isConcreteClass(file); - } catch (Exception e) { - e.printStackTrace(); - return false; - } - } - - private boolean isTopLevelClass(final File file) { - return file.getAbsolutePath().endsWith(".class") && !file.getAbsolutePath().contains("$"); - } - - private boolean isConcreteClass(File file) throws Exception { - ClassParser parser = new ClassParser(file.getAbsolutePath()); - JavaClass javaClass = parser.parse(); - return !javaClass.isAbstract() && !javaClass.isInterface(); - } - - public abstract void visitClassFile(FileVisitDetails fileDetails); - } -} diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestAdapter.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestAdapter.java new file mode 100644 index 000000000..bcb32c33c --- /dev/null +++ b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestAdapter.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2015 the original author or authors. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Donát Csikós (Gradle Inc.) - initial API and implementation and initial documentation + */ + +package eclipsebuild.testing; + +import org.eclipse.jdt.internal.junit.model.ITestRunListener2; +import org.gradle.api.internal.tasks.testing.DefaultTestClassDescriptor; +import org.gradle.api.internal.tasks.testing.DefaultTestDescriptor; +import org.gradle.api.internal.tasks.testing.DefaultTestMethodDescriptor; +import org.gradle.api.internal.tasks.testing.DefaultTestOutputEvent; +import org.gradle.api.internal.tasks.testing.DefaultTestSuiteDescriptor; +import org.gradle.api.internal.tasks.testing.TestCompleteEvent; +import org.gradle.api.internal.tasks.testing.TestDescriptorInternal; +import org.gradle.api.internal.tasks.testing.TestResultProcessor; +import org.gradle.api.internal.tasks.testing.TestStartEvent; +import org.gradle.api.internal.tasks.testing.results.AttachParentTestResultProcessor; +import org.gradle.api.tasks.testing.TestOutputEvent; +import org.gradle.api.tasks.testing.TestResult; +import org.gradle.api.tasks.testing.TestResult.ResultType; +import org.gradle.internal.id.IdGenerator; +import org.gradle.internal.time.Clock; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public final class EclipseTestAdapter implements ITestRunListener2 { + + private final TestResultProcessor resultProcessor; + private final Clock clock; + private final IdGenerator idGenerator; + private final Object lock = new Object(); + private final Map executing = new HashMap(); + + + public EclipseTestAdapter(TestResultProcessor resultProcessor, Clock clock, IdGenerator idGenerator) { + this.resultProcessor = resultProcessor; + this.clock = clock; + this.idGenerator = idGenerator; + } + + @Override + public synchronized void testStarted(String testId, String testName) { + TestDescriptorInternal descriptor = nullSafeDescriptor(idGenerator.generateId(), testName); + synchronized (lock) { + TestDescriptorInternal oldTest = executing.put(testId, descriptor); + assert oldTest == null : String.format("Unexpected start event for %s", testName); + } + resultProcessor.started(descriptor, startEvent()); + } + + @Override + public synchronized void testEnded(String testId, String testName) { + long endTime = clock.getCurrentTime(); + TestDescriptorInternal testInternal; + ResultType resultType = ResultType.SUCCESS; + synchronized (lock) { + testInternal = executing.remove(testId); + if (testInternal == null && executing.size() == 1) { + // Assume that test has renamed itself (this can actually happen) + testInternal = executing.values().iterator().next(); + executing.clear(); + } + assert testInternal != null : String.format("Unexpected end event for %s", testName); + resultType = null; + } + resultProcessor.completed(testInternal.getId(), new TestCompleteEvent(endTime, resultType)); + } + + @Override + public synchronized void testFailed(int status, String testId, String testName, String trace, String expected, String actual) { + TestDescriptorInternal descriptor = nullSafeDescriptor(idGenerator.generateId(), testName); + TestDescriptorInternal testInternal; + synchronized (lock) { + testInternal = executing.get(testId); + } + boolean needEndEvent = false; + if (testInternal == null) { + // This can happen when, for example, a @BeforeClass or @AfterClass method fails + needEndEvent = true; + testInternal = descriptor; + resultProcessor.started(testInternal, startEvent()); + } + String message = testName + " failed"; + if (expected != null || actual != null) { + message += " (expected=" + expected + ", actual=" + actual + ")"; + } + resultProcessor.failure(testInternal.getId(), new EclipseTestFailure(message, trace)); + if (needEndEvent) { + resultProcessor.completed(testInternal.getId(), new TestCompleteEvent(clock.getCurrentTime())); + } + } + + @Override + public synchronized void testRunStarted(int testCount) { + } + + @Override + public synchronized void testRunEnded(long elapsedTime) { + } + + @Override + public synchronized void testRunStopped(long elapsedTime) { + } + + @Override + public synchronized void testRunTerminated() { + } + + @Override + public synchronized void testReran(String testId, String testClass, String testName, int status, String trace, String expected, String actual) { + } + + @Override + public synchronized void testTreeEntry(String description) { + } + + private TestDescriptorInternal nullSafeDescriptor(Object id, String testName) { + String methodName = methodName(testName); + if (methodName != null) { + return new DefaultTestDescriptor(id, className(testName), methodName); + } else { + return new DefaultTestDescriptor(id, className(testName), "classMethod"); + } + } + + private static String className(String testName) { + return testName.substring(testName.lastIndexOf('(') + 1, testName.length() - 1); + } + + private static String methodName(String testName) { + return testName.substring(0, testName.lastIndexOf('(')); + } + + private TestStartEvent startEvent() { + return new TestStartEvent(clock.getCurrentTime()); + } +} diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestClassDetector.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestClassDetector.java new file mode 100644 index 000000000..c9ce1189f --- /dev/null +++ b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestClassDetector.java @@ -0,0 +1,15 @@ +package eclipsebuild.testing; + +import org.gradle.api.internal.tasks.testing.detection.TestClassVisitor; + +class EclipseTestClassDetector extends TestClassVisitor { + + EclipseTestClassDetector(final EclipseTestFrameworkDetector detector) { + super(detector); + } + + @Override + protected boolean ignoreNonStaticInnerClass() { + return true; + } +} diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestExecuter.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestExecuter.java deleted file mode 100644 index 818915233..000000000 --- a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestExecuter.java +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (c) 2015 the original author or authors. - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Donát Csikós (Gradle Inc.) - initial API and implementation and initial documentation - */ - -package eclipsebuild.testing; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import eclipsebuild.Config; -import eclipsebuild.Constants; -import eclipsebuild.TestBundlePlugin; -import org.gradle.api.GradleException; -import org.gradle.api.JavaVersion; -import org.gradle.api.Project; -import org.gradle.api.file.FileTree; -import org.gradle.api.internal.file.FileResolver; -import org.gradle.api.internal.tasks.testing.*; -import org.gradle.api.internal.tasks.testing.detection.TestFrameworkDetector; -import org.gradle.api.internal.tasks.testing.processors.TestMainAction; -import org.gradle.api.logging.Logger; -import org.gradle.api.logging.Logging; -import org.gradle.api.tasks.testing.Test; -import org.gradle.api.tasks.testing.TestOutputEvent; -import org.gradle.initialization.DefaultBuildCancellationToken; -import org.gradle.internal.concurrent.DefaultExecutorFactory; -import org.gradle.internal.operations.BuildOperationExecutor; -import org.gradle.internal.time.Time; -import org.gradle.process.ExecResult; -import org.gradle.process.internal.DefaultJavaExecAction; -import org.gradle.process.internal.JavaExecAction; - -import org.eclipse.jdt.internal.junit.model.ITestRunListener2; -import org.eclipse.jdt.internal.junit.model.RemoteTestRunnerClient; - -public final class EclipseTestExecuter implements TestExecuter { - - private static final Logger LOGGER = Logging.getLogger(EclipseTestExecuter.class); - - private final Project project; - private final Config config; - private final BuildOperationExecutor executor; - - public EclipseTestExecuter(Project project, Config config, BuildOperationExecutor executor) { - this.project = project; - this.config = config; - this.executor = executor; - } - - @Override - public void execute(TestExecutionSpec test, TestResultProcessor testResultProcessor) { - LOGGER.info("Executing tests in Eclipse"); - - int pdeTestPort = new PDETestPortLocator().locatePDETestPortNumber(); - if (pdeTestPort == -1) { - throw new GradleException("Cannot allocate port for PDE test run"); - } - LOGGER.info("Will use port {} to communicate with Eclipse.", pdeTestPort); - - runPDETestsInEclipse(test, testResultProcessor, pdeTestPort); - } - - private EclipseTestExtension getExtension(Test testTask) { - return (EclipseTestExtension) testTask.getProject().getExtensions().findByName("eclipseTest"); - } - - private void runPDETestsInEclipse(final TestExecutionSpec testSpec, final TestResultProcessor testResultProcessor, - final int pdeTestPort) { - - Test testTask = ((EclipseTestExecutionSpec)testSpec).getTestTask(); - - final Object testTaskOperationId = this.executor.getCurrentOperation().getParentId(); - final Object rootTestSuiteId = testTask.getPath(); - - ExecutorService threadPool = Executors.newFixedThreadPool(2); - File runDir = new File(testTask.getProject().getBuildDir(), testTask.getName()); - - File testEclipseDir = new File(this.project.property("buildDir") + "/eclipseTest/eclipse"); - - // File configIniFile = getInputs().getFiles().getSingleFile(); - File configIniFile = new File(testEclipseDir, "configuration/config.ini"); - assert configIniFile.exists(); - - File runPluginsDir = new File(testEclipseDir, "plugins"); - LOGGER.info("Eclipse test directory is {}", runPluginsDir.getPath()); - File equinoxLauncherFile = getEquinoxLauncherFile(testEclipseDir); - LOGGER.info("equinox launcher file {}", equinoxLauncherFile); - - final JavaExecAction javaExecHandleBuilder = new DefaultJavaExecAction(getFileResolver(testTask), new DefaultExecutorFactory().create("Exec process"), new DefaultBuildCancellationToken()); - javaExecHandleBuilder.setClasspath(this.project.files(equinoxLauncherFile)); - javaExecHandleBuilder.setMain("org.eclipse.equinox.launcher.Main"); - - String javaHome = getExtension(testTask).getTestEclipseJavaHome(); - File executable = new File(javaHome, "bin/java"); - if (executable.exists()) { - javaExecHandleBuilder.setExecutable(executable); - } else { - LOGGER.warn("Java executable doesn't exist: " + executable.getAbsolutePath()); - } - - List programArgs = new ArrayList(); - - programArgs.add("-os"); - programArgs.add(Constants.getOs()); - programArgs.add("-ws"); - programArgs.add(Constants.getWs()); - programArgs.add("-arch"); - programArgs.add(Constants.getArch()); - - if (getExtension(testTask).isConsoleLog()) { - programArgs.add("-consoleLog"); - } - File optionsFile = getExtension(testTask).getOptionsFile(); - if (optionsFile != null) { - programArgs.add("-debug"); - programArgs.add(optionsFile.getAbsolutePath()); - } - programArgs.add("-version"); - programArgs.add("4"); - programArgs.add("-port"); - programArgs.add(Integer.toString(pdeTestPort)); - programArgs.add("-testLoaderClass"); - programArgs.add("org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader"); - programArgs.add("-loaderpluginname"); - programArgs.add("org.eclipse.jdt.junit4.runtime"); - programArgs.add("-classNames"); - - List testNames = new ArrayList(collectTestNames(testTask, testTaskOperationId, rootTestSuiteId)); - Collections.sort(testNames); - programArgs.addAll(testNames); - - programArgs.add("-application"); - programArgs.add(getExtension(testTask).getApplicationName()); - programArgs.add("-product org.eclipse.platform.ide"); - // alternatively can use URI for -data and -configuration (file:///path/to/dir/) - programArgs.add("-data"); - programArgs.add(runDir.getAbsolutePath() + File.separator + "workspace"); - programArgs.add("-configuration"); - programArgs.add(configIniFile.getParentFile().getAbsolutePath()); - - programArgs.add("-testpluginname"); - String fragmentHost = getExtension(testTask).getFragmentHost(); - if (fragmentHost != null) { - programArgs.add(fragmentHost); - } else { - programArgs.add(this.project.getName()); - } - - javaExecHandleBuilder.setArgs(programArgs); - javaExecHandleBuilder.setSystemProperties(testTask.getSystemProperties()); - javaExecHandleBuilder.setEnvironment(testTask.getEnvironment()); - - // TODO this should be specified when creating the task (to allow override in build script) - List jvmArgs = new ArrayList(); - jvmArgs.add("-XX:MaxPermSize=256m"); - jvmArgs.add("-Xms40m"); - jvmArgs.add("-Xmx1024m"); - - // Java 9 workaround from https://bugs.eclipse.org/bugs/show_bug.cgi?id=493761 - // TODO we should remove this option when it is not required by Eclipse - if (JavaVersion.current().isJava9Compatible()) { - jvmArgs.add("--add-modules=ALL-SYSTEM"); - } - // uncomment to debug spawned Eclipse instance - // jvmArgs.add("-Xdebug"); - // jvmArgs.add("-Xrunjdwp:transport=dt_socket,address=8998,server=y"); - - if (Constants.getOs().equals("macosx")) { - jvmArgs.add("-XstartOnFirstThread"); - } - - // declare mirror urls if exists - Map mirrorUrls = new HashMap<>(); - if (project.hasProperty("mirrors")) { - String mirrorsString = (String) project.property("mirrors"); - String[] mirrors = mirrorsString.split(","); - for (String mirror : mirrors) { - if (!"".equals(mirror)) { - String[] nameAndUrl = mirror.split(":", 2); - mirrorUrls.put(nameAndUrl[0], nameAndUrl[1]); - } - } - } - - for (Map.Entry mirrorUrl : mirrorUrls.entrySet()) { - jvmArgs.add("-Dorg.eclipse.buildship.eclipsetest.mirrors." + mirrorUrl.getKey() + "=" + mirrorUrl.getValue()); - } - - javaExecHandleBuilder.setJvmArgs(jvmArgs); - javaExecHandleBuilder.setWorkingDir(this.project.getBuildDir()); - - final CountDownLatch latch = new CountDownLatch(1); - Future eclipseJob = threadPool.submit(new Runnable() { - @Override - public void run() { - try { - ExecResult execResult = javaExecHandleBuilder.execute(); - execResult.assertNormalExitValue(); - } - catch (Exception e) { - e.printStackTrace(); - } - finally { - latch.countDown(); - } - } - }); - // TODO - final String suiteName = this.project.getName(); - Future testCollectorJob = threadPool.submit(new Runnable() { - @Override - public void run() { - EclipseTestListener pdeTestListener = new EclipseTestListener(testResultProcessor, suiteName, this, testTaskOperationId, rootTestSuiteId); - new RemoteTestRunnerClient().startListening(new ITestRunListener2[] { pdeTestListener }, pdeTestPort); - LOGGER.info("Listening on port " + pdeTestPort + " for test suite " + suiteName + " results ..."); - synchronized (this) { - try { - wait(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } finally { - latch.countDown(); - } - } - } - }); - try { - latch.await(getExtension(testTask).getTestTimeoutSeconds(), TimeUnit.SECONDS); - // short chance to do cleanup - eclipseJob.get(15, TimeUnit.SECONDS); - testCollectorJob.get(15, TimeUnit.SECONDS); - } catch (Exception e) { - throw new GradleException("Test execution failed", e); - } - } - - private File getEquinoxLauncherFile(File testEclipseDir) { - File[] plugins = new File(testEclipseDir, "plugins").listFiles(); - for (File plugin : plugins) { - if (plugin.getName().startsWith("org.eclipse.equinox.launcher_")) { - return plugin; - } - } - return null; - } - - private FileResolver getFileResolver(Test testTask) { - return testTask.getProject().getPlugins().findPlugin(TestBundlePlugin.class).fileResolver; - } - - private List collectTestNames(Test testTask, Object testTaskOperationId, Object rootTestSuiteId) { - ClassNameCollectingProcessor processor = new ClassNameCollectingProcessor(); - Runnable detector; - final FileTree testClassFiles = testTask.getCandidateClassFiles(); - if (testTask.isScanForTestClasses()) { - TestFrameworkDetector testFrameworkDetector = testTask.getTestFramework().getDetector(); - testFrameworkDetector.setTestClasses(testTask.getTestClassesDirs().getFiles()); - testFrameworkDetector.setTestClasspath(testTask.getClasspath().getFiles()); - detector = new EclipsePluginTestClassScanner(testClassFiles, processor); - } else { - detector = new EclipsePluginTestClassScanner(testClassFiles, processor); - } - - new TestMainAction(detector, processor, new NoOpTestResultProcessor(), Time.clock(), testTaskOperationId, rootTestSuiteId, String.format("Gradle Eclipse Test Run %s", testTask.getIdentityPath())).run(); - LOGGER.info("collected test class names: {}", processor.classNames); - return processor.classNames; - } - - @Override - public void stopNow() { - - } - public static final class NoOpTestResultProcessor implements TestResultProcessor { - - - @Override - public void started(TestDescriptorInternal testDescriptorInternal, TestStartEvent testStartEvent) { - } - - @Override - public void completed(Object o, TestCompleteEvent testCompleteEvent) { - } - - @Override - public void output(Object o, TestOutputEvent testOutputEvent) { - } - - @Override - public void failure(Object o, Throwable throwable) { - } - } - - private class ClassNameCollectingProcessor implements TestClassProcessor { - public List classNames = new ArrayList(); - - @Override - public void startProcessing(TestResultProcessor testResultProcessor) { - // no-op - } - - @Override - public void processTestClass(TestClassRunInfo testClassRunInfo) { - this.classNames.add(testClassRunInfo.getTestClassName()); - } - - @Override - public void stop() { - // no-op - } - - @Override - public void stopNow() { - // no-op - } - } -} diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestExecutionSpec.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestExecutionSpec.java index dd82b6d2f..b5db1cf42 100644 --- a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestExecutionSpec.java +++ b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestExecutionSpec.java @@ -1,23 +1,15 @@ package eclipsebuild.testing; -import org.gradle.api.file.FileCollection; -import org.gradle.api.file.FileTree; import org.gradle.api.internal.tasks.testing.JvmTestExecutionSpec; -import org.gradle.api.internal.tasks.testing.TestExecutionSpec; import org.gradle.api.internal.tasks.testing.TestFramework; import org.gradle.api.tasks.testing.Test; -import org.gradle.process.JavaForkOptions; -import org.gradle.util.Path; - -import java.io.File; -import java.util.Set; public class EclipseTestExecutionSpec extends JvmTestExecutionSpec { private final Test testTask; - public EclipseTestExecutionSpec(JvmTestExecutionSpec spec, Test testTask) { - super(spec.getTestFramework(), spec.getClasspath(), spec.getCandidateClassFiles(), spec.isScanForTestClasses(), spec.getTestClassesDirs(), spec.getPath(), spec.getIdentityPath(), spec.getForkEvery(), spec.getJavaForkOptions(), spec.getMaxParallelForks(), spec.getPreviousFailedTestClasses()); + public EclipseTestExecutionSpec(JvmTestExecutionSpec spec, TestFramework framework, Test testTask) { + super(framework, spec.getClasspath(), spec.getCandidateClassFiles(), spec.isScanForTestClasses(), spec.getTestClassesDirs(), spec.getPath(), spec.getIdentityPath(), spec.getForkEvery(), spec.getJavaForkOptions(), spec.getMaxParallelForks(), spec.getPreviousFailedTestClasses()); this.testTask = testTask; } diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestExtension.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestExtension.java deleted file mode 100644 index 1e7bba14a..000000000 --- a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestExtension.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2015 the original author or authors. - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Donát Csikós (Gradle Inc.) - initial API and implementation and initial documentation - */ - -package eclipsebuild.testing; - -import java.io.File; - -public class EclipseTestExtension { - - private String fragmentHost; - - /** - * Application launched in Eclipse. - * {@code org.eclipse.pde.junit.runtime.coretestapplication} can be used to run non-UI tests. - */ - private String applicationName = "org.eclipse.pde.junit.runtime.uitestapplication"; - - private File optionsFile; - - /** Boolean toggle to control whether to show Eclipse log or not. */ - private boolean consoleLog; - - private long testTimeoutSeconds = 60 * 60L; - - private String testEclipseJavaHome = System.getProperty("java.home"); - - public String getApplicationName() { - return this.applicationName; - } - - public void setApplicationName(String applicationName) { - this.applicationName = applicationName; - } - - public File getOptionsFile() { - return this.optionsFile; - } - - public void setOptionsFile(File optionsFile) { - this.optionsFile = optionsFile; - } - - public boolean isConsoleLog() { - return this.consoleLog; - } - - public void setConsoleLog(boolean consoleLog) { - this.consoleLog = consoleLog; - } - - public long getTestTimeoutSeconds() { - return this.testTimeoutSeconds; - } - - public void setTestTimeoutSeconds(long testTimeoutSeconds) { - this.testTimeoutSeconds = testTimeoutSeconds; - } - - public String getFragmentHost() { - return this.fragmentHost; - } - - public void setFragmentHost(String fragmentHost) { - this.fragmentHost = fragmentHost; - } - - public String getTestEclipseJavaHome() { - return this.testEclipseJavaHome; - } - - public void setTestEclipseJavaHome(String testEclipseJavaHome) { - this.testEclipseJavaHome = testEclipseJavaHome; - } - -} diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestFailure.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestFailure.java index ce6526b99..ec5ac20c3 100644 --- a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestFailure.java +++ b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestFailure.java @@ -11,6 +11,10 @@ import java.io.PrintStream; import java.io.PrintWriter; +/** + * The PDE test runner returns the String representation of the test failures. To forward it to the Gradle test + * framework, we have to convert it back a Throwable. + */ public final class EclipseTestFailure extends Throwable { // TODO (donat) build scans use StacktaceElement to parse a build failed exception diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestFramework.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestFramework.java new file mode 100644 index 000000000..6d047fc9a --- /dev/null +++ b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestFramework.java @@ -0,0 +1,117 @@ +package eclipsebuild.testing; + +import edu.emory.mathcs.backport.java.util.Arrays; +import org.gradle.api.Action; +import org.gradle.api.GradleException; +import org.gradle.api.InvalidUserDataException; +import org.gradle.api.internal.initialization.loadercache.ClassLoaderCache; +import org.gradle.api.internal.plugins.DslObject; +import org.gradle.api.internal.tasks.testing.TestClassLoaderFactory; +import org.gradle.api.internal.tasks.testing.TestClassProcessor; +import org.gradle.api.internal.tasks.testing.TestFramework; +import org.gradle.api.internal.tasks.testing.WorkerTestClassProcessorFactory; +import org.gradle.api.internal.tasks.testing.detection.ClassFileExtractionManager; +import org.gradle.api.internal.tasks.testing.filter.DefaultTestFilter; +import org.gradle.api.reporting.DirectoryReport; +import org.gradle.api.tasks.testing.Test; +import org.gradle.api.tasks.testing.TestFrameworkOptions; +import org.gradle.internal.actor.ActorFactory; +import org.gradle.internal.id.IdGenerator; +import org.gradle.internal.reflect.Instantiator; +import org.gradle.internal.service.ServiceRegistry; +import org.gradle.internal.time.Clock; +import org.gradle.process.internal.worker.DefaultWorkerProcessBuilder; +import org.gradle.process.internal.worker.WorkerProcessBuilder; + +import java.io.File; +import java.io.Serializable; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; + +public class EclipseTestFramework implements TestFramework { + private final EclipseTestOptions options; + private final EclipseTestFrameworkDetector detector; + private final DefaultTestFilter filter; + private final TestClassLoaderFactory classLoaderFactory; + + public EclipseTestFramework(final Test testTask, DefaultTestFilter filter, Instantiator instantiator, ClassLoaderCache classLoaderCache) { + this.filter = filter; + + options = instantiator.newInstance(EclipseTestOptions.class, testTask.getProject().getProjectDir(), new File(testTask.getProject().getBuildDir(), "eclipseTest-build-output"), testTask); + conventionMapOutputDirectory(options, testTask.getReports().getHtml()); + detector = new EclipseTestFrameworkDetector(new ClassFileExtractionManager(testTask.getTemporaryDirFactory())); + classLoaderFactory = new TestClassLoaderFactory(classLoaderCache, testTask); + } + + private static void conventionMapOutputDirectory(EclipseTestOptions options, final DirectoryReport html) { + new DslObject(options).getConventionMapping().map("outputDirectory", new Callable() { + public File call() { + return html.getDestination(); + } + }); + } + + @Override + public TestClassProcessorFactoryImpl getProcessorFactory() { + System.err.println("getProcessorFactory"); + EclipseTestSpec spec = new EclipseTestSpec(options, filter); + return new TestClassProcessorFactoryImpl(this.options.getOutputDirectory(), spec); + } + + private void verifyMethodExists(String methodName, Class parameterType, String failureMessage) { + try { + createTestNg().getMethod(methodName, parameterType); + } catch (NoSuchMethodException e) { + throw new InvalidUserDataException(failureMessage, e); + } + } + + private Class createTestNg() { + try { + return classLoaderFactory.create().loadClass("org.testng.TestNG"); + } catch (ClassNotFoundException e) { + throw new GradleException("Could not load TestNG.", e); + } + } + + @Override + public Action getWorkerConfigurationAction() { + System.err.println("getWorkerConfigurationAction"); + return new Action() { + public void execute(WorkerProcessBuilder workerProcessBuilder) { + workerProcessBuilder.sharedPackages("eclipsebuild.testing"); + List urls = new ArrayList<>(((DefaultWorkerProcessBuilder)workerProcessBuilder).getImplementationClassPath()); + urls.addAll(Arrays.asList(((URLClassLoader)TestClassProcessorFactoryImpl.class.getClassLoader()).getURLs())); + workerProcessBuilder.setImplementationClasspath(urls); + } + }; + } + + @Override + public TestFrameworkOptions getOptions() { + return options; + } + + @Override + public EclipseTestFrameworkDetector getDetector() { + return detector; + } + + public static class TestClassProcessorFactoryImpl implements WorkerTestClassProcessorFactory, Serializable { + private final File testReportDir; + private final EclipseTestSpec options; + + public TestClassProcessorFactoryImpl(File testReportDir, EclipseTestSpec options) { + this.testReportDir = testReportDir; + this.options = options; + } + + @Override + public TestClassProcessor create(ServiceRegistry serviceRegistry) { + return new EclipseTestTestClassProcessor(options, serviceRegistry.get(IdGenerator.class), serviceRegistry.get(Clock.class), serviceRegistry.get(ActorFactory.class)); + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestFrameworkDetector.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestFrameworkDetector.java new file mode 100644 index 000000000..953de8c91 --- /dev/null +++ b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestFrameworkDetector.java @@ -0,0 +1,20 @@ +package eclipsebuild.testing; + +import org.gradle.api.internal.tasks.testing.detection.AbstractTestFrameworkDetector; +import org.gradle.api.internal.tasks.testing.detection.ClassFileExtractionManager; + +class EclipseTestFrameworkDetector extends AbstractTestFrameworkDetector { + EclipseTestFrameworkDetector(ClassFileExtractionManager classFileExtractionManager) { + super(classFileExtractionManager); + } + + @Override + protected EclipseTestClassDetector createClassVisitor() { + return new EclipseTestClassDetector(this); + } + + @Override + protected boolean isKnownTestCaseClassName(String testCaseClassName) { + return "spock/lang/Specification".equals(testCaseClassName); + } +} diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestListener.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestListener.java deleted file mode 100644 index 655dd1a92..000000000 --- a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestListener.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2015 the original author or authors. - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Donát Csikós (Gradle Inc.) - initial API and implementation and initial documentation - */ - -package eclipsebuild.testing; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.gradle.api.internal.tasks.testing.DefaultTestClassDescriptor; -import org.gradle.api.internal.tasks.testing.DefaultTestMethodDescriptor; -import org.gradle.api.internal.tasks.testing.DefaultTestOutputEvent; -import org.gradle.api.internal.tasks.testing.DefaultTestSuiteDescriptor; -import org.gradle.api.internal.tasks.testing.TestCompleteEvent; -import org.gradle.api.internal.tasks.testing.TestDescriptorInternal; -import org.gradle.api.internal.tasks.testing.TestResultProcessor; -import org.gradle.api.internal.tasks.testing.TestStartEvent; -import org.gradle.api.internal.tasks.testing.results.AttachParentTestResultProcessor; -import org.gradle.api.tasks.testing.TestOutputEvent; -import org.gradle.api.tasks.testing.TestResult.ResultType; - -import org.eclipse.jdt.internal.junit.model.ITestRunListener2; - -public final class EclipseTestListener implements ITestRunListener2 { - - private static final Pattern ECLIPSE_TEST_NAME = Pattern.compile("(.*)\\((.*)\\)"); - - private final TestResultProcessor resultProcessor; - private final String suiteName; - private final Object waitMonitor; - private final Object testTaskOperationId; - private final Object rootTestSuiteId; - - private TestDescriptorInternal currentTestSuite; - private TestDescriptorInternal currentTestClass; - private TestDescriptorInternal currentTestMethod; - - public EclipseTestListener(TestResultProcessor testResultProcessor, String suite, Object waitMonitor, Object testTaskOperationId, Object rootTestSuiteId) { - this.resultProcessor = new AttachParentTestResultProcessor(testResultProcessor); - this.waitMonitor = waitMonitor; - this.suiteName = suite; - this.testTaskOperationId = testTaskOperationId; - this.rootTestSuiteId = rootTestSuiteId; - } - - @Override - public synchronized void testRunStarted(int testCount) { - this.currentTestSuite = testSuite(this.rootTestSuiteId, this.suiteName, this.testTaskOperationId); - this.resultProcessor.started(this.currentTestSuite, startEvent()); - } - - @Override - public synchronized void testRunEnded(long elapsedTime) { - if (this.currentTestClass != null) { - this.resultProcessor.completed(this.currentTestClass.getId(), completeEvent(ResultType.SUCCESS)); - } - - this.resultProcessor.completed(this.currentTestSuite.getId(), completeEvent(ResultType.SUCCESS)); - synchronized (this.waitMonitor) { - this.waitMonitor.notifyAll(); - } - } - - @Override - public synchronized void testRunStopped(long elapsedTime) { - // System.out.println("Test Run Stopped"); - // TODO report failure when stopped? - testRunEnded(elapsedTime); - } - - @Override - public synchronized void testRunTerminated() { - // System.out.println("Test Run Terminated"); - // TODO report failure when terminated? - testRunEnded(0); - } - - @Override - public synchronized void testStarted(String testId, String testName) { - // TODO need idGenerator - String testClass = testName; - String testMethod = testName; - Matcher matcher = ECLIPSE_TEST_NAME.matcher(testName); - if (matcher.matches()) { - testClass = matcher.group(2); - testMethod = matcher.group(1); - } - - String classId = testId + " class"; - if (this.currentTestClass == null) { - this.currentTestClass = testClass(classId, testClass, this.currentTestSuite); - this.resultProcessor.started(this.currentTestClass, startEvent(this.currentTestSuite)); - } else if (!this.currentTestClass.getId().equals(classId)) { - this.resultProcessor.completed(this.currentTestClass.getId(), completeEvent(ResultType.SUCCESS)); - this.currentTestClass = testClass(classId, testClass, this.currentTestSuite); - this.resultProcessor.started(this.currentTestClass, startEvent(this.currentTestSuite)); - } - - this.currentTestMethod = testMethod(testId, testClass, testMethod, this.currentTestClass); - this.resultProcessor.started(this.currentTestMethod, startEvent(this.currentTestClass)); - } - - @Override - public synchronized void testEnded(String testId, String testName) { - this.resultProcessor.completed(testId, completeEvent(ResultType.SUCCESS)); - } - - @Override - public synchronized void testFailed(int status, String testId, String testName, String trace, String expected, String actual) { - String message = testName + " failed"; - if (expected != null || actual != null) { - message += " (expected=" + expected + ", actual=" + actual + ")"; - } - - this.resultProcessor.output(this.currentTestMethod.getId(), new DefaultTestOutputEvent(TestOutputEvent.Destination.StdOut, message)); - this.resultProcessor.failure(this.currentTestMethod.getId(), new EclipseTestFailure(message, trace)); - } - - @Override - public synchronized void testReran(String testId, String testClass, String testName, int status, String trace, String expected, String actual) { - throw new UnsupportedOperationException("Unexpected call to testReran when running tests in Eclipse."); - } - - @Override - public synchronized void testTreeEntry(String description) { - } - - private DefaultTestSuiteDescriptor testSuite(Object id, String displayName, final Object testTaskOperationid) { - return new DefaultTestSuiteDescriptor(id, displayName) { - private static final long serialVersionUID = 1L; - - @Override - public Object getOwnerBuildOperationId() { - return testTaskOperationid; - } - }; - } - - private static DefaultTestClassDescriptor testClass(String id, String className, final TestDescriptorInternal parent) { - return new DefaultTestClassDescriptor(id, className){ - private static final long serialVersionUID = 1L; - - @Override - public TestDescriptorInternal getParent() { - return parent; - } - - }; - } - - private static DefaultTestMethodDescriptor testMethod(String id, String className, String methodName, final TestDescriptorInternal parent) { - return new DefaultTestMethodDescriptor(id, className, methodName) { - private static final long serialVersionUID = 1L; - - @Override - public TestDescriptorInternal getParent() { - return parent; - } - }; - } - - private static TestStartEvent startEvent() { - return new TestStartEvent(System.currentTimeMillis()); - } - - private static TestStartEvent startEvent(TestDescriptorInternal parent) { - return new TestStartEvent(System.currentTimeMillis(), parent.getId()); - } - - private static TestCompleteEvent completeEvent(ResultType resultType) { - return new TestCompleteEvent(System.currentTimeMillis(), resultType); - } - - public static void main(String[] args) { - System.out.println(new RuntimeException("asdfasdf").toString()); - } - -} diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestOptions.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestOptions.java new file mode 100644 index 000000000..812261d8b --- /dev/null +++ b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestOptions.java @@ -0,0 +1,101 @@ +package eclipsebuild.testing; + +import org.gradle.api.tasks.testing.Test; +import org.gradle.api.tasks.testing.TestFrameworkOptions; + +import javax.annotation.Nullable; +import java.io.File; + +/** + * Configuration entry for the {@code test.options} block. + */ +public class EclipseTestOptions extends TestFrameworkOptions { + + private final File projectDir; + private final Test test; + + private File outputDirectory; + private String fragmentHost = null; + private String applicationName = "org.eclipse.pde.junit.runtime.uitestapplication"; + private File optionsFile = null; + private boolean consoleLog = false; + + public EclipseTestOptions(File projectDir, File outputDirectory, Test test) { + this.projectDir = projectDir; + this.outputDirectory = outputDirectory; + this.test = test; + } + + File getProjectDir() { + return projectDir; + } + + String getTaskPath() { + return test.getPath(); + } + + public File getOutputDirectory() { + return outputDirectory; + } + + public void outputDirectory(@Nullable File outputDirectory) { + this.outputDirectory = outputDirectory; + } + + String getFragmentHost() { + return fragmentHost; + } + + public void fragmentHost(String fragmentHost) { + this.fragmentHost = fragmentHost; + } + + String getApplicationName() { + return applicationName; + } + + public void applicationName(String applicationName) { + this.applicationName = applicationName; + } + + File getOptionsFile() { + return optionsFile; + } + + public void optionsFile(@Nullable File optionsFile) { + this.optionsFile = optionsFile; + } + + boolean isConsoleLog() { + return consoleLog; + } + + public void consoleLog(boolean consoleLog) { + this.consoleLog = consoleLog; + } + + boolean isDebug() { + return test.getDebug(); + } + + @Nullable String getMirrors() { + return (String) test.getProject().findProperty("mirrors"); + } + + String getProjectName() { + return test.getProject().getName(); + } + + String getTestTaskName() { + return test.getName(); + } + + public File getWorkspace() { + return new File(test.getProject().getBuildDir().getAbsolutePath(), test.getName() + File.separator + "workspace"); + } + + public File getEclipseRuntime() { + return new File(test.getProject().getBuildDir(), test.getName() + File.separator + "eclipse"); + } +} + diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestSpec.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestSpec.java new file mode 100644 index 000000000..f42277e36 --- /dev/null +++ b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestSpec.java @@ -0,0 +1,88 @@ +package eclipsebuild.testing; + +import org.gradle.api.internal.tasks.testing.filter.DefaultTestFilter; + +import javax.annotation.Nullable; +import java.io.File; +import java.io.Serializable; + +public class EclipseTestSpec implements Serializable { + private static final long serialVersionUID = 1; + private final File projectDir; + private final String taskPath; + private final File outputDirectory; + private final String mirrors; + private final String fragmentHost; + private final String applicationName; + private final File optionsFile; + private final boolean consoleLog; + private final String projectName; + private final File workspace; + private final File eclipseRuntime; + private final boolean debug; + + public EclipseTestSpec(EclipseTestOptions options, DefaultTestFilter filter) { + // TODO make use of the test filtering + this.projectDir = options.getProjectDir(); + this.outputDirectory = options.getOutputDirectory(); + this.taskPath = options.getTaskPath(); + this.fragmentHost = options.getFragmentHost(); + this.applicationName = options.getApplicationName(); + this.optionsFile = options.getOptionsFile(); + this.consoleLog = options.isConsoleLog(); + this.mirrors = options.getMirrors(); + this.projectName = options.getProjectName(); + this.workspace = options.getWorkspace(); + this.eclipseRuntime = options.getEclipseRuntime(); + this.debug = options.isDebug(); + } + + public File getProjectDir() { + return projectDir; + } + + public String getTaskPath() { + return taskPath; + } + + public @Nullable File getOutputDirectory() { + return outputDirectory; + } + + public String getMirrors() { + return mirrors; + } + + public String getFragmentHost() { + return fragmentHost; + } + + public String getApplicationName() { + return applicationName; + } + + public @Nullable File getOptionsFile() { + return optionsFile; + } + + public boolean isConsoleLog() { + return consoleLog; + } + + public String getProjectName() { + return projectName; + } + + public File getWorkspace() { + return workspace; + } + + public File getEclipseRuntime() { + return eclipseRuntime; + } + + public boolean isDebug() { + return debug; + } +} + diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestTask.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestTask.java index 7b37de094..c70449dde 100644 --- a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestTask.java +++ b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestTask.java @@ -1,12 +1,39 @@ package eclipsebuild.testing; +import groovy.lang.Closure; import org.gradle.api.internal.tasks.testing.JvmTestExecutionSpec; +import org.gradle.api.internal.tasks.testing.TestFramework; +import org.gradle.api.internal.tasks.testing.filter.DefaultTestFilter; import org.gradle.api.tasks.testing.Test; public class EclipseTestTask extends Test { + TestFramework framework = new EclipseTestFramework(this, (DefaultTestFilter) getFilter(), getInstantiator(), getClassLoaderCache()); + private boolean debug; + @Override protected JvmTestExecutionSpec createTestExecutionSpec() { - return new EclipseTestExecutionSpec(super.createTestExecutionSpec(), this); + JvmTestExecutionSpec execSpec = super.createTestExecutionSpec(); + return new EclipseTestExecutionSpec(execSpec, framework, this); + } + + @Override + public TestFramework getTestFramework() { + return framework; + } + + @Override + public TestFramework testFramework(Closure testFrameworkConfigure) { + return framework; + } + + @Override + public void setDebug(boolean debug) { + this.debug = debug; + } + + @Override + public boolean getDebug() { + return debug; } } diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestTestClassProcessor.java b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestTestClassProcessor.java new file mode 100644 index 000000000..015b14064 --- /dev/null +++ b/buildSrc/src/main/groovy/eclipsebuild/testing/EclipseTestTestClassProcessor.java @@ -0,0 +1,242 @@ +package eclipsebuild.testing; + +import org.eclipse.jdt.internal.junit.model.ITestRunListener2; +import org.eclipse.jdt.internal.junit.model.RemoteTestRunnerClient; +import org.gradle.api.GradleException; +import org.gradle.api.JavaVersion; +import org.gradle.api.internal.tasks.testing.TestClassProcessor; +import org.gradle.api.internal.tasks.testing.TestClassRunInfo; +import org.gradle.api.internal.tasks.testing.TestResultProcessor; +import org.gradle.internal.actor.Actor; +import org.gradle.internal.actor.ActorFactory; +import org.gradle.internal.id.IdGenerator; +import org.gradle.internal.os.OperatingSystem; +import org.gradle.internal.time.Clock; + +import java.io.File; +import java.io.IOException; +import java.net.ServerSocket; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EclipseTestTestClassProcessor implements TestClassProcessor { + private final List testClassNames = new ArrayList(); + private final EclipseTestSpec options; + private final IdGenerator idGenerator; + private final Clock clock; + private final ActorFactory actorFactory; + private Actor resultProcessorActor; + private TestResultProcessor resultProcessor; + + private Process eclipseUnderTestProcess; + private RemoteTestRunnerClient testRunner; + + public EclipseTestTestClassProcessor(EclipseTestSpec options, IdGenerator idGenerator, Clock clock, ActorFactory actorFactory) { + this.options = options; + this.idGenerator = idGenerator; + this.clock = clock; + this.actorFactory = actorFactory; + } + + @Override + public void startProcessing(TestResultProcessor resultProcessor) { + // Wrap the processor in an actor, to make it thread-safe + resultProcessorActor = actorFactory.createBlockingActor(resultProcessor); + this.resultProcessor = resultProcessorActor.getProxy(TestResultProcessor.class); + } + + @Override + public void processTestClass(TestClassRunInfo testClass) { + testClassNames.add(testClass.getTestClassName()); + } + + @Override + public void stop() { + try { + runTests(); + } finally { + resultProcessorActor.stop(); + } + } + + @Override + public void stopNow() { + try { + testRunner.stopWaiting(); + testRunner.stopTest(); + eclipseUnderTestProcess.destroyForcibly(); + } finally { + resultProcessorActor.stop(); + } + } + + private void runTests() { + final int pdeTestPort = locatePDETestPortNumber(); + if (pdeTestPort == -1) { + throw new GradleException("Cannot allocate port for PDE test run"); + } + + File eclipseRuntime = options.getEclipseRuntime(); + + List command = new ArrayList<>(); + command.add(System.getProperty("java.home") + "/bin/java"); + command.add("-cp"); + command.add(getEquinoxLauncherFile(eclipseRuntime).getAbsolutePath()); + + command.add("-XX:MaxPermSize=256m"); + command.add("-Xms40m"); + command.add("-Xmx1024m"); + + // Java 9 workaround from https://bugs.eclipse.org/bugs/show_bug.cgi?id=493761 + // TODO we should remove this option when it is not required by Eclipse + if (JavaVersion.current().isJava9Compatible()) { + command.add("--add-modules=ALL-SYSTEM"); + } + + // run the eclipseTest task with `--debug-jvm` parameter to enable debugging + if (options.isDebug()) { + command.add("-Xdebug"); + command.add("-Xrunjdwp:transport=dt_socket,address=5005,server=y"); + } + + if (getOs().equals("macosx")) { + command.add("-XstartOnFirstThread"); + } + + // declare mirror urls if exists + Map mirrorUrls = new HashMap<>(); + if (options.getMirrors() != null) { + String mirrorsString = options.getMirrors(); + String[] mirrors = mirrorsString.split(","); + for (String mirror : mirrors) { + if (!"".equals(mirror)) { + String[] nameAndUrl = mirror.split(":", 2); + mirrorUrls.put(nameAndUrl[0], nameAndUrl[1]); + } + } + } + + for (Map.Entry mirrorUrl : mirrorUrls.entrySet()) { + command.add("-Dorg.eclipse.buildship.eclipsetest.mirrors." + mirrorUrl.getKey() + "=" + mirrorUrl.getValue()); + } + + // Java 9 workaround from https://bugs.eclipse.org/bugs/show_bug.cgi?id=493761 + // TODO we should remove this option when it is not required by Eclipse + if (JavaVersion.current().isJava9Compatible()) { + command.add("--add-modules=ALL-SYSTEM"); + } + + if (getOs().equals("macosx")) { + command.add("-XstartOnFirstThread"); + } + + command.add("org.eclipse.equinox.launcher.Main"); + + command.add("-os"); + command.add(getOs()); + command.add("-ws"); + command.add(getWs()); + command.add("-arch"); + command.add(getArch()); + + if (options.isConsoleLog()) { + command.add("-consoleLog"); + } + File optionsFile = options.getOptionsFile(); + if (optionsFile != null) { + command.add("-debug"); + command.add(optionsFile.getAbsolutePath()); + } + + command.add("-version"); + command.add("4"); + command.add("-port"); + command.add(Integer.toString(pdeTestPort)); + command.add("-testLoaderClass"); + command.add("org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader"); + command.add("-loaderpluginname"); + command.add("org.eclipse.jdt.junit4.runtime"); + + command.add("-classNames"); + command.addAll(testClassNames); + + command.add("-application"); + command.add(options.getApplicationName()); + + command.add("-product org.eclipse.platform.ide"); + // alternatively can use URI for -data and -configuration (file:///path/to/dir/) + command.add("-data"); + command.add(options.getWorkspace().getAbsolutePath()); + command.add("-configuration"); + command.add(new File(eclipseRuntime, "configuration").getAbsolutePath()); + + command.add("-testpluginname"); + String fragmentHost = options.getFragmentHost(); + if (fragmentHost != null) { + command.add(fragmentHost); + } else { + command.add(options.getProjectName()); + } + + ProcessBuilder pb = new ProcessBuilder(command); + pb.directory(options.getProjectDir()); + pb.inheritIO(); + try { + eclipseUnderTestProcess = pb.start(); + testRunner = new RemoteTestRunnerClient(); + testRunner.startListening(new ITestRunListener2[] { new EclipseTestAdapter(resultProcessor, clock, idGenerator) }, pdeTestPort); + eclipseUnderTestProcess.waitFor(); + testRunner.stopWaiting(); + } catch (IOException e) { + throw new RuntimeException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + private static int locatePDETestPortNumber() { + ServerSocket socket = null; + try { + socket = new ServerSocket(0); + return socket.getLocalPort(); + } catch (IOException e) { + // ignore + } finally { + if (socket != null) { + try { + socket.close(); + } catch (IOException e) { + // ignore + } + } + } + return -1; + } + + private File getEquinoxLauncherFile(File testEclipseDir) { + File[] plugins = new File(testEclipseDir, "plugins").listFiles(); + for (File plugin : plugins) { + if (plugin.getName().startsWith("org.eclipse.equinox.launcher_")) { + return plugin; + } + } + return null; + } + + static String getOs() { + OperatingSystem os = OperatingSystem.current(); + return os.isLinux() ? "linux" : os.isWindows() ? "win32" : os.isMacOsX() ? "macosx": null; + } + + static String getWs() { + OperatingSystem os = OperatingSystem.current(); + return os.isLinux() ? "gtk" : os.isWindows() ? "win32" : os.isMacOsX() ? "cocoa" : null; + } + + static String getArch() { + return System.getProperty("os.arch").contains("64") ? "x86_64" : "x86"; + } +} + diff --git a/buildSrc/src/main/groovy/eclipsebuild/testing/PDETestPortLocator.java b/buildSrc/src/main/groovy/eclipsebuild/testing/PDETestPortLocator.java deleted file mode 100644 index da72fa54a..000000000 --- a/buildSrc/src/main/groovy/eclipsebuild/testing/PDETestPortLocator.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2015 the original author or authors. - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Donát Csikós (Gradle Inc.) - initial API and implementation and initial documentation - */ - -package eclipsebuild.testing; - -import java.io.IOException; -import java.net.ServerSocket; - -public final class PDETestPortLocator { - - public int locatePDETestPortNumber() { - ServerSocket socket = null; - try { - socket = new ServerSocket(0); - return socket.getLocalPort(); - } catch (IOException e) { - // ignore - } finally { - if (socket != null) { - try { - socket.close(); - } catch (IOException e) { - // ignore - } - } - } - return -1; - } - -} diff --git a/gradle/config/checkstyle/checkstyle.xml b/gradle/config/checkstyle/checkstyle.xml index 6d17c3c8d..584be1e64 100644 --- a/gradle/config/checkstyle/checkstyle.xml +++ b/gradle/config/checkstyle/checkstyle.xml @@ -11,9 +11,6 @@ - - - @@ -35,8 +32,8 @@ - - + + diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 717f03890..b41dbe8a6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip diff --git a/org.eclipse.buildship.core.test/build.gradle b/org.eclipse.buildship.core.test/build.gradle index 35aa2172b..cb8886fc3 100644 --- a/org.eclipse.buildship.core.test/build.gradle +++ b/org.eclipse.buildship.core.test/build.gradle @@ -8,11 +8,8 @@ dependencies { def javaHome = hasProperty('eclipse.test.java.home') ? getProperty('eclipse.test.java.home') : System.getProperty('java.home') javaHome = javaHome.replace('\"', '').replace('\'', '') -eclipseTest { +tasks['eclipseTest'].options { fragmentHost 'org.eclipse.buildship.core' applicationName 'org.eclipse.pde.junit.runtime.coretestapplication' optionsFile rootProject.project(':org.eclipse.buildship.core').file('.options') - // TODO (donat) re-enable custom java home when we change the execution environment to Java 7 for the entire project and adjust CI builds - // testEclipseJavaHome = javaHome } - diff --git a/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/SynchronizationInvalidLocationTest.groovy b/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/SynchronizationInvalidLocationTest.groovy deleted file mode 100644 index acfb9bc3c..000000000 --- a/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/SynchronizationInvalidLocationTest.groovy +++ /dev/null @@ -1,32 +0,0 @@ -package org.eclipse.buildship.core - -import org.eclipse.core.runtime.IStatus - -import org.eclipse.buildship.core.internal.operation.ToolingApiStatus.ToolingApiStatusType -import org.eclipse.buildship.core.internal.test.fixtures.ProjectSynchronizationSpecification - -class SynchronizationInvalidLocationTest extends ProjectSynchronizationSpecification { - - def "Can import a nonexistent location"() { - setup: - File location = new File('nonexistent') - - when: - SynchronizationResult result = tryImportAndWait(location) - - then: - result.status.isOK() - } - - def "Cannot import a plain file"() { - setup: - File location = file('nonexistent.file') - - when: - SynchronizationResult result = tryImportAndWait(location) - - then: - result.status.severity == IStatus.WARNING - ToolingApiStatusType.IMPORT_ROOT_DIR_FAILED.matches(result.status) - } -} diff --git a/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/internal/configuration/RunConfigurationTest.groovy b/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/internal/configuration/RunConfigurationTest.groovy deleted file mode 100644 index bc101cdd1..000000000 --- a/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/internal/configuration/RunConfigurationTest.groovy +++ /dev/null @@ -1,199 +0,0 @@ -package org.eclipse.buildship.core.internal.configuration - -import spock.lang.Issue - -import org.eclipse.core.runtime.Platform -import org.eclipse.core.variables.IStringVariableManager -import org.eclipse.core.variables.IValueVariable -import org.eclipse.core.variables.VariablesPlugin -import org.eclipse.debug.core.DebugPlugin -import org.eclipse.debug.core.ILaunchConfiguration -import org.eclipse.debug.core.ILaunchConfigurationType -import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy -import org.eclipse.debug.core.ILaunchManager - -import org.eclipse.buildship.core.GradleDistribution -import org.eclipse.buildship.core.internal.GradlePluginsRuntimeException -import org.eclipse.buildship.core.internal.launch.GradleRunConfigurationAttributes -import org.eclipse.buildship.core.internal.launch.GradleRunConfigurationDelegate -import org.eclipse.buildship.core.internal.test.fixtures.ProjectSynchronizationSpecification - -class RunConfigurationTest extends ProjectSynchronizationSpecification { - - def "load default settings"() { - given: - ILaunchConfigurationWorkingCopy launchConfig = createGradleLaunchConfig() - // when executed from the IDE, the working directory is set to the core.test plugin folder - // which makes this test read the run configuration from the `.settings` folder - boolean isDev = Platform.inDevelopmentMode() - File tmpDir - if (isDev) { - tmpDir = dir("tmpDir") - launchConfig.setAttribute(GradleRunConfigurationAttributes.WORKING_DIR, tmpDir.absolutePath) - launchConfig.doSave() - } - - RunConfiguration runConfig = configurationManager.loadRunConfiguration(launchConfig) - - expect: - runConfig.tasks == [] - runConfig.javaHome == null - runConfig.arguments == [] - runConfig.jvmArguments == [] - runConfig.showExecutionView == true - runConfig.showConsoleView == true - runConfig.projectConfiguration.projectDir.path == (isDev ? tmpDir.canonicalPath : new File('').canonicalPath) - runConfig.projectConfiguration.buildConfiguration.rootProjectDirectory.path == (isDev ? tmpDir.canonicalPath : new File('').canonicalPath) - runConfig.projectConfiguration.buildConfiguration.gradleDistribution == GradleDistribution.fromBuild() - runConfig.projectConfiguration.buildConfiguration.overrideWorkspaceSettings == false - runConfig.projectConfiguration.buildConfiguration.buildScansEnabled == false - runConfig.projectConfiguration.buildConfiguration.offlineMode == false - runConfig.projectConfiguration.buildConfiguration.workspaceConfiguration.gradleUserHome == null - runConfig.projectConfiguration.buildConfiguration.workspaceConfiguration.gradleIsOffline == false - runConfig.projectConfiguration.buildConfiguration.workspaceConfiguration.buildScansEnabled == false - } - - def "load custom settings"() { - setup: - List tasks = ['clean', 'build'] - File javaHome = dir('custom-java-home') - List arguments = ['-q', '-Pkey=value'] - List jvmArguments = ['-ea', '-Dkey=value'] - boolean showConsoleView = false - boolean showExecutionView = false - File rootDir = dir('projectDir').canonicalFile - GradleDistribution distribution = GradleDistribution.forVersion("3.3") - boolean overrideBuildSettings = true - boolean buildScansEnabled = true - boolean offlineMode = true - - ILaunchConfiguration launchConfig = createGradleLaunchConfig() - GradleRunConfigurationAttributes.applyTasks(tasks, launchConfig) - GradleRunConfigurationAttributes.applyJavaHomeExpression(javaHome.absolutePath, launchConfig) - GradleRunConfigurationAttributes.applyArgumentExpressions(arguments, launchConfig) - GradleRunConfigurationAttributes.applyJvmArgumentExpressions(jvmArguments, launchConfig) - GradleRunConfigurationAttributes.applyShowConsoleView(showConsoleView, launchConfig) - GradleRunConfigurationAttributes.applyShowExecutionView(showExecutionView, launchConfig) - GradleRunConfigurationAttributes.applyWorkingDirExpression(rootDir.absolutePath, launchConfig) - GradleRunConfigurationAttributes.applyGradleDistribution(distribution, launchConfig) - GradleRunConfigurationAttributes.applyOverrideBuildSettings(overrideBuildSettings, launchConfig) - GradleRunConfigurationAttributes.applyBuildScansEnabled(buildScansEnabled, launchConfig) - GradleRunConfigurationAttributes.applyOfflineMode(offlineMode, launchConfig) - - when: - RunConfiguration runConfig = configurationManager.loadRunConfiguration(launchConfig) - - then: - runConfig.tasks == tasks - runConfig.javaHome == javaHome - runConfig.arguments == arguments - runConfig.jvmArguments == jvmArguments - runConfig.showConsoleView == showConsoleView - runConfig.showExecutionView == showExecutionView - runConfig.projectConfiguration.projectDir == rootDir - runConfig.projectConfiguration.buildConfiguration.rootProjectDirectory == rootDir - runConfig.projectConfiguration.buildConfiguration.gradleDistribution == distribution - runConfig.projectConfiguration.buildConfiguration.overrideWorkspaceSettings == overrideBuildSettings - runConfig.projectConfiguration.buildConfiguration.buildScansEnabled == buildScansEnabled - runConfig.projectConfiguration.buildConfiguration.offlineMode == offlineMode - runConfig.projectConfiguration.buildConfiguration.workspaceConfiguration.gradleUserHome == null - runConfig.projectConfiguration.buildConfiguration.workspaceConfiguration.gradleIsOffline == false - runConfig.projectConfiguration.buildConfiguration.workspaceConfiguration.buildScansEnabled == false - } - - @Issue('https://github.com/eclipse/buildship/issues/572') - def "load attributes from valid expressions"() { - setup: - IStringVariableManager variableManager = VariablesPlugin.default.stringVariableManager - IValueVariable[] variables = [ - variableManager.newValueVariable('buildship_test_var1', 'Variable to test run config substitution', true, 'test_value1'), - variableManager.newValueVariable('buildship_test_var2', 'Variable to test run config substitution', true, 'test_value2'), - variableManager.newValueVariable('buildship_test_var3', 'Variable to test run config substitution', true, 'test_value3'), - variableManager.newValueVariable('buildship_test_var4', 'Variable to test run config substitution', true, 'test_value4') - ] - variableManager.addVariables(variables) - - File projectDir = dir('sample-project').canonicalFile - importAndWait(projectDir) - - ILaunchConfiguration launchConfig = emptyLaunchConfig() - GradleRunConfigurationAttributes.applyOverrideBuildSettings(true, launchConfig) - GradleRunConfigurationAttributes.applyWorkingDirExpression('${workspace_loc:/sample-project}', launchConfig) - GradleRunConfigurationAttributes.applyGradleUserHomeExpression('/gradleUserHome/${buildship_test_var1}', launchConfig) - GradleRunConfigurationAttributes.applyJavaHomeExpression('/javaHome/${buildship_test_var2}', launchConfig) - GradleRunConfigurationAttributes.applyArgumentExpressions(['-PsampleProjectProperty=${buildship_test_var3}'], launchConfig) - GradleRunConfigurationAttributes.applyJvmArgumentExpressions(['-DsampleJvmProperty=${buildship_test_var4}'], launchConfig) - - when: - RunConfiguration runConfig = configurationManager.loadRunConfiguration(launchConfig) - - then: - runConfig.projectConfiguration.projectDir == projectDir - runConfig.gradleUserHome.path.contains 'test_value1' - runConfig.javaHome.path.contains 'test_value2' - runConfig.arguments == ['-PsampleProjectProperty=test_value3'] - runConfig.jvmArguments == ['-DsampleJvmProperty=test_value4'] - - cleanup: - variableManager.removeVariables(variables) - } - - @Issue('https://github.com/eclipse/buildship/issues/572') - def "load attributes from invaild expressions"() { - setup: - File projectDir = dir('sample-project').canonicalFile - importAndWait(projectDir) - - ILaunchConfiguration launchConfig = emptyLaunchConfig() - GradleRunConfigurationAttributes.applyOverrideBuildSettings(true, launchConfig) - GradleRunConfigurationAttributes.applyWorkingDirExpression('${nonexisting}', launchConfig) - - when: - configurationManager.loadRunConfiguration(launchConfig) - - then: - thrown GradlePluginsRuntimeException - - when: - launchConfig = emptyLaunchConfig() - GradleRunConfigurationAttributes.applyWorkingDirExpression('${workspace_loc:/sample-project}', launchConfig) - GradleRunConfigurationAttributes.applyGradleUserHomeExpression('${nonexisting}', launchConfig) - configurationManager.loadRunConfiguration(launchConfig) - - then: - thrown GradlePluginsRuntimeException - - when: - launchConfig = emptyLaunchConfig() - GradleRunConfigurationAttributes.applyWorkingDirExpression('${workspace_loc:/sample-project}', launchConfig) - GradleRunConfigurationAttributes.applyJavaHomeExpression('${nonexisting}', launchConfig) - configurationManager.loadRunConfiguration(launchConfig) - - then: - thrown GradlePluginsRuntimeException - - when: - launchConfig = emptyLaunchConfig() - GradleRunConfigurationAttributes.applyWorkingDirExpression('${workspace_loc:/sample-project}', launchConfig) - GradleRunConfigurationAttributes.applyArgumentExpressions(['${nonexisting}'], launchConfig) - configurationManager.loadRunConfiguration(launchConfig) - - then: - thrown GradlePluginsRuntimeException - - when: - launchConfig = emptyLaunchConfig() - GradleRunConfigurationAttributes.applyWorkingDirExpression('${workspace_loc:/sample-project}', launchConfig) - GradleRunConfigurationAttributes.applyJvmArgumentExpressions(['${nonexisting}'], launchConfig) - configurationManager.loadRunConfiguration(launchConfig) - - then: - thrown GradlePluginsRuntimeException - } - - private ILaunchConfiguration emptyLaunchConfig() { - ILaunchManager launchManager = DebugPlugin.default.launchManager - ILaunchConfigurationType type = launchManager.getLaunchConfigurationType(GradleRunConfigurationDelegate.ID) - type.newInstance(null, launchManager.generateLaunchConfigurationName('launch-config-name')) - } -} diff --git a/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/internal/workspace/GradleClasspathContainerUpdaterTest.groovy b/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/internal/workspace/GradleClasspathContainerUpdaterTest.groovy index 84cad2497..a72b790ac 100644 --- a/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/internal/workspace/GradleClasspathContainerUpdaterTest.groovy +++ b/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/internal/workspace/GradleClasspathContainerUpdaterTest.groovy @@ -62,7 +62,7 @@ class GradleClasspathContainerUpdaterTest extends WorkspaceSpecification { then: resolvedClasspath[0].entryKind == IClasspathEntry.CPE_LIBRARY - resolvedClasspath[0].path.toFile() == dir("foo") + resolvedClasspath[0].path.toFile().canonicalPath.equals(dir("foo").canonicalPath) } def "Linked files can be added to the classpath"(String path) { diff --git a/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/internal/workspace/LinkedResourcesUpdaterTest.groovy b/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/internal/workspace/LinkedResourcesUpdaterTest.groovy index 36356a591..37a7ff286 100644 --- a/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/internal/workspace/LinkedResourcesUpdaterTest.groovy +++ b/org.eclipse.buildship.core.test/src/main/groovy/org/eclipse/buildship/core/internal/workspace/LinkedResourcesUpdaterTest.groovy @@ -30,7 +30,7 @@ class LinkedResourcesUpdaterTest extends WorkspaceSpecification { linkedresources.size() == 1 linkedresources[0].name == 'another' linkedresources[0].exists() - linkedresources[0].location.toFile().equals(externalDir) + linkedresources[0].location.toFile().canonicalPath.equals(externalDir.canonicalPath) } def "Can define a linked resource even if the resource does not exist"() { @@ -48,7 +48,7 @@ class LinkedResourcesUpdaterTest extends WorkspaceSpecification { linkedResources.size() == 1 linkedResources[0].name == 'another' linkedResources[0].exists() - linkedResources[0].location.toFile().equals(externalDir) + linkedResources[0].location.toFile().canonicalPath.equals(externalDir.canonicalPath) } def "Defining a linked resource is idempotent"() { @@ -137,7 +137,7 @@ class LinkedResourcesUpdaterTest extends WorkspaceSpecification { linkedResources.size() == 1 linkedResources[0].name == 'another2' linkedResources[0].exists() - linkedResources[0].location.toFile().equals(externalDirB) + linkedResources[0].location.toFile().canonicalPath.equals(externalDirB.canonicalPath) where: linkName << ['another', 'a/b/c'] diff --git a/org.eclipse.buildship.oomph.test/build.gradle b/org.eclipse.buildship.oomph.test/build.gradle index c13051d1c..a2c784a72 100644 --- a/org.eclipse.buildship.oomph.test/build.gradle +++ b/org.eclipse.buildship.oomph.test/build.gradle @@ -9,12 +9,11 @@ dependencies { def javaHome = hasProperty('eclipse.test.java.home') ? getProperty('eclipse.test.java.home') : System.getProperty('java.home') javaHome = javaHome.replace('\"', '').replace('\'', '') -eclipseTest { +tasks['eclipseTest'].options { fragmentHost 'org.eclipse.buildship.core' applicationName 'org.eclipse.swtbot.eclipse.core.swtbottestapplication' optionsFile rootProject.project(':org.eclipse.buildship.core').file('.options') - consoleLog = true - // TODO (donat) re-enable custom java home when we change the execution environment to Java 7 for the entire project and adjust CI builds - // testEclipseJavaHome = javaHome + consoleLog true } + diff --git a/org.eclipse.buildship.stsmigration.test/build.gradle b/org.eclipse.buildship.stsmigration.test/build.gradle index c2d8c28e3..dbd1dea5a 100644 --- a/org.eclipse.buildship.stsmigration.test/build.gradle +++ b/org.eclipse.buildship.stsmigration.test/build.gradle @@ -5,10 +5,9 @@ dependencies { compile project(':org.eclipse.buildship.stsmigration') } -eclipseTest { +tasks['eclipseTest'].options { fragmentHost 'org.eclipse.buildship.stsmigration' applicationName 'org.eclipse.swtbot.eclipse.core.swtbottestapplication' optionsFile rootProject.project(':org.eclipse.buildship.core').file('.options') - consoleLog = true -} - + consoleLog true +} \ No newline at end of file diff --git a/org.eclipse.buildship.ui.test/build.gradle b/org.eclipse.buildship.ui.test/build.gradle index e2fd4c9a0..50be090da 100644 --- a/org.eclipse.buildship.ui.test/build.gradle +++ b/org.eclipse.buildship.ui.test/build.gradle @@ -9,12 +9,10 @@ dependencies { def javaHome = hasProperty('eclipse.test.java.home') ? getProperty('eclipse.test.java.home') : System.getProperty('java.home') javaHome = javaHome.replace('\"', '').replace('\'', '') -eclipseTest { +tasks['eclipseTest'].options { fragmentHost 'org.eclipse.buildship.ui' applicationName 'org.eclipse.swtbot.eclipse.core.swtbottestapplication' optionsFile rootProject.project(':org.eclipse.buildship.core').file('.options') - consoleLog = true - // TODO (donat) re-enable custom java home when we change the execution environment to Java 7 for the entire project and adjust CI builds - // testEclipseJavaHome = javaHome + consoleLog true }